diff --git a/build-tools/labsite-gen/main.go b/build-tools/labsite-gen/main.go
index e3288904..a8a9a31c 100644
--- a/build-tools/labsite-gen/main.go
+++ b/build-tools/labsite-gen/main.go
@@ -14,7 +14,12 @@ import (
"rsc.io/markdown"
)
-const marker = "[>]"
+const (
+ detailsMarker = "[>]"
+ nextButtonMarker = "[Next]"
+)
+
+var nextButton = newNextButton()
func main() {
if len(os.Args) != 3 {
@@ -34,6 +39,7 @@ func run(mdFile, htmlfFile string) error {
return err
}
doc := parse(string(md))
+ replaceNextButton(doc)
doc.Blocks = collapse(doc.Blocks)
html := markdown.ToHTML(doc)
@@ -45,6 +51,29 @@ func parse(md string) *markdown.Document {
return p.Parse(md)
}
+func replaceNextButton(doc *markdown.Document) {
+ for i, block := range doc.Blocks {
+ if isNextButton(block) {
+ doc.Blocks[i] = nextButton
+ }
+ }
+}
+
+func isNextButton(block markdown.Block) bool {
+ paragraph, ok := block.(*markdown.Paragraph)
+ if !ok {
+ return false
+ }
+ if len(paragraph.Text.Inline) != 1 {
+ return false
+ }
+ plain, ok := paragraph.Text.Inline[0].(*markdown.Plain)
+ if !ok {
+ return false
+ }
+ return plain.Text == nextButtonMarker
+}
+
func collapse(blocks []markdown.Block) []markdown.Block {
var result []markdown.Block
for idx := 0; idx < len(blocks); {
@@ -75,19 +104,22 @@ func isCollapsible(block markdown.Block) bool {
return false
}
plain, ok := heading.Text.Inline[0].(*markdown.Plain)
- return ok && strings.HasPrefix(plain.Text, marker)
+ return ok && strings.HasPrefix(plain.Text, detailsMarker)
}
func deleteCollapseMarker(heading *markdown.Heading) {
// assumes isCollapsible returned true
plain := heading.Text.Inline[0].(*markdown.Plain)
- s := strings.TrimPrefix(plain.Text, marker)
+ s := strings.TrimPrefix(plain.Text, detailsMarker)
s = strings.TrimLeftFunc(s, unicode.IsSpace)
plain.Text = s
}
func findEndIdx(level, start int, blocks []markdown.Block) int {
for i := start; i < len(blocks); i++ {
+ if blocks[i] == nextButton {
+ return i
+ }
if _, ok := blocks[i].(*markdown.ThematicBreak); ok {
return i
}
@@ -110,8 +142,15 @@ func toDetailsHTML(heading *markdown.Heading, blocks []markdown.Block) *markdown
buf.WriteString(markdown.ToHTML(block))
}
buf.WriteString("")
- doc := parse(buf.String())
- return doc.Blocks[0].(*markdown.HTMLBlock)
+ htmlBlock := &markdown.HTMLBlock{
+ Text: strings.Split(buf.String(), "\n"),
+ }
+ return htmlBlock
+}
+
+func newNextButton() *markdown.Paragraph {
+ doc := parse(``)
+ return doc.Blocks[0].(*markdown.Paragraph)
}
func isThematicBreak(blocks []markdown.Block, idx int) bool {
diff --git a/build-tools/labsite-gen/main_test.go b/build-tools/labsite-gen/main_test.go
index 94b5ace0..cf1401a8 100644
--- a/build-tools/labsite-gen/main_test.go
+++ b/build-tools/labsite-gen/main_test.go
@@ -63,6 +63,26 @@ anybody here?`,
hallo
+
+print 1
+
+print 2
+
hallo
\n", + }, + { + name: "single button", + in: `[Next]`, + wantMD: `` + "\n", + wantHTML: `` + "\n", + }, + { + name: "multiple buttons", + in: `# Heading +[Next] + +paragraph + +[Next]`, + wantMD: ` +# Heading + + + +paragraph + + +`[1:], + wantHTML: ` +paragraph
+ +`[1:], + }, +} + +func TestReplaceNextButton(t *testing.T) { + for _, tt := range nextButtonTests { + t.Run(tt.name, func(t *testing.T) { + p := markdown.Parser{} + doc := p.Parse(tt.in) + replaceNextButton(doc) + gotMD := markdown.Format(doc) + assert.Equal(t, tt.wantMD, gotMD) + gotHTML := markdown.ToHTML(doc) + assert.Equal(t, tt.wantHTML, gotHTML) + }) + } +}