(lispkit markdown)
Library (lispkit markdown) provides an API for programmatically constructing Markdown documents, for parsing strings in Markdown format, as well as for mapping Markdown documents into corresponding HTML. The Markdown syntax supported by this library is based on the CommonMark Markdown specification.
Data Model
Markdown documents are represented using an abstract syntax that is implemented by three algebraic datatypes block, list-item, and inline, via define-datatype of library (lispkit datatype).
Blocks
At the top-level, a Markdown document consist of a list of blocks. The following recursively defined datatype shows all the supported block types as variants of type block.
(define-datatype block markdown-block?
(document blocks)
where (markdown-blocks? blocks)
(blockquote blocks)
where (markdown-blocks? blocks)
(list-items start tight items)
where (and (opt fixnum? start) (markdown-list? items))
(paragraph text)
where (markdown-text? text)
(heading level text)
where (and (fixnum? level) (markdown-text? text))
(indented-code lines)
where (every? string? lines)
(fenced-code lang lines)
where (and (opt string? lang) (every? string? lines))
(html-block lines)
where (every? string? lines)
(reference-def label dest title)
where (and (string? label) (string? dest) (every? string? title))
(table header alignments rows)
where (and (every? markdown-text? header)
(every? symbol? alignments)
(every? (lambda (x) (every? markdown-text? x)) rows))
(definition-list defs)
where (every? (lambda (x)
(and (markdown-text? (car x))
(markdown-list? (cdr x)))) defs)
(math-block tex)
where (string? tex)
(thematic-break))
(document blocks) represents a full Markdown document consisting of a list of blocks. (blockquote blocks) represents a blockquote block which itself has a list of sub-blocks. (list-items start tight items) defines either a bullet list or an ordered list. start is #f for bullet lists and defines the first item number for ordered lists. tight is a boolean which is #f if this is a loose list (with vertical spacing between the list items). items is a list of list items of type list-item as defined as follows:
(define-datatype list-item markdown-list-item?
(bullet ch tight? blocks)
where (and (char? ch) (markdown-blocks? blocks))
(ordered num ch tight? blocks)
where (and (fixnum? num) (char? ch) (markdown-blocks? blocks))
(task checked? item)
where (and (boolean? checked?) (markdown-list-item? item)))
(bullet ch tight? blocks) is an item of a bullet list with bullet character ch and (ordered num ch tight? blocks) is an item of an ordered list with number num and delimiter character ch (. or )). (task checked? item) turns a bullet or ordered list item item into a task list item (written - [ ] to do or - [x] done in Markdown) with a checkbox that is checked if checked? is true. A task list item is never nested in another one. Task list items are only created when parsing Markdown with the dialects full, math, or latex (see markdown below).
The most frequent Markdown block type is a paragraph. (paragraph text) represents a single paragraph of text where text refers to a list of inline text fragments of type inline (see below). (heading level text) defines a heading block for a heading of a given level, where level is a number starting with 1 (up to 6). (indented-code lines) represents a code block consisting of a list of text lines each represented by a string. (fenced-code lang lines) is similar: it defines a code block with code expressed in the given language lang. (html lines) defines a HTML block consisting of the given lines of text. (reference-def label dest title) introduces a reference definition consisting of a given label, a destination URI dest, as well as a title string. (table header alignments rows) defines a table consisting of headers, a list of markdown text describing the header of each column, alignments, a list of symbols l (= left), c (= center), and r (= right), and rows, a list of lists of markdown text. (definition-list defs) represents a definition list where defs refers to a list of definitions. A definition has the form (name def ...) where name is markdown text defining a name, and def is a bullet item using : as bullet character. Tables and definition lists are only created when parsing Markdown with the dialects extended, full, math, or latex (see markdown below). (math-block tex) represents a formula that is a block of its own, where tex is the LaTeX of the formula; such blocks are only created when parsing Markdown with the dialects math or latex (see markdown below). Finally, (thematic-break) introduces a thematic break block separating the previous and following blocks visually, often via a line.
Inline Text
Markdown text is represented as lists of inline text segments, each represented as an object of type inline. inline is defined as follows:
(define-datatype inline markdown-inline?
(text str)
where (string? str)
(code str)
where (string? str)
(emph text)
where (markdown-text? text)
(strong text)
where (markdown-text? text)
(underline text)
where (markdown-text? text)
(strikethrough text)
where (markdown-text? text)
(link text uri title)
where (and (markdown-text? text) (opt string? uri) (opt string? title))
(auto-link uri)
where (string? uri)
(email-auto-link email)
where (string? uri)
(image text uri title)
where (and (markdown-text? text) (opt string? uri) (opt string? title))
(html tag)
where (string? tag)
(math tex display? source)
where (and (string? tex) (boolean? display?) (opt string? source))
(line-break hard?))
(text str) refers to a text segment consisting of string str. (code str) refers to a code string str (often displayed as verbatim text). (emph text) represents emphasized text (often displayed as italics). (strong text) represents text in boldface. (underline text) represents underlined text and (strikethrough text) represents text that is struck through; both are only created when parsing Markdown with the dialects full, math, or latex (see markdown below). (link text uri title) represents a hyperlink with text linking to uri and title representing a title for the link. uri and title are optional: they are #f if the link has no destination or no title, which is what the parser returns for [text](uri). An empty title is the same as no title, as it is for the Markdown parser. (auto-link uri) is a link where uri is both the text and the destination URI. (email-auto-link email) is a "mailto:" link to the given email address email. (image text uri title) inserts an image at uri with image description text and image link title title; uri and title are optional like for link. (html tag) represents a single HTML tag of the form <tag>. (math tex display? source) represents a formula within a line of text, where tex is its LaTeX and display? is #t for display math. source is the formula as it was written, including its delimiters (e.g. "$x^2$" or "\(x^2\)"); #f stands for the LaTeX between dollar signs ($tex$, or $$tex$$ for display math). Finally, (line-break #f) introduces a "soft line break", whereas (line-break #t) inserts a "hard line break".
Creating Markdown documents
Markdown documents can either be constructed programmatically via the datatypes introduced above, or a string representing a Markdown documents gets parsed into the internal abstract syntax representation via function markdown.
For instance, (markdown "# My title\n\nThis is a paragraph.") returns a markdown document consisting of two blocks: a header block for header "My title" and a paragraph block for the text "This is a paragraph":
(markdown "# My title\n\nThis is a paragraph.")
⇒ #block:(document (#block:(heading 1 (#inline:(text "My title"))) #block:(paragraph (#inline:(text "This is a paragraph.")))))
The same document can be created programmatically in the following way:
(document
(list
(heading 1 (list (text "My title")))
(paragraph (list (text "This is a paragraph.")))))
⇒ #block:(document (#block:(heading 1 (#inline:(text "My title"))) #block:(paragraph (#inline:(text "This is a paragraph.")))))
Processing Markdown documents
Since the abstract syntax of Markdown documents is represented via algebraic datatypes, pattern matching can be used to deconstruct the data. For instance, the following function returns all the top-level headers of a given Markdown document:
(import (lispkit datatype)) ; this is needed to import `match`
(define (top-headings doc)
(match doc
((document blocks)
(filter-map (lambda (block)
(match block
((heading 1 text) (text->string text))
(else #f)))
blocks))))
An example for how top-headings can be applied to this Markdown document:
# *header* 1
Paragraph.
# __header__ 2
## header 3
The end.
is shown here:
(top-headings (markdown "# *header* 1\nParagraph.\n# __header__ 2\n## header 3\nThe end."))
⇒ ("header 1" "header 2")
Configuring document styles
Library (lispkit markdown) provides a comprehensive API for creating styled output from Markdown. The style of the documents generated by markdown->html-doc, markdown->styled-text, markdown->pdf, and markdown->pdf-data is configured by an association list config with symbol keys.
Configuration parameters
All entries are optional. #f and () stand for the default configuration, and if a key appears more than once, the first entry for the key is used. This makes it possible to override entries of a base configuration by adding entries in front of it, e.g. (cons '(safe-mode . #t) base-config). Unknown keys and values of the wrong type result in an error. The following keys are supported; for keys with #f as a possible value, the value #f selects the default:
| Key | Value | Default |
|---|---|---|
style | default, light, or dark; the preset that the other keys refine. default has fonts and colors of the system, light has colors for a white background, and dark has colors for a dark background; the preset also determines the theme for syntax highlighting, which syntax-highlighting refines. The defaults of the keys listed below are those of preset light. | light |
font-size, font-family, font-color | point size (a number), font name (a string), and HTML color (a string) of the text | 14, "system-ui, -apple-system, 'Helvetica Neue', Helvetica, sans-serif", "#000000" |
line-spacing | the line height of text as a multiple of the line height of its font; 1 or less keeps the line height of the font | 1.1 |
code-font-size, code-font-family, code-font-color | the same for inline code | 13, "'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace", "#0000AA" |
code-block-font-size, code-block-font-color, code-block-background | point size, text color and background color of code blocks | 12, "#000099", "#EEE" |
code-block-line-spacing | the same as line-spacing for the lines of code blocks | 1 |
border-color, blockquote-color | HTML colors of the border of code blocks and of the bars of blockquotes | "#DDD", "#BBE" |
h1-color, h2-color, h3-color, h4-color | HTML colors of headings | "#aa1111", "#003399", "#0055CC", "#007AFF" |
h1-font-size, h2-font-size, h3-font-size, h4-font-size | point sizes of headings; #f stands for 6, 4, 2 and 1 points more than font-size | #f |
header-font | font family of headings, a font name or a CSS font list, or #f for the font of the text | #f |
syntax-highlighting | #f disables syntax highlighting, #t enables it with default settings, an association list with the optional keys theme (a theme name or CSS), ignore-syntax-errors (boolean), ignored-languages (list of strings), and highlight-indented-code-blocks (boolean) configures it; see markdown->formatted-string | enabled |
tight-lists | boolean; if #t, the paragraphs of the items of loose lists are shown without paragraph spacing, too | #f |
align-list-markers | boolean; if #t, the numbers and bullets of list items are put on the baseline of the first line of their items, also if an image, such as a formula, makes that line taller than the text. Only used by markdown->styled-text; PDF documents always align them | #f |
max-image-width, max-image-height | a CSS length (e.g. "100%" or "300px") limiting the size of images, or #f | no limit |
custom-style | a string with CSS rules that get added to the style sheet of the document | "" |
image-base-url | a URL or the path of a directory that relative image paths of the Markdown text are resolved against, or #f | the value of base-url |
preset | trusted or untrusted; defines the default for the following options. untrusted is meant for Markdown that does not come from a trusted source: raw HTML is omitted, links are limited to http, https and mailto, and no images are loaded | trusted |
base-url | a URL or the path of a directory that relative URLs are resolved against, or #f | #f |
local-images | none, any, or the path of a directory. Controls which images stored in the local file system are loaded. Images that are not loaded are replaced by their alternative text. A directory restricts images to files inside of this directory. | any |
remote-images | none, any, or an http or https URL. Controls which images are loaded from the web. A URL restricts images to the web site and path of the URL. | any |
image-extensions | a list of path extensions (without dot) that the URLs of loaded images need to have | png, jpg, jpeg, gif, tif, tiff, bmp, ico, heic, heif, webp |
safe-mode | boolean; if #t, raw HTML is omitted and links are limited to http, https and mailto | #f |
timeout | the maximum time in seconds that markdown->styled-text, markdown->pdf, and markdown->pdf-data may take for rendering a document (including loading images), or #f for no limit | 30 |
text-size-multiplier | a number scaling font sizes, or #f | #f |
mermaid | #f, #t, or an association list configuring Mermaid diagrams; used by markdown->styled-text, markdown->pdf, and markdown->pdf-data (see "Mermaid diagrams"). The PDF procedures draw diagrams unless mermaid is #f | #f (#t for PDF documents) |
math | #f, #t, or an association list configuring formulas; used by markdown->styled-text, markdown->pdf, and markdown->pdf-data (see "Math formulas"). #f shows formulas as they were written, also in PDF documents | #t |
Paths are interpreted relative to the current directory, and strings starting with http:, https: or file: are URLs. The restrictions on images do not apply to images referred to by raw HTML or by custom-style.
(markdown->styled-text
(markdown "# Title\n\n")
'((font-family . "Helvetica")
(h1-color . "#cc3300")
(max-image-width . "50%")
(image-base-url . "images")
(remote-images . none)))
Mermaid diagrams
If mermaid is set, the content of fenced code blocks with the language mermaid is turned into images of the specified diagrams (see mermaid.js.org for the diagram syntax). The diagrams are rendered to images by a headless web view using the Mermaid script that comes with LispKit; no network connection is needed. A diagram that Mermaid rejects stays a code block, preceded by a note with the reason. Rendered diagrams are cached, so showing a document again is fast. Diagrams are not supported by markdown->html-doc, which ignores mermaid, and the timeout of the diagrams (5 seconds by default) is independent of the timeout for rendering the document. markdown->pdf and markdown->pdf-data draw these diagrams, with the default settings unless mermaid is an association list, and unlike markdown->styled-text also if there is no mermaid key at all; #f shows them as code. In a PDF document, all diagrams are scaled alike, so that a diagram that fills a page of width points fills the text of a page; max-width is the greatest width in points that a diagram has on the pages after this scaling.
The value of mermaid is #f, #t (default settings), or an association list with the following optional keys; defaults are in parentheses:
theme: Mermaid theme, one ofdefault,neutral,dark,forest, andbase(default)theme-variables: association list overriding variables of the theme, e.g.((primaryColor . "#ffcc00")); names are symbols or strings, values are strings (())font-family: font family of the text in diagrams, or#ffor the font of Mermaid's theme (#f)scale: factor by which the resolution of the rendered image is higher than its size (2)width: width in points of the page that diagrams are laid out on (800)margin: margin in points around a diagram;#fkeeps the margins that Mermaid adds, which depend on the diagram type (8)max-width: maximum width in points of a diagram in the text, or#ffor the width of the text (#f)spacing: minimum distance in points between a diagram and the text above and below it (16)timeout: maximum time in seconds for rendering a single diagram (5)
(markdown->styled-text
(markdown "```mermaid\ngraph LR\n A[Start] --> B{Choice}\n```")
'((mermaid . ((theme . forest) (max-width . 400)))))
Math formulas
If a Markdown document contains formulas (see the dialects math and latex of markdown for parsing them, and math and math-block for creating them), markdown->styled-text and related procedures typesets them with KaTeX: a formula within a line of text sits on the baseline of the text, has the color of the text around it and is as large as the text; a formula that is a block of its own is centered. The formulas are rendered to images by a headless web view using the KaTeX script, style sheet and fonts that come with LispKit; no network connection is needed. Rendered formulas are cached. A formula that KaTeX does not understand stays code (a block formula is preceded by a note with the reason). Documents without formulas are not affected. Formulas are not supported by markdown->html-doc, which ignores math and shows them as code. markdown->pdf and markdown->pdf-data typeset formulas, with the default settings unless math is an association list, and #f shows them as they were written; formulas are never wider than the text of a page, and max-width limits their width on the pages further.
The value of math is #t (default settings), #f (formulas are shown as code), or an association list with the following optional keys; defaults are in parentheses:
scale: factor by which the resolution of the images is higher than their size in points (3)spacing: minimum distance in points between a formula that is a block of its own and the text above and below it (8)max-width: width in points that wider formulas are scaled down to, or#ffor no limit (#f)timeout: maximum time in seconds for rendering the formulas of a document;0means no limit (15)macros,max-expand,max-size,min-rule-thickness,max-length: macros for formulas, limits for macro expansion, sizes, rules and the length of formulas; these keys are described with procedurelatex-math->imageof library(lispkit draw)
(markdown->styled-text
(markdown "The area is $\\pi r^2$." 'math)
'((math . ((scale . 2)))))
Generating PDF documents
Procedures markdown->pdf and markdown->pdf-data lay out text, lists, tables, block quotes and code blocks in the width of a page, and break them into pages. A page does not end within a list item, a code block or a table row, unless it is taller than a page, and a heading is not the last line of a page. Links are clickable, except for links to a place in the same document (#name). Diagrams (fenced code blocks with language mermaid) and formulas (math and math-block) are drawn as images, configured by the keys mermaid and math of config; with #f, diagrams are shown as code and formulas as they were written. Code blocks are colored by the syntax highlighter of the library, e.g. with a theme of your own. The key image-base-url of config determines where relative image paths are resolved against. The keys tight-lists and align-list-markers have no effect: the numbers and bullets of lists sit on the baseline of the first line of their items. All other keys described in "Configuring styled documents" apply; the text of a PDF document is about 70% as large as the text of a styled text with the same configuration, since the text of a printed page is smaller than the text on a screen (14 points become about 10 points), and text-size-multiplier scales it further. The default style is preset light.
An error is signaled if the margins leave less than 36 points for the text, or if the document cannot be rendered, e.g. because the rendering takes longer than the timeout.
API
block-type-tag 
Symbol representing the markdown block type. The type-for procedure of library (lispkit type) returns this symbol for all block objects.
list-item-type-tag 
Symbol representing the markdown list-item type. The type-for procedure of library (lispkit type) returns this symbol for all list item objects.
inline-type-tag 
Symbol representing the markdown inline type. The type-for procedure of library (lispkit type) returns this symbol for all inline objects.
(markdown-blocks? obj) 
Returns #t if obj is a proper list of objects o for which (markdown-block?`` o) returns #t; otherwise it returns #f.
(markdown-block? obj) 
Returns #t if obj is a variant of algebraic datatype block.
(markdown-block=? lhs rhs) 
Returns #t if markdown blocks lhs and rhs are equal after normalizing them; otherwise it returns #f. Normalizing merges adjacent text fragments, see markdown=?.
(markdown-block-equals? lhs rhs) 
Returns #t if markdown blocks lhs and rhs have the same structure; otherwise it returns #f. In contrast to markdown-block=?, the blocks are not normalized before they get compared.
(markdown-list? obj) 
Returns #t if obj is a proper list of list items i for which (markdown-list-item?`` i) returns #t; otherwise it returns #f.
(markdown-list-item? obj) 
Returns #t if obj is a variant of algebraic datatype list-item.
(markdown-list-item=? lhs rhs) 
Returns #t if markdown list items lhs and rhs are equal after normalizing them; otherwise it returns #f. Normalizing merges adjacent text fragments, see markdown=?.
(markdown-list-item-equals? lhs rhs) 
Returns #t if markdown list items lhs and rhs have the same structure; otherwise it returns #f. In contrast to markdown-list-item=?, the list items are not normalized before they get compared.
(markdown-text? obj) 
Returns #t if obj is a proper list of objects o for which (markdown-inline?`` o) returns #t; otherwise it returns #f.
(markdown-inline? obj) 
Returns #t if obj is a variant of algebraic datatype inline.
(markdown-inline=? lhs rhs) 
Returns #t if markdown inline text lhs and rhs are equal after normalizing them; otherwise it returns #f. Normalizing merges adjacent text fragments in the text of nested elements such as emph or link, see markdown=?.
(markdown-inline-equals? lhs rhs) 
Returns #t if markdown inline text lhs and rhs have the same structure; otherwise it returns #f. In contrast to markdown-inline=?, the inline text is not normalized before it gets compared.
(markdown? obj) 
Returns #t if obj is a valid markdown document, i.e. an instance of the document variant of datatype block; returns #f otherwise.
(markdown=? lhs rhs) 
Returns #t if markdown documents lhs and rhs are equal after normalizing them; otherwise it returns #f. Normalizing a document merges adjacent text fragments of the same paragraph, heading, etc. into a single fragment. This is necessary because the parser splits text into several fragments at characters that may start markup, such as (, [, or *, and does so differently for escaped characters: 2 * 3 is parsed into the fragments "2 ", "*", and " 3", whereas 2 \* 3 is parsed into the single fragment "2 * 3". Both documents are equal according to markdown=?, but not according to markdown-equals?.
(markdown-equals? lhs rhs) 
Returns #t if markdown documents lhs and rhs have the same structure; otherwise it returns #f. In contrast to markdown=?, the documents are not normalized before they get compared. Thus, two documents with the same text split into different text fragments are not equal.
(normalize-markdown obj) 
Returns the normal form of the Markdown object obj. obj is a block (such as a document), a list item, an inline object, or a list of blocks, list items, or inline objects (i.e. inline text); the result is an object of the same kind. The normal form of () is (). The following changes are made:
- The parser splits text into several
textfragments at characters that may start markup, such as(,[, or*, and does so differently for escaped characters. In the normal form, adjacenttextfragments are merged into one fragment, and emptytextfragments are removed. This holds for the text of paragraphs, headings, table cells, and definition lists, as well as for the text within emphasis, links, and images. - The line terminators of the lines of code blocks, HTML blocks, and formulas that are blocks are
\n.
Texts that mean the same, such as a (b) and a (b), are parsed into documents with the same normal form. Procedures markdown=?, markdown-block=?, markdown-list-item=?, and markdown-inline=? compare normal forms: (markdown=? lhs rhs) is the same as (markdown-equals? (normalize-markdown lhs) (normalize-markdown rhs)). An inline object remains an inline object when it is normalized; an empty text fragment becomes (text "").
(markdown->debug-string (markdown "2 * 3"))
⇒ "document(paragraph(text(\"2 \"), text(\"*\"), text(\" 3\")))"
(markdown->debug-string (normalize-markdown (markdown "2 * 3")))
⇒ "document(paragraph(text(\"2 * 3\")))"
(markdown str) 
(markdown str dialect)
Parses the text in Markdown format in str and returns a representation of the abstract syntax using the algebraic datatypes block, list-item, and inline.
The optional argument dialect is a symbol that selects the Markdown dialect, and thus the parser, that is used. Each dialect supports everything that the dialect listed before it supports:
standard(the default, also selected by#f) parses standard CommonMark.extendedadditionally supports tables and definition lists.fulladditionally supports underlined text (~text~), text that is struck through (~~text~~), and task lists (- [ ] to doand- [x] done). The resulting document may containunderlineandstrikethroughinline elements as well astasklist items.mathadditionally supports LaTeX formulas:$x^2$is a formula within a line of text,$$x^2$$a display formula within a line of text. A formula that is a block of its own is enclosed by$$on separate lines, written as the only content of a line (e.g.$$x^2$$), or written as a fenced code block with the info stringmath. The resulting document may containmathinline elements andmath-blockblocks. The other dialects leave dollar signs alone, so a text such ascosts $5 and $6is the same for them.latexadditionally supports the delimiters of LaTeX for formulas:(x^2)is a formula within a line of text,\[x^2\]a display formula within a line of text. A formula that is a block of its own is enclosed by\[and\]on separate lines, or written as the only content of a line (e.g.\[x^2\]). For all other dialects, a backslash in front of a parenthesis or bracket makes it an ordinary character.
The value #t selects latex, the most comprehensive dialect. Note that #t selected extended in earlier versions of LispKit; use extended for parsing tables and definition lists without underlined text, task lists, and formulas. All other values, e.g. unknown symbols, signal an error.
(markdown "| a | b |\n|---|---|\n| 1 | 2 |" 'extended)
(markdown "Some ~~old~~ text" 'full)
(markdown "The area is $\\pi r^2$." 'math)
(markdown->string md) 
Converts a Markdown document md into plain text, a string ignoring any markup. md needs to satisfy the markdown? predicate. Use markdown->formatted-string for a text that is laid out for display on a terminal, and markdown->source-string for turning md into Markdown again. In earlier versions of LispKit, this procedure was markdown->raw-string; the procedure that was called markdown->string is now markdown->formatted-string.
(markdown->debug-string md) 
Converts a Markdown document md into a debug string representation showing the internal structure. md needs to satisfy the markdown? predicate.
(markdown->formatted-string md) 
(markdown->formatted-string md width)
(markdown->formatted-string md width ansi)
Converts a Markdown document md into a formatted string suitable for display on a terminal. md needs to satisfy the markdown? predicate. width specifies the number of columns available for typesetting; if width is omitted or #f, the current terminal size (as determined by terminal-size) is used if available, falling back to 80 columns otherwise. Formulas are shown as they were written, e.g. $x^2$; formulas that are blocks are shown between lines with $$.
If ansi is omitted or #f, the output is plain text without ANSI escape sequences. If ansi is #t, the output uses ANSI escape sequences with default styling for headers, links, code, emphasis, etc. so that the result can be printed to an ANSI-compatible terminal with visual markup. Alternatively, ansi can be a list configuring the styling and colors used for each document element, as well as syntax highlighting for code blocks. This configuration list has up to fourteen elements, all of which are optional and can be omitted from the end of the list, or set to #f individually to fall back to the corresponding default:
-
header-properties: a list of text properties (see below), one for each header level, e.g.
(h1-properties h2-properties ...). Headers for which no entry is provided are typeset using the properties of the last provided entry, or without styling if the list is empty. -
link-properties: text properties used for typesetting link text.
-
code-properties: text properties used for typesetting inline code.
-
code-block-border-properties: text properties used for the border framing indented and fenced code blocks.
-
code-block-lang-properties: text properties used for typesetting the language tag of fenced code blocks.
-
emphasis-properties: text properties used for emphasized text (e.g.
*this*). -
strong-properties: text properties used for strongly emphasized text (e.g.
**this**). -
def-term-properties: text properties used for typesetting the term of a definition list entry.
-
def-descr-properties: text properties used for typesetting the description of a definition list entry.
-
blockquote-properties: text properties used for typesetting block quotes.
-
break-properties: text properties used for typesetting thematic breaks (horizontal rules).
-
syntax-highlighting: configuration for syntax-highlighting the content of code blocks.
#fdisables syntax highlighting entirely; omitting this element (or ending the list before it) enables syntax highlighting with default settings. Otherwise, this is a list with up to five elements (theme ignore-syntax-errors? ignored-languages highlight-indented-code-blocks? full-color?), all of which are optional: theme is the name of a syntax highlighting theme (a string), or#ffor the default theme; ignore-syntax-errors? is a boolean determining whether syntactic issues in the code being highlighted should be ignored (default:#t); ignored-languages is a list of language name strings for which syntax highlighting is skipped; highlight-indented-code-blocks? is a boolean determining whether indented (as opposed to fenced) code blocks are syntax-highlighted (default:#t); full-color? is a boolean determining whether full RGB colors are used for highlighting as opposed to the limited, extended ANSI color palette (default:#t). -
underline-properties: text properties used for underlined text (e.g.
~this~, supported by the Markdown dialectsfull,math, andlatex). The default isunderline. Since this element follows syntax-highlighting, specify#tfor the latter to keep syntax highlighting enabled with default settings. -
strikethrough-properties: text properties used for text that is struck through (e.g.
~~this~~, supported by the Markdown dialectsfull,math, andlatex). The default isstrikethrough.
Each properties argument above is a "text properties" value in one of the following formats:
#ffor using default styling.'()for no styling.- a symbol naming a predefined style or color; supported are:
default, bold, dim, italic, underline, blink, swap, strikethrough, default-color, black, maroon, green, olive, navy, purple, teal, silver, grey, red, lime, yellow, blue, fuchsia, aqua, andwhite. - a list (text-color background-color style ...) of up to three elements, where text-color and background-color define the foreground and background color, and the remaining elements are style symbols; supported styles are
bold,italic,underline,dim,blink,swap,strikethrough, anddefaultfor the terminal's default style).
text-color can be #f (default color), a color name symbol (default, black, maroon, green, olive, navy, purple, teal, silver, grey, red, lime, yellow, blue, fuchsia, aqua, or white), a hex color string (e.g. "#F67" or "#FF6677"), a color object as created by library (lispkit draw), or a fixnum between 0 and 255 referring to a color of the extended ANSI 256-color palette. background-color uses the same formats, except that its color name symbols are default, black, white, red, green, yellow, blue, magenta, cyan, light-black, light-red, light-green, light-yellow, light-blue, light-magenta, light-cyan, and light-white.
(markdown->source-string md) 
(markdown->source-string md dialect)
(markdown->source-string md dialect specials)
Converts a Markdown document md back into Markdown, represented in form of a string. md needs to satisfy the markdown? predicate. This is the counterpart of markdown: parsing the result with markdown and the same dialect yields a document with the same content as md. This makes it possible to change a Markdown document programmatically, or to build one from scratch, and to save it as Markdown. The documents are equal according to markdown=?, but not necessarily according to markdown-equals?, because the parser splits text into text fragments differently for escaped characters: 2 * 3 is parsed into three fragments, whereas 2 \* 3, which is what this procedure writes, is parsed into a single one.
The procedure does not reproduce the text that a document was parsed from. It chooses one form for every construct: headings are written with #, emphasis with * and **, and links in the inline form. Characters that could be taken for markup are escaped with a backslash (e.g. 2 \* 3).
dialect is a symbol that selects the Markdown dialect for which the source is written, in the same way as for markdown: standard (also selected by #f), extended, full, math, or latex. If dialect is omitted or #t, latex is used. The dialect determines which Markdown elements the source may use, and which characters have to be escaped: $5 is written as \$5 for math and latex, and stays as it is for the other dialects. Escapes needed by a dialect are harmless for dialects with fewer features, so the default latex produces source that is read correctly by all dialects, whereas a more specific dialect produces source with fewer escapes. The procedure does not fail if md has elements that dialect does not support, as it must not invent markup that the parser of dialect does not read. For instance, the cells of a table are written as paragraphs for standard, and underlined text is written without markup for standard and extended. In such cases, the source does not read back as md. Formulas are written with the delimiters of dialect: (x) is written as $x$ for math.
specials is a character set (see library (lispkit char-set)). Its characters are escaped in plain text in addition to the characters that have a meaning in dialect. It is empty by default.
(markdown->source-string (markdown "Setext Title\n===\n\n* one\n* __two__\n"))
⇒ "# Setext Title\n\n* one\n* **two**\n"
(markdown->source-string (markdown "Costs $5 *only*" 'standard) 'math)
⇒ "Costs \\$5 *only*\n"
(blocks->string bs) 
Converts a Markdown block or list of blocks bs into plain text, a string ignoring any markup.
(text->string text) 
Converts given inline text text into plain text, a string ignoring any markup in text. text needs to satisfy the markdown-text? predicate or be an inline element. This procedure is the counterpart of markdown->string for inline text. In earlier versions of LispKit, it was called text->raw-string; the procedure that was called text->string is now text->debug-string.
(text->debug-string text) 
Converts given inline text text into a string representation which approximates the markup in text using Markdown syntax. The result is meant for debugging: characters with a special meaning in Markdown are not escaped, so it cannot be parsed back reliably. text needs to satisfy the markdown-text? predicate or be an inline element.
(markdown->html md) 
Converts a Markdown document md into HTML, represented in form of a string. md needs to satisfy the markdown? predicate. Formulas are written as <span class="math inline">(tex)</span>, <span class="math display">\[tex\]</span> or, for blocks, <div class="math display">\[tex\]</div>, with the LaTeX escaped, so that libraries like KaTeX or MathJax can typeset them in a web page.
(blocks->html bs) 
(blocks->html bs tight)
Converts a Markdown block or list of blocks bs into HTML, represented in form of a string. tight? is a boolean and should be set to true if the conversion should consider tight typesetting (see CommonMark specification for details).
(text->html txt) 
Converts Markdown inline text or list of inline texts txt into HTML, represented in form of a string.
(markdown->sxml md) 
Converts a Markdown document md into SXML representation. md needs to satisfy the markdown? predicate. Formulas are represented by raw HTML, in the same form as for markdown->html.
(blocks->sxml bs) 
(blocks->sxml bs tight)
Converts a Markdown block or list of blocks bs into SXML representation. tight? is a boolean and should be set to true if the conversion should consider tight typesetting (see CommonMark specification for details).
(text->sxml txt) 
Converts Markdown inline text or a list of inline text objects txt into SXML representation.
(markdown->html-doc md) 
(markdown->html-doc md config)
Converts a Markdown document md into a styled HTML document, represented in form of a string. md needs to satisfy the markdown? predicate. config is an association list that configures the style of the document, as well as how images and raw HTML get handled; see "Configuring styled documents" below. If config is omitted or #f, the default configuration is used. The options for fonts, colors, syntax highlighting, images, and custom styles apply to the generated HTML. The options timeout and text-size-multiplier only matter for markdown->styled-text.
(markdown->styled-text md) 
(markdown->styled-text md config)
Converts a Markdown document md into a styled-text object (see library (lispkit draw)), e.g. for rendering it with draw-styled-text. md needs to satisfy the markdown? predicate. config is an association list with the same meaning as for markdown->html-doc; see "Configuring styled documents" above.
The following style keys are supported by config (for a full list, see above). Defaults are in parentheses; all keys are optional, and #f selects the default for keys that do not list #f as a value:
style: presetdefault,lightordarkthat the other keys refine (see above); the defaults below are those of presetlight, which is used if there is no preset (light)font-size: point size of the text (14)font-family: font family of the text, a font name or a CSS font list ("system-ui, -apple-system, 'Helvetica Neue', Helvetica, sans-serif")font-color: HTML color of the text ("#000000")line-spacing: line height of text as a multiple of the line height of its font (1.1)code-font-size: point size of inline code (13)code-font-family: font family of inline code ("'SF Mono', SFMono-Regular, ui-monospace, Menlo, Consolas, monospace")code-font-color: HTML color of inline code ("#0000AA")code-block-font-size: point size of code blocks (12)code-block-font-color: HTML color of the text of code blocks ("#000099")code-block-line-spacing: line height of the lines of code blocks as a multiple of the line height of their font (1)code-block-background: HTML color of the background of code blocks ("#EEE")border-color: HTML color of the border around code blocks ("#DDD")blockquote-color: HTML color of the bars next to block quotes ("#BBE")h1-color,h2-color,h3-color,h4-color: HTML colors of headings of levels 1 to 4 ("#aa1111","#003399","#0055CC","#007AFF")h1-font-size,h2-font-size,h3-font-size,h4-font-size: point sizes of headings of levels 1 to 4, or#ffor 6, 4, 2 and 1 points more thanfont-size(#f)header-font: font family of headings, a font name or a CSS font list, or#ffor the font of the text (#f)syntax-highlighting:#fdisables syntax highlighting of code blocks,#tenables it with default settings; an association list with the optional keystheme(theme name or CSS),ignore-syntax-errors(boolean),ignored-languages(list of strings), andhighlight-indented-code-blocks(boolean) configures it (enabled with default settings)tight-lists: if#t, the paragraphs of list items are shown without paragraph spacing, also in loose lists (#f)align-list-markers: if#t, the numbers and bullets of list items are put on the baseline of the first line of their items, also if an image makes that line taller than the text (#f)max-image-width: CSS length (e.g."100%"or"300px") limiting the width of images, or#f(no limit)max-image-height: CSS length limiting the height of images, or#f(no limit)image-base-url: URL or path of a directory against which relative image paths of the Markdown text are resolved, or#f(the value ofbase-url)base-url: URL or path of a directory against which relative URLs are resolved, or#f(#f)local-images:none,any, or the path of a directory; controls which images from the local file system are loaded, images that are not loaded are replaced by their alternative text (any)remote-images:none,any, or anhttporhttpsURL; controls which images from the web are loaded, a URL restricts images to its web site and path (any)timeout: maximum time in seconds for rendering the document, including loading images, or#ffor no limit (30)text-size-multiplier: number by which font sizes are scaled, or#f(#f)mermaid: draws fenced code blocks with the languagemermaidas diagrams;#fshows them as code,#tdraws them with default settings, and an association list with the optional keystheme,theme-variables,font-family,scale,width,margin,max-width,spacing, andtimeoutconfigures the diagrams; see below (#f)math: typesets formulas, i.e.mathandmath-blockelements;#fshows them as code,#ttypesets them with default settings, and an association list with the optional keysscale,spacing,max-width,timeout,macros,max-expand,max-size,min-rule-thickness, andmax-lengthconfigures them; see below (#t)
The styled text is generated asynchronously by the HTML rendering engine of the operating system, and markdown->styled-text waits for the result. Rendering a document therefore takes a moment, and images from the web are loaded unless remote-images is set to none (or a restricting URL). If the document cannot be rendered within the time given by timeout, or if rendering fails, an error is signaled. If this procedure is called by a thread other than the main thread of the application, the main thread needs to execute its run loop and must not wait for the calling thread. Otherwise, the procedure signals an error after the timeout has expired.
(markdown->pdf md) 
(markdown->pdf md config)
(markdown->pdf md config page-size)
(markdown->pdf md config page-size margins)
(markdown->pdf md config page-size margins title)
(markdown->pdf md config page-size margins title author)
Converts a Markdown document md into a PDF document and returns it as a PDF object (see library (lispkit pdf)). md needs to satisfy the markdown? predicate. All arguments except for md are optional; #f selects the default for an argument:
- config is an association list that configures the style of the document, as well as how images and raw HTML get handled; see "Configuring styled documents" above and "PDF documents" below. The default is the default configuration.
- page-size is the size of the pages: the symbol or string
a4orletter(US Letter), a string with a width and a height separated byx, in points or with a unit (pt,in,mm, orcm) after the height, which also applies to the width, e.g."210x297mm"or"8.5x11in", or a list(width height)of two positive numbers in points. The default isletter. - margins is the space between the text and the edges of a page: a number (points) for all edges, a string with one, two, or four widths separated by commas or spaces, each in points or with a unit, e.g.
"20mm"or"20mm, 15mm", or a list of one, two, or four numbers (points). As in CSS, one width stands for all edges, two widths are the widths of the upper and the lower edge, and of the left and the right edge, and four widths are the widths of the upper, the right, the lower and the left edge. The default is72(one inch). - title is a string with the title of the document, which becomes one of its properties. By default, the document has no title.
- author is a string with the author of the document, which becomes one of its properties. By default, the document has no author.
(markdown->pdf
(markdown "# Title\n\nThe area is $\\pi r^2$." 'math)
'((font-size . 16) (preset . untrusted))
'a4
"25mm, 20mm"
"Circles"
"Me")
(markdown->pdf-data md) 
(markdown->pdf-data md config)
(markdown->pdf-data md config page-size)
(markdown->pdf-data md config page-size margins)
(markdown->pdf-data md config page-size margins title)
(markdown->pdf-data md config page-size margins title author)
Converts a Markdown document md into a PDF document in the same way as markdown->pdf, with the same arguments, but returns the document as a bytevector, i.e. the content of a PDF file. This makes it possible to write the document directly into a file or to send it somewhere without creating a PDF object.
(call-with-port (open-binary-output-file "document.pdf")
(lambda (port)
(write-bytevector (markdown->pdf-data (markdown "# Title\n\nSome text.")) port)))
(save-markdown path md format) 
(save-markdown path md format config)
(save-markdown path md format config page-size)
(save-markdown path md format config page-size margins)
(save-markdown path md format config page-size margins title)
(save-markdown path md format config page-size margins title author)
Saves the Markdown document md in a new file at file path in file format. md needs to satisfy the markdown? predicate. A relative path refers to the current directory, and an existing file is replaced. format is one of the following symbols:
rtf: RTF file. RTF files cannot contain images, so diagrams are shown as code and formulas as they were written, regardless of the keysmermaidandmathof config.rtfd: RTFD document, a file package (a directory) with the text and the images of diagrams and formulas (and of the Markdown text, if it refers to images that are loaded). With#fformermaidandmath, diagrams are shown as code and formulas as they were written.pdf: PDF file; the same document asmarkdown->pdf-datareturns.
The optional arguments config, page-size, margins, title, and author are the same as for markdown->pdf (see there and "PDF documents" above); #f selects the default for an argument. The arguments page-size and margins are only used for format pdf, and the entries tight-lists and align-list-markers of config are not supported by any of the formats. title and author become properties of the document; macOS writes them to RTF and RTFD documents, iOS does not. An error is signaled for an unsupported format, if the document cannot be rendered, and if the file cannot be written.
(save-markdown "report.pdf" doc 'pdf '((font-size . 12)) 'a4 "25mm" "Report" "Me")
(save-markdown "report.rtfd" doc 'rtfd #f #f #f "Report" "Me")
(save-markdown "report.rtf" doc 'rtf)
(markdown-style-config) 
(markdown-style-config style)
(markdown-style-config style codestyle)
(markdown-style-config style codestyle cblockstyle)
(markdown-style-config style codestyle cblockstyle colors)
(markdown-style-config style codestyle cblockstyle colors syntax)
Returns a configuration (see "Configuring styled documents" below) for markdown->html-doc, markdown->styled-text, markdown->pdf, and markdown->pdf-data built from positional arguments. This procedure eases porting code from earlier versions of this library, where markdown->html-doc and markdown->styled-text had these positional arguments. A call (markdown->styled-text md style codestyle cblockstyle colors syntax) is replaced by (markdown->styled-text md (markdown-style-config style codestyle cblockstyle colors syntax)). Any argument can be omitted or set to #f to use the default for that argument.
- style is a list with up to three elements: (size font color). It specifies the default text style of the document. size is the point size of the font, font is a font name, and color is a HTML color specification (e.g.
"#FF6789"). - codestyle specifies the style of inline code in the same format.
- cblockstyle specifies the style of code blocks as a list (size color background) of up to three elements: the point size of the font, the text color, and the background color.
- colors is a list of HTML color specifications for the following document elements in this order: the border color of code blocks, the color of blockquote "bars", the color of H1, H2, H3 and H4 headers.
- syntax configures syntax highlighting for code blocks and is a list with up to four elements: (theme ignore-syntax-errors? ignored-languages highlight-indented-code-blocks?). If syntax is
#f, default syntax highlighting is used. If syntax is#tor(), syntax highlighting is disabled entirely.
(markdown-style-config '(16 "Helvetica" "#222222") #f #f #f '("xcode"))
⇒ ((font-size . 16) (font-family . "Helvetica") (font-color . "#222222")
(syntax-highlighting (theme . "xcode")))
(syntax-highlighting-theme name-or-spec) 
Returns the CSS associated with the theme name-or-spec. name-or-spec is a string that either refers to the name of the theme, or it is the CSS directly. This makes it possible to use dynamically created CSS code for highlighting purposes.
(syntax-highlighting-themes) 
Returns a list of syntax highlighting theme names that can be used with procedures supporting syntax highlighting.
(syntax-highlighting-themes)
⇒ ("zenburn" "xt256" "xcode-dusk" "xcode" "vulcan" "vs2015" "vs"
"tomorrow-night-eighties" "tomorrow-night-bright" "tomorrow-night-blue"
"tomorrow-night" "tomorrow" "sunburst" "stackoverflow-light"
"stackoverflow-dark" "srcery" "solarized-light" "solarized-dark"
"snazzy" "silk-light" "silk-dark" "shades-of-purple" "school-book"
"routeros" "rainbow" "railscasts" "qtcreator_light" "qtcreator_dark"
"purebasic" "pojoaque" "paraiso-light" "paraiso-dark" "ocean"
"obsidian" "nord" "nnfx-light" "nnfx-dark" "night-owl"
"monokai-sublime" "monokai" "mono-blue" "markdownkit-dark"
"markdownkit" "magula" "lioshi" "lightfair" "kimbie-light"
"kimbie-dark" "isbl-editor-light" "isbl-editor-dark"
"ir-black" "idea" "hybrid" "hopscotch" "gruvbox-light"
"gruvbox-dark" "grayscale" "gradient-light" "gradient-dark"
"googlecode" "gml" "github-gist" "github-dark" "github"
"foundation" "far" "dracula" "docco" "default" "dark" "darcula"
"color-brewer" "codepen-embed" "brown-paper" "atom-one-light"
"atom-one-dark-reasonable" "atom-one-dark" "atelier-sulphurpool-light"
"atelier-sulphurpool-dark" "atelier-seaside-light"
"atelier-seaside-dark" "atelier-savanna-light" "atelier-savanna-dark"
"atelier-plateau-light" "atelier-plateau-dark"
"atelier-lakeside-light" "atelier-lakeside-dark"
"atelier-heath-light" "atelier-heath-dark" "atelier-forest-light"
"atelier-forest-dark" "atelier-estuary-light" "atelier-estuary-dark"
"atelier-dune-light" "atelier-dune-dark" "atelier-cave-light"
"atelier-cave-dark" "ascetic" "arta" "arduino-light" "androidstudio"
"an-old-hope" "agate" "a11y-light" "a11y-dark")