(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)
(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:
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. 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:
(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. (link text uri title) represents a hyperlink with text linking to uri and title representing a title for the link. (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. (html tag) represents a single HTML tag of the form <tag>. 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":
The same document can be created programmatically in the following way:
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:
An example for how top-headings can be applied to this Markdown document:
is shown here:
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 equals; otherwise it returns #f.
(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 equals; otherwise it returns #f.
(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 equals; otherwise it returns #f.
(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 equals; otherwise it returns #f.
(markdown str) ![]()
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.
(markdown->html md) ![]()
Converts a Markdown document md into HTML, represented in form of a string. md needs to satisfy the markdown? predicate.
(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->html-doc md)
(markdown->html-doc md style)
(markdown->html-doc md style codestyle)
(markdown->html-doc md style codestyle cblockstyle)
(markdown->html-doc md style codestyle cblockstyle colors)
(markdown->html-doc md style codestyle cblockstyle colors syntax)
Converts a Markdown document md into a styled HTML document, represented in form of a string. md needs to satisfy the markdown? predicate. 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. 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. Any of style, codestyle, cblockstyle, and colors can be set to #f to use the default for that argument.
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?). theme is the name of a syntax highlighting theme (a string), or #f to use 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). If syntax is omitted or #f, default syntax highlighting is used. If syntax is #t or '(), syntax highlighting is disabled entirely.
(markdown->string md)
(markdown->string md width)
(markdown->string md width ansi)
Converts a Markdown document md into a plain-text 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.
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 twelve 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).
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->styled-text md)
(markdown->styled-text md style)
(markdown->styled-text md style codestyle)
(markdown->styled-text md style codestyle cblockstyle)
(markdown->styled-text md style codestyle cblockstyle colors)
(markdown->styled-text md style codestyle cblockstyle colors syntax)
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. The arguments style, codestyle, cblockstyle, colors, and syntax have the same meaning as for markdown->html-doc. Returns #f if the styled text object could not be created.
(markdown->sxml md) ![]()
Converts a Markdown document md into SXML representation. md needs to satisfy the markdown? predicate.
(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->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->raw-string md) ![]()
Converts a Markdown document md into raw text, a string ignoring any markup. md needs to satisfy the markdown? predicate.
(blocks->raw-string bs) ![]()
Converts a Markdown block or list of blocks bs into raw text, a string ignoring any markup.
(text->raw-string text) ![]()
Converts given inline text text into raw text, a string representation ignoring any markup in text. text needs to satisfy the markdown-text? predicate.
(text->string text) ![]()
Converts given inline text text into a string representation which encodes markup in text using Markdown syntax. text needs to satisfy the markdown-text? predicate.
(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.
Last updated