AtlatestRepositorysigil-markdown
1# Markdown
2
3> Parse Markdown text into SXML for use with `(sigil sxml)`. Supports
4> CommonMark-style syntax with YAML front matter.
5
6```scheme
7(import (sigil markdown))
8```
9
10## markdown->sxml
12Parse a Markdown string to an SXML document. Returns a `document` element
13containing the parsed content. YAML front matter becomes attributes on the
14document element.
16```scheme
17(markdown->sxml "# Hello\n\nWorld")
18; => (document (h1 "Hello") (p "World"))
20(markdown->sxml "---\ntitle: Hello\n---\n\n# Content")
21; => (document (@ (title "Hello")) (h1 "Content"))
23;; Inline formatting
24(markdown->sxml "**bold** and *italic*")
25; => (document (p (strong "bold") " and " (em "italic")))
27;; Links and images
28(markdown->sxml "[Sigil](https://sigil.dev)")
29; => (document (p (a (@ (href "https://sigil.dev")) "Sigil")))
30```
32## markdown-file->sxml
34Read a file and parse its contents as Markdown.
36```scheme
37(markdown-file->sxml "README.md")
38; => (document (h1 "Project Name") (p "Description...") ...)
39```
41## Supported Syntax
43| Markdown | SXML Tag |
44|---------------------|----------------------------------------------|
45| `# H1` ... `###### H6` | `(h1 ...)` ... `(h6 ...)` |
46| Blank-line separated text | `(p ...)` |
47| Fenced ` ``` ` or indented | `(pre ...)` or `(pre (@ (lang "x")) ...)` |
48| `> quoted text` | `(blockquote ...)` |
49| `- item` | `(ul (li ...))` |
50| `1. item` | `(ol (li ...))` |
51| `---` | `(hr)` |
52| `\| col \| col \|` | `(table (thead ...) (tbody ...))` |
53| `` `code` `` | `(code "...")` |
54| `**bold**` | `(strong ...)` |
55| `*italic*` | `(em ...)` |
56| `[text](url)` | `(a (@ (href "url")) "text")` |
57| `![alt](src)` | `(img (@ (src "src") (alt "alt")))` |
59## SXML Output Format
61Code blocks with a language annotation:
63```scheme
64(markdown->sxml "```scheme\n(+ 1 2)\n```")
65; => (document (pre (@ (lang "scheme")) "(+ 1 2)"))
66```
68Tables produce `thead`/`tbody` structure with optional alignment:
70```scheme
71(markdown->sxml "| Name | Age |\n|------|----:|\n| Alice | 30 |")
72; => (document
73; (table
74; (thead (tr (th "Name") (th (@ (style "text-align: right")) "Age")))
75; (tbody (tr (td "Alice") (td (@ (style "text-align: right")) "30")))))
76```
78Lists nest inline formatting:
80```scheme
81(markdown->sxml "- **bold** item\n- *italic* item")
82; => (document (ul (li (strong "bold") " item") (li (em "italic") " item")))
83```
85## Front Matter
87YAML front matter is delimited by `---` lines at the start of a document.
88Values are auto-typed: numbers become numbers, `true`/`false` become
89booleans, and `snake_case` keys are converted to `kebab-case` symbols.
91```scheme
92(markdown->sxml "---\ntitle: Hello World\npost_count: 42\ndraft: true\n---\n\nContent")
93; => (document (@ (title "Hello World") (post-count 42) (draft #t))
94; (p "Content"))
95```
97### parse-front-matter
99Parse front matter from a list of lines. Returns a pair of
100`(metadata . remaining-lines)` where metadata is an alist, or
101`(#f . lines)` if no front matter is present.
103```scheme
104(parse-front-matter '("---" "title: Hello" "---" "" "# Content"))
105; => (((title . "Hello")) "" "# Content")
107(parse-front-matter '("# No front matter"))
108; => (#f "# No front matter")
109```
111### parse-yaml-line
113Parse a single `key: value` line. Returns a pair or `#f`.
115```scheme
116(parse-yaml-line "title: Hello World") ; => (title . "Hello World")
117(parse-yaml-line "count: 42") ; => (count . 42)
118(parse-yaml-line "no colon here") ; => #f
119```
121### parse-yaml-value
123Parse a YAML value string into a typed Scheme value.
125```scheme
126(parse-yaml-value "42") ; => 42
127(parse-yaml-value "true") ; => #t
128(parse-yaml-value "\"hi\"") ; => "hi"
129(parse-yaml-value "hello") ; => "hello"
130```
132## Lower-Level API
134### parse-blocks
136Parse Markdown block elements from a list of lines. Returns a list of
137block structures (headers, paragraphs, code blocks, lists, tables, etc.).
139```scheme
140(parse-blocks '("# Hello" "" "World"))
141; => ((header 1 "Hello") (paragraph ("World")))
142```
144### parse-inline
146Parse inline Markdown elements from a text string. Returns a list of
147strings and SXML elements.
149```scheme
150(parse-inline "Hello **world**")
151; => ("Hello " (strong "world"))
153(parse-inline "`code` and [link](url)")
154; => ((code "code") " and " (a (@ (href "url")) "link"))
155```
157### string->lines
159Split a string into a list of lines on newline boundaries.
161```scheme
162(string->lines "a\nb\nc") ; => ("a" "b" "c")
163```
165## Common Patterns
167### Convert Markdown to HTML
169```scheme
170(import (sigil markdown)
171 (sigil sxml))
173(define (markdown->html text)
174 (let ((doc (markdown->sxml text)))
175 (sxml->html doc)))
176```
178### Extract Metadata from a Post
180```scheme
181(let* ((doc (markdown-file->sxml "post.md"))
182 (attrs (and (pair? (cdr doc))
183 (pair? (cadr doc))
184 (eq? (caadr doc) '@)
185 (cdadr doc))))
186 (assq 'title attrs))
187; => (title "My Post Title")
188```
190### Use with sigil-publish
192```scheme
193(import (sigil publish))
195;; sigil-publish automatically uses (sigil markdown) for .md files.
196;; The markdown classifier reads front matter during scanning and
197;; parses full content during rendering.
198(define my-site
199 (site title: "My Blog"
200 content: "posts/**/*.md"))
202(run-publish my-site)
203```