markdown API reference
A lightweight Markdown renderer for a small CommonMark subset: ATX headings, bold / italic emphasis, inline code, links, images, fenced code blocks, unordered / ordered lists (nested by indentation), blockquotes (nesting recursively), and GFM tables. Renders to HTML (through the html module, so escaping is handled for you) and to styled terminal text (through the ansi module). It also authors Markdown text (header / style / link / list / codeBlock / table). Pure Jennifer; line-oriented block parsing with a small inline scanner. Not full CommonMark: inline spans do not nest (the content of **...**, ... , a link, or an image alt is plain text), and there is no thematic break, setext heading, or reference-link support. A link / image URL cannot contain an unescaped ) (the scanner closes on the first one).
Import with import "markdown.j" as markdown;. See the markdown guide for prose and examples.
Functions
markdown.attr(node as Node, name as string)
A named string attribute of a node: "href" / "title" (a link / image), "lang" (a code block), "align" (a table cell), "ordered" ("true" / "false", a list), or "level" (a heading, as a string). Returns "" for an absent attribute.
Parameters
node{Node}- the nodename{string}- the attribute name
Returns {string} - the attribute value, or ""
markdown.bullets(items as list of string)
Render an unordered list, one - item per line.
Parameters
items{list of string}- the list items
Returns {string} - the Markdown bullet list
markdown.children(node as Node)
A node's direct children.
Parameters
node{Node}- the node
Returns {list of Node} - the child nodes
markdown.codeBlock(text as string)
Render a fenced code block around verbatim text.
Parameters
text{string}- the verbatim code
Returns {string} - the fenced Markdown code block
markdown.findAll(node as Node, selector as string)
Every node matching a /-separated selector relative to node: each step is a kind name, * (any kind), or name[k] (the k-th such child, 1-based). Steps match direct children.
Parameters
node{Node}- the node to search underselector{string}- the selector path (e.g. "list/item")
Returns {list of Node} - the matching nodes (empty if none)
markdown.get(node as Node, selector as string)
The first node matching selector (see findAll), or an empty node (typeOf "") if there is no match.
Parameters
node{Node}- the node to search underselector{string}- the selector path
Returns {Node} - the first match, or an empty node
markdown.gray(level as int)
A grey fill of the given 0-255 level (0 black, 255 white).
Parameters
level{int}- the grey level, 0-255
Returns {Fill} - the fill
markdown.has(node as Node, selector as string)
Whether any node matches selector (see findAll).
Parameters
node{Node}- the node to search underselector{string}- the selector path
Returns {bool} - true if at least one node matches
markdown.header(level as string, text as string)
Render an ATX heading.
Parameters
level{string}- the heading depth, "h1".."h6"text{string}- the heading text
Returns {string} - the Markdown heading line
Throws
{Error}- when level is not "h1".."h6"
markdown.headingStyle(background as Fill)
A heading style with the given background fill.
Parameters
background{Fill}- the background fill (off for none)
Returns {HeadingStyle} - the style
markdown.level(node as Node)
A heading's level (1-6); 0 for any other node.
Parameters
node{Node}- the node
Returns {int} - the heading level
markdown.link(text as string, url as string)
Render an inline link [text](url).
Parameters
text{string}- the link texturl{string}- the link target
Returns {string} - the Markdown link
markdown.noFill()
No fill (a transparent background).
Returns {Fill} - an off fill
markdown.numbered(items as list of string)
Render an ordered list, 1. item upward.
Parameters
items{list of string}- the list items
Returns {string} - the Markdown numbered list
markdown.pageBreak()
A page-break node. Placed in a document tree (typically between the blocks of a hand-assembled book), it makes renderPdf / toPdf start the following content on a fresh page - a lever independent of the level-one-heading page break. The HTML and ANSI renderers ignore it. In Markdown source, a lone <!-- pagebreak --> comment parses to the same node.
Returns {Node} - a page_break node
markdown.parse(md as string)
Parse Markdown into a document tree, walked by the reader accessors (typeOf / children / text / level / attr / get / findAll / has) - so a caller can inspect or transform a document (pull the headings for a table of contents, rewrite links, convert to another format) before rendering it. The returned node is the document root (its typeOf is "document"); its children are the top-level blocks. A document that nests too deep or holds too many nodes is a catchable "markdown" error.
Parameters
md{string}- the Markdown source
Returns {Node} - the document root node
markdown.pdfDefaults()
The default options: US Letter, 54-point margins, the Helvetica family for body / bold / italic / headings, Courier for code, 11-point body. Copy and tweak fields (value semantics) to customise.
Returns {PdfOptions} - the default options
markdown.render(doc as Node, format as string)
Render a document tree (a parse result, or a hand-built one) to a string. format is "html" (block elements concatenated, no indentation) or "ansi" (styled terminal text, blocks separated by a blank line). A "document" node renders its children; any other node renders as a single block. An unknown format is a catchable "markdown" error.
Parameters
doc{Node}- the document (or block) node to renderformat{string}- "html" or "ansi"
Returns {string} - the rendered document
markdown.renderPdf(doc as Node, opts as PdfOptions)
Render a parsed (or hand-built / transformed) markdown document tree to PDF bytes with the given options. A one-liner over renderPdfDoc + pdf.render; call those two directly when you need to touch the pdf.Document in between.
Parameters
doc{Node}- the document root node fromparseopts{PdfOptions}- the page geometry and fonts
Returns {bytes} - the PDF document
markdown.renderPdfDoc(doc as Node, opts as PdfOptions)
Lay a parsed (or hand-built / transformed) markdown document tree out to a pdf.Document, ready for any document-level work - a running header or footer (pdf.setHeader / pdf.setFooter, with %page% / %pages%), extra pdf.info metadata, more bookmarks - before it is serialised with pdf.render. This is the seam renderPdf renders through; use it directly when you need the document itself (a page number in a book's footer needs the total page count, which only exists once the whole document is laid out).
Parameters
doc{Node}- the document root node fromparseopts{PdfOptions}- the page geometry and fonts
Returns {pdf.Document} - the laid-out document, not yet serialised
markdown.rgb(r as int, g as int, b as int)
An RGB fill (each component 0-255).
Parameters
r{int}- red 0-255g{int}- green 0-255b{int}- blue 0-255
Returns {Fill} - the fill
markdown.style(kind as string, text as string)
Wrap text in an inline emphasis span.
Parameters
kind{string}- the emphasis, "bold" / "italic" / "code"text{string}- the text to wrap
Returns {string} - the emphasised Markdown span
Throws
{Error}- when kind is not "bold" / "italic" / "code"
markdown.table(headings as list of string, aligns as list of string, rows as list of list of string)
Render a GFM table. Columns follow headings: a short row is padded with empty cells, extra cells are dropped. Pipes and newlines in a cell are made safe.
Parameters
headings{list of string}- the column headingsaligns{list of string}- the per-column alignment ("left" / "right" / "center" / "none";[]for all-default)rows{list of list of string}- the data rows, each a list of cell strings
Returns {string} - the GFM table source
Throws
{Error}- when an align value is not "left" / "right" / "center" / "none"
markdown.tablePretty(md as string)
Reformat every GFM table in Markdown text so its source columns line up (padded cells, aligned delimiters), leaving all other lines exactly as written. The handcraft-then-prettify workflow, in one call.
Parameters
md{string}- the Markdown source
Returns {string} - the source with its tables aligned
markdown.text(node as Node)
The text content of a node: a leaf's own literal text, else the concatenation of its descendants' text - so text of a heading (or any container) is its full flattened text, handy for a table of contents.
Parameters
node{Node}- the node
Returns {string} - the flattened text
markdown.toAnsi(md as string)
Render Markdown to styled terminal text, blocks separated by a blank line.
Parameters
md{string}- the Markdown source
Returns {string} - the rendered terminal text
markdown.toHtml(md as string)
Render Markdown to an HTML string (block elements concatenated, no indentation). Safe by default: a raw HTML block in the source (a line opening with <tag>) is escaped and rendered as literal text, so passing untrusted Markdown (a README, a user comment) cannot inject a <script> or an event-handler attribute. Everything the renderer builds is already escaped (text, link URLs via an allow-list, image attributes). To pass raw HTML through for trusted input, use toHtmlWith with allowRawHtml: true.
Parameters
md{string}- the Markdown source
Returns {string} - the rendered HTML
markdown.toHtmlWith(md as string, opts as HtmlOptions)
Render Markdown to HTML with explicit options. The only option today is allowRawHtml: set it true to emit raw HTML blocks verbatim (for trusted Markdown), or false (the default toHtml behavior) to escape them.
Parameters
md{string}- the Markdown sourceopts{HtmlOptions}- the render options
Returns {string} - the rendered HTML
markdown.toPdf(md as string)
Render a Markdown string to PDF bytes with the default options.
Parameters
md{string}- the Markdown source
Returns {bytes} - the PDF document
markdown.toPdfWith(md as string, opts as PdfOptions)
Render a Markdown string to PDF bytes with the given options.
Parameters
md{string}- the Markdown sourceopts{PdfOptions}- the page geometry and fonts
Returns {bytes} - the PDF document
markdown.typeOf(node as Node)
The kind of a node ("document", "heading", "link", "text", ...).
Parameters
node{Node}- the node
Returns {string} - the node kind
Structs
markdown.Fill
A fill colour (0-255 RGB) that may be off. on: false means "no fill" (draw nothing); an on: true fill paints a background behind a heading or a table header row. Build one with gray / rgb, or noFill for none.
| Field | Type | Description |
|---|---|---|
on | bool | whether the fill is applied at all |
r | int | red 0-255 |
g | int | green 0-255 |
b | int | blue 0-255 |
markdown.HeadingStyle
The style for a heading level - currently just a background fill painted behind the heading text (a shaded bar). A struct so more style knobs can be added later.
| Field | Type | Description |
|---|---|---|
background | Fill | the background fill (off for none) |
markdown.HtmlOptions
Options for HTML rendering.
| Field | Type | Description |
|---|---|---|
allowRawHtml | bool | pass raw HTML blocks through verbatim (trusted input only). Default (zero value) is false: raw HTML is escaped, so untrusted Markdown cannot inject scripts or event handlers. |
markdown.Node
A node in a parsed Markdown document tree. The tree is walked with the reader accessors (typeOf / children / text / level / attr / get / findAll / has), the same family vocabulary as xml / html. A node's kind is one of the block kinds "document" / "heading" / "paragraph" / "code" / "list" / "item" / "table" / "row" / "cell" / "quote", or the inline kinds "text" / "codespan" / "strong" / "emphasis" / "link" / "image".
| Field | Type | Description |
|---|---|---|
kind | string | the node kind |
level | int | a heading's level (1-6); 0 otherwise |
text | string | literal text (a text / codespan / code node, or an image's alt); "" for a container (read its content with the text accessor) |
lang | string | a fenced code block's language ("" if none) |
ordered | bool | whether a list is ordered |
url | string | a link / image target |
title | string | a link / image title ("" if none) |
align | string | a table cell's alignment ("left" / "right" / "center" / "") |
children | list of Node | the child nodes |
markdown.PdfOptions
Page geometry and fonts for a render. margin is applied to all four sides; bodyFont / boldFont / italicFont / monoFont are standard-14 font names for body text and its inline styles, headingFont for headings. bodySize is the body point size; heading sizes derive from the heading level.
| Field | Type | Description |
|---|---|---|
pageWidth | int | page width in points (Letter 612, A4 595) |
pageHeight | int | page height in points (Letter 792, A4 842) |
margin | int | margin on every side, in points |
bodyFont | string | standard-14 font for body text |
boldFont | string | standard-14 font for **strong** |
italicFont | string | standard-14 font for *emphasis* |
monoFont | string | standard-14 font for inline / block code |
headingFont | string | standard-14 font for headings |
bodySize | int | body text point size |
tablePad | int | padding inside a table cell, in points (table density) |
tableHeaderFill | Fill | background fill behind a table's header row (off for none) |
headingStyles | list of HeadingStyle | per-level heading style; index 0 is h1, 1 is h2, and so on (missing / off entries render with no background) |
title | string | PDF document Title metadata ("" = unset) |
author | string | PDF document Author metadata ("" = unset) |
subject | string | PDF document Subject metadata ("" = unset) |
keywords | string | PDF document Keywords metadata ("" = unset) |
bookmarkLevel | int | bookmark headings up to this level (0 = none; 2 = h1 + h2) |
unencodable | string | substitute for a character the standard-14 fonts cannot encode ("?" default; "" drops it) |
codeFill | Fill | background fill behind a code block (off for none) |
codeBorder | Fill | border stroke around a code block (off for none) |
quoteFill | Fill | background fill behind a blockquote (off for none) |
quoteRule | Fill | colour of the vertical bar down a blockquote's left edge (off for none) |
creator | string | PDF document Creator metadata ("" = unset) |
producer | string | PDF document Producer metadata ("" = keep the pdf default) |