# MARKDOWN module – parsing markdown

A basic Markdown parser

This is a basic Markdown parser.

The parser's ambitions are modest – it is intended to implement the core of the format, but not to be a comprehensive implementation. The implementation covers a decent fraction of the Gruber spec; the only major omission is that it currently knows nothing about inline HTML.

The implementation is intended to be Unicode-friendly, though the only places where this is relevant are in link reference keys (ie, `[key]: URL`) and in the YAML-style hash mentioned below.

The default output is in the form of ‘x-expressions’ – XML represented as scheme s-expressions, which is easy to wrangle (see the `xexpr` module).

You can parse a Markdown file with either `parse-markdown-file` or `parse-markdown-file/metadata`. The former returns the parsed contents of the file as an xexpr. The latter additionally returns, as multiple values, a structure which can be queried with `metadata/type`, obtaining either annotations or citation information as described below.

There is experimental built-in support for references, in the style of RMarkdown. Specifically, if a Markdown document contains references marked up like `[@foo]`, then the multiple values returned from `parse-markdown-file/metadata` will be a parse-tree and a collection of ‘metadata’. From that metadata, you can extract (with `(metadata/type metadata 'citation)`) a list of citations and the place in the parse-tree where they appear. The latter are the `(cite "foo")` elements in the parse-tree, which can therefore be edited retrospectively. A way of using this is illustrated in `examples/bibliography-in-markdown.scm`.

Similarly, `(metadata/type metadata 'annotation)` will produce a list of `("key" "value")` lists containing annotations from the input Markdown file. The annotations are of the form

    ---
    key: value

(ie, a YAML-style hash; this is the only YAML-ish content which is recognised). Note that

    Text
    ---
    key: value

will also be recognised as metadata, rather than a section heading. So don't write that.

## Functions

Index:

- metadata/type
- parse-markdown-file
- parse-markdown-file/metadata
- parse-markdown-string
- parse-markdown-string/metadata

### metadata/type

`metadata/type : <opaque> symbol? -> <various>` : Given a metadata list returned from `parse-markdown-file/metadata`, extract the elements keyed by `key`. The keys can be

- 'citation : this returns a list of lists, where the car of each list is the content of a `[@cite]` key and the cadr is the `(cite ...)` element in the parsed tree which corresponds to it.
- 'annotation : this is similarly a list of lists capturing key-value annotations within the Markdown (ie, `key: value` immediately after `----`).

The content of both of these should currently be regarded as very much subject to change.

### parse-markdown-file

`parse-markdown-file : string? -> list?` : Given a file name, parse it as Markdown and return the parse-tree.

The parse tree is an x-expression, containing a list of paragraph-level elements inside an enclosing `(div ...)`; see the `'xexpr` module.

For example, the Markdown

    This is a [link](http://example.org).
    ...

would parse to

    (div
      (p "This is a " (a ((href "http://example.org")) "link") ".")
      ...)

### parse-markdown-file/metadata

`parse-markdown-file/metadata : string? -> list? <opaque>` : Given a file containing Markdown, this parses it and returns the parse tree and metadata as multiple values. The parse-tree is as described in `parse-markdown-file`, and the metadata is a structure which can be queried by `metadata/type`.

### parse-markdown-string

`parse-markdown-string : string? -> list?` : Given a string, parse it as Markdown and return the parse-tree.

See `parse-markdown-file`.

### parse-markdown-string/metadata

`parse-markdown-string/metadata : string? -> list? <opaque>` : As with `parse-markdown-file/metadata`, but parsing the given string as Markdown.

Norman
2026 August 02