repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
090d8de
parent
49858df
author
ChloƩ Vulquin
date
2024-03-08 19:48:58 +0000 UTC
mdparser: extract ast manipulation into shared fn (#96)

1 files changed,  +30, -19
M shared/mdparser.go
+30, -19
 1@@ -213,29 +213,13 @@ func ParseText(text string) (*ParsedText, error) {
 2 	if err != nil {
 3 		return &parsed, fmt.Errorf("front-matter field (%s): %w", "title", err)
 4 	}
 5-	parsed.MetaData.Title = title
 6 	// 2. If an <h1> is found before a <p> or other heading is found, use that
 7-	if parsed.MetaData.Title == "" {
 8-		err = ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
 9-			if n.Kind() == ast.KindHeading {
10-				if h := n.(*ast.Heading); h.Level == 1 {
11-					parsed.MetaData.Title = string(h.Text(btext))
12-					p := h.Parent()
13-					p.RemoveChild(p, n)
14-				}
15-				return ast.WalkStop, nil
16-			}
17-			if ast.IsParagraph(n) {
18-				return ast.WalkStop, nil
19-			}
20-			return ast.WalkContinue, nil
21-		})
22-		if err != nil {
23-			panic(err) // unreachable
24-		}
25+	if title == "" {
26+		title = AstTitle(doc, btext, true)
27 	}
28 	// 3. else, set it to nothing (slug should get used later down the line)
29 	// this is implicit since it's already ""
30+	parsed.MetaData.Title = title
31 
32 	description, err := toString(metaData["description"])
33 	if err != nil {
34@@ -318,3 +302,30 @@ func ParseText(text string) (*ParsedText, error) {
35 
36 	return &parsed, nil
37 }
38+
39+// AstTitle extracts the title (if any) from a parsed markdown document.
40+//
41+// If "clean" is true, it will also remove the heading node from the AST.
42+func AstTitle(doc ast.Node, src []byte, clean bool) string {
43+	out := ""
44+	err := ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
45+		if n.Kind() == ast.KindHeading {
46+			if h := n.(*ast.Heading); h.Level == 1 {
47+				if clean {
48+					p := h.Parent()
49+					p.RemoveChild(p, n)
50+				}
51+				out = string(h.Text(src))
52+			}
53+			return ast.WalkStop, nil
54+		}
55+		if ast.IsParagraph(n) {
56+			return ast.WalkStop, nil
57+		}
58+		return ast.WalkContinue, nil
59+	})
60+	if err != nil {
61+		panic(err) // unreachable
62+	}
63+	return out
64+}