Markdown
Parse Markdown text into SXML for use with (sigil sxml). Supports CommonMark-style syntax with YAML front matter.(import (sigil markdown))markdown->sxml
Parse a Markdown string to an SXML document. Returns a document element containing the parsed content. YAML front matter becomes attributes on the document element.
(markdown->sxml "# Hello\n\nWorld")
; => (document (h1 "Hello") (p "World"))
(markdown->sxml "---\ntitle: Hello\n---\n\n# Content")
; => (document (@ (title "Hello")) (h1 "Content"))
;; Inline formatting
(markdown->sxml "**bold** and *italic*")
; => (document (p (strong "bold") " and " (em "italic")))
;; Links and images
(markdown->sxml "[Sigil](https://sigil.dev)")
; => (document (p (a (@ (href "https://sigil.dev")) "Sigil")))markdown-file->sxml
Read a file and parse its contents as Markdown.
(markdown-file->sxml "README.md")
; => (document (h1 "Project Name") (p "Description...") ...)Supported Syntax
| Markdown | SXML Tag | |||
|---|---|---|---|---|
# H1 ... ###### H6 | (h1 ...) ... (h6 ...) | |||
| Blank-line separated text | (p ...) | |||
Fenced ` or indented | (pre ...) or (pre (@ (lang "x")) ...) | |||
> quoted text | (blockquote ...) | |||
- item | (ul (li ...)) | |||
1. item | (ol (li ...)) | |||
--- | (hr) | |||
| `\ | col \ | col \ | ` | (table (thead ...) (tbody ...)) |
` code ` | (code "...") | |||
**bold** | (strong ...) | |||
*italic* | (em ...) | |||
[text](url) | (a (@ (href "url")) "text") | |||
 | (img (@ (src "src") (alt "alt"))) |
SXML Output Format
Code blocks with a language annotation:
(markdown->sxml "```scheme\n(+ 1 2)\n```")
; => (document (pre (@ (lang "scheme")) "(+ 1 2)"))Tables produce thead/tbody structure with optional alignment:
(markdown->sxml "| Name | Age |\n|------|----:|\n| Alice | 30 |")
; => (document
; (table
; (thead (tr (th "Name") (th (@ (style "text-align: right")) "Age")))
; (tbody (tr (td "Alice") (td (@ (style "text-align: right")) "30")))))Lists nest inline formatting:
(markdown->sxml "- **bold** item\n- *italic* item")
; => (document (ul (li (strong "bold") " item") (li (em "italic") " item")))Front Matter
YAML front matter is delimited by --- lines at the start of a document. Values are auto-typed: numbers become numbers, true/false become booleans, and snake_case keys are converted to kebab-case symbols.
(markdown->sxml "---\ntitle: Hello World\npost_count: 42\ndraft: true\n---\n\nContent")
; => (document (@ (title "Hello World") (post-count 42) (draft #t))
; (p "Content"))parse-front-matter
Parse front matter from a list of lines. Returns a pair of (metadata . remaining-lines) where metadata is an alist, or (#f . lines) if no front matter is present.
(parse-front-matter '("---" "title: Hello" "---" "" "# Content"))
; => (((title . "Hello")) "" "# Content")
(parse-front-matter '("# No front matter"))
; => (#f "# No front matter")parse-yaml-line
Parse a single key: value line. Returns a pair or #f.
(parse-yaml-line "title: Hello World") ; => (title . "Hello World")
(parse-yaml-line "count: 42") ; => (count . 42)
(parse-yaml-line "no colon here") ; => #fparse-yaml-value
Parse a YAML value string into a typed Scheme value.
(parse-yaml-value "42") ; => 42
(parse-yaml-value "true") ; => #t
(parse-yaml-value "\"hi\"") ; => "hi"
(parse-yaml-value "hello") ; => "hello"Lower-Level API
parse-blocks
Parse Markdown block elements from a list of lines. Returns a list of block structures (headers, paragraphs, code blocks, lists, tables, etc.).
(parse-blocks '("# Hello" "" "World"))
; => ((header 1 "Hello") (paragraph ("World")))parse-inline
Parse inline Markdown elements from a text string. Returns a list of strings and SXML elements.
(parse-inline "Hello **world**")
; => ("Hello " (strong "world"))
(parse-inline "`code` and [link](url)")
; => ((code "code") " and " (a (@ (href "url")) "link"))string->lines
Split a string into a list of lines on newline boundaries.
(string->lines "a\nb\nc") ; => ("a" "b" "c")Common Patterns
Convert Markdown to HTML
(import (sigil markdown)
(sigil sxml))
(define (markdown->html text)
(let ((doc (markdown->sxml text)))
(sxml->html doc)))Extract Metadata from a Post
(let* ((doc (markdown-file->sxml "post.md"))
(attrs (and (pair? (cdr doc))
(pair? (cadr doc))
(eq? (caadr doc) ,@)
(cdadr doc))))
(assq 'title attrs))
; => (title "My Post Title")Use with sigil-publish
(import (sigil publish))
;; sigil-publish automatically uses (sigil markdown) for .md files.
;; The markdown classifier reads front matter during scanning and
;; parses full content during rendering.
(define my-site
(site title: "My Blog"
content: "posts/**/*.md"))
(run-publish my-site)