From cb1b9806c30d37a25096d918e3e8bd261893c46d Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Sat, 22 Nov 2025 17:10:39 +0100 Subject: [PATCH] don't use delimiters for top level choice items --- html.go | 8 +++++++- html_test.go | 20 ++++++++++++++++++++ markdown.go | 1 + markdown_test.go | 20 ++++++++++++++++++++ runoff.go | 1 + runoff_test.go | 20 ++++++++++++++++++++ teletype.go | 1 + teletype_test.go | 20 ++++++++++++++++++++ 8 files changed, 90 insertions(+), 1 deletion(-) diff --git a/html.go b/html.go index dadd4a3..2beb9a7 100644 --- a/html.go +++ b/html.go @@ -153,7 +153,13 @@ func htmlSequence(s SyntaxItem) string { } func htmlChoice(s SyntaxItem) string { - ss := htmlSyntaxItems(s.choice) + items := make([]SyntaxItem, len(s.choice)) + copy(items, s.choice) + for i := range items { + items[i].topLevel = s.topLevel + } + + ss := htmlSyntaxItems(items) if s.topLevel { return strings.Join(ss, "\n") } diff --git a/html_test.go b/html_test.go index eeb987e..590159b 100644 --- a/html_test.go +++ b/html_test.go @@ -1562,6 +1562,26 @@ lines.

} }) + t.Run("top level choice with sequence item", func(t *testing.T) { + doc := textfmt.Doc( + textfmt.Syntax( + textfmt.Choice( + textfmt.Symbol("foo"), + textfmt.Sequence(textfmt.Symbol("bar"), textfmt.Symbol("baz")), + ), + ), + ) + + var b bytes.Buffer + if err := textfmt.HTMLFragment(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "
\nfoo\nbar baz\n
\n" { + t.Fatal(b.String()) + } + }) + t.Run("choice", func(t *testing.T) { doc := textfmt.Doc( textfmt.Syntax( diff --git a/markdown.go b/markdown.go index 3b79d31..6087a73 100644 --- a/markdown.go +++ b/markdown.go @@ -293,6 +293,7 @@ func renderMDChoice(w io.Writer, s SyntaxItem) { } item.delimited = false + item.topLevel = s.topLevel renderMDSyntaxItem(w, item) } diff --git a/markdown_test.go b/markdown_test.go index c92ab77..fd3d305 100644 --- a/markdown_test.go +++ b/markdown_test.go @@ -1706,6 +1706,26 @@ textfmt supports the following entries: } }) + t.Run("top level choice with sequence item", func(t *testing.T) { + doc := textfmt.Doc( + textfmt.Syntax( + textfmt.Choice( + textfmt.Symbol("foo"), + textfmt.Sequence(textfmt.Symbol("bar"), textfmt.Symbol("baz")), + ), + ), + ) + + var b bytes.Buffer + if err := textfmt.Markdown(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "```\nfoo\nbar baz\n```\n" { + t.Fatal(b.String()) + } + }) + t.Run("choice", func(t *testing.T) { doc := textfmt.Doc( textfmt.Syntax( diff --git a/runoff.go b/runoff.go index 86aa4a0..e9ac7c8 100644 --- a/runoff.go +++ b/runoff.go @@ -456,6 +456,7 @@ func renderRoffChoice(w io.Writer, s SyntaxItem) { } item.delimited = false + item.topLevel = s.topLevel renderRoffSyntaxItem(w, item) } diff --git a/runoff_test.go b/runoff_test.go index 9ebf358..7da0f71 100644 --- a/runoff_test.go +++ b/runoff_test.go @@ -2637,6 +2637,26 @@ and silver birch\~\~\~\~ | their canopies creating\~ | and shadow on the } }) + t.Run("top level choice with sequence item", func(t *testing.T) { + doc := textfmt.Doc( + textfmt.Syntax( + textfmt.Choice( + textfmt.Symbol("foo"), + textfmt.Sequence(textfmt.Symbol("bar"), textfmt.Symbol("baz")), + ), + ), + ) + + var b bytes.Buffer + if err := textfmt.Runoff(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != ".nf\nfoo\nbar baz\n.fi\n" { + t.Fatal(b.String()) + } + }) + t.Run("choice", func(t *testing.T) { doc := textfmt.Doc( textfmt.Syntax( diff --git a/teletype.go b/teletype.go index c177e5d..1d8a783 100644 --- a/teletype.go +++ b/teletype.go @@ -347,6 +347,7 @@ func renderTTYChoice(w io.Writer, s SyntaxItem) { } item.delimited = false + item.topLevel = s.topLevel renderTTYSyntaxItem(w, item) } diff --git a/teletype_test.go b/teletype_test.go index d8295b8..d3cf6f0 100644 --- a/teletype_test.go +++ b/teletype_test.go @@ -2276,6 +2276,26 @@ and silver birch | their canopies creating | and shadow on the } }) + t.Run("top level choice with sequence item", func(t *testing.T) { + doc := textfmt.Doc( + textfmt.Syntax( + textfmt.Choice( + textfmt.Symbol("foo"), + textfmt.Sequence(textfmt.Symbol("bar"), textfmt.Symbol("baz")), + ), + ), + ) + + var b bytes.Buffer + if err := textfmt.Teletype(&b, doc); err != nil { + t.Fatal(err) + } + + if b.String() != "foo\nbar baz\n" { + t.Fatal(b.String()) + } + }) + t.Run("choice", func(t *testing.T) { doc := textfmt.Doc( textfmt.Syntax(