Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

romannumdemo.gno

3.67 Kb · 110 lines
  1// Package romannumdemo is a small gnoweb demo of the Roman-numeral converter
  2// provided by the [p/moul/x/daily/romannum](/p/nym-moultest123/x/daily/romannum/v0)
  3// library: it renders a table of worked examples and interactive
  4// integer→Roman and Roman→integer conversions.
  5//
  6// It contains no conversion logic of its own — everything comes from
  7// romannum.ToRoman and romannum.FromRoman.
  8package romannumdemo
  9
 10import (
 11	"strconv"
 12	"strings"
 13
 14	"gno.land/p/nym-moultest123/x/daily/romannum/v0"
 15)
 16
 17// examples are the classic milestones shown by the root Render.
 18var examples = []int{1, 4, 9, 14, 40, 49, 90, 400, 900, 1994, 2024, 3888, 3999}
 19
 20// Render drives gnoweb:
 21//   - ""        or "/"          → a table of example conversions
 22//   - "/<n>"                    → integer → Roman
 23//   - "/r/<roman>"              → Roman → integer
 24func Render(path string) string {
 25	arg := strings.Trim(strings.TrimSpace(path), "/")
 26
 27	switch {
 28	case arg == "":
 29		return renderTable()
 30	case strings.HasPrefix(strings.ToLower(arg), "r/"):
 31		return renderFromRoman(arg[2:])
 32	default:
 33		return renderToRoman(arg)
 34	}
 35}
 36
 37func renderToRoman(arg string) string {
 38	n, err := strconv.Atoi(strings.TrimSpace(arg))
 39	if err != nil {
 40		return "# Roman numeral converter\n\nCould not parse `" + arg +
 41			"` as an integer.\n\n" + usage()
 42	}
 43	if n < 1 || n > 3999 {
 44		return "# Roman numeral converter\n\n`" + strconv.Itoa(n) +
 45			"` is out of range — Roman numerals here cover **1..3999**.\n\n" + usage()
 46	}
 47	var b strings.Builder
 48	b.WriteString("# " + strconv.Itoa(n) + " → " + romannum.ToRoman(n) + "\n\n")
 49	b.WriteString("| decimal | roman |\n|---:|:---|\n")
 50	b.WriteString("| " + strconv.Itoa(n) + " | **" + romannum.ToRoman(n) + "** |\n\n")
 51	if n > 1 {
 52		b.WriteString("[« " + strconv.Itoa(n-1) + "](/r/nym-moultest123/x/daily/romannumdemo/v0:" +
 53			strconv.Itoa(n-1) + ") · ")
 54	}
 55	if n < 3999 {
 56		b.WriteString("[" + strconv.Itoa(n+1) + " »](/r/nym-moultest123/x/daily/romannumdemo/v0:" +
 57			strconv.Itoa(n+1) + ")")
 58	}
 59	b.WriteString("\n\n" + usage())
 60	return b.String()
 61}
 62
 63func renderFromRoman(arg string) string {
 64	arg = strings.TrimSpace(arg)
 65	n, ok := tryFromRoman(arg)
 66	if !ok {
 67		return "# Roman numeral converter\n\n`" + arg +
 68			"` is not a valid Roman numeral (1..3999).\n\n" + usage()
 69	}
 70	up := strings.ToUpper(arg)
 71	var b strings.Builder
 72	b.WriteString("# " + up + " → " + strconv.Itoa(n) + "\n\n")
 73	b.WriteString("| roman | decimal |\n|:---|---:|\n")
 74	b.WriteString("| **" + up + "** | " + strconv.Itoa(n) + " |\n\n")
 75	b.WriteString(usage())
 76	return b.String()
 77}
 78
 79// tryFromRoman wraps the panic-on-invalid romannum.FromRoman in a panic-free
 80// (value, ok) shape, so the demo can report a friendly error for bad input.
 81func tryFromRoman(s string) (n int, ok bool) {
 82	defer func() {
 83		if recover() != nil {
 84			n, ok = 0, false
 85		}
 86	}()
 87	return romannum.FromRoman(s), true
 88}
 89
 90func renderTable() string {
 91	var b strings.Builder
 92	b.WriteString("# Roman numeral converter\n\n")
 93	b.WriteString("A tiny demo of the [`p/moul/x/daily/romannum`](/p/nym-moultest123/x/daily/romannum/v0) ")
 94	b.WriteString("library — the classic `ToRoman` / `FromRoman` kata. ")
 95	b.WriteString("Pure and deterministic.\n\n")
 96	b.WriteString("## Examples\n\n")
 97	b.WriteString("| decimal | roman |\n|---:|:---|\n")
 98	for _, n := range examples {
 99		b.WriteString("| [" + strconv.Itoa(n) + "](/r/nym-moultest123/x/daily/romannumdemo/v0:" +
100			strconv.Itoa(n) + ") | " + romannum.ToRoman(n) + " |\n")
101	}
102	b.WriteString("\n" + usage())
103	return b.String()
104}
105
106func usage() string {
107	return "## Try it\n\n" +
108		"- `:/<n>` — integer → Roman, e.g. `:/2024` → " + romannum.ToRoman(2024) + "\n" +
109		"- `:/r/<roman>` — Roman → integer, e.g. `:/r/MMXXIV` → 2024\n"
110}