LOWDOWN(3)
๐ LOWDOWN(3) โ simple markdown translator library โจ
okay bestie, welcome to the lowdown(3) page. This is the library that parses lowdown(5) into a bunch of different output formats, and we're gonna get you comfy with it. No cap.
๐ธ NAME
lowdown โ simple markdown translator library
๐ LIBRARY
library โliblowdownโ
๐ง SYNOPSIS
#include <sys/queue.h>
#include <stdio.h>
#include <lowdown.h>
struct lowdown_meta
struct lowdown_node
struct lowdown_opts
๐ DESCRIPTION
This library parses lowdown(5) into various output formats. Slay.
The library starts with a high-level interface made of lowdown_buf(3), lowdown_buf_diff(3), lowdown_file(3), and lowdown_file_diff(3).
Those high-level functions talk to low-level functions that do the actual parsing and formatting. The low-level crew is lowdown_doc_new(3), lowdown_doc_parse(3), and lowdown_doc_free(3), and they're what turn lowdown(5) documents into an abstract syntax tree.
The front-end functions for freeing, allocation, and rendering are literally these:
- HTML5:
lowdown_html_free(3),lowdown_html_new(3),lowdown_html_rndr(3) - gemini:
lowdown_gemini_free(3),lowdown_gemini_new(3),lowdown_gemini_rndr(3) - LaTeX:
lowdown_latex_free(3),lowdown_latex_new(3),lowdown_latex_rndr(3) - OpenDocument:
lowdown_odt_free(3),lowdown_odt_new(3),lowdown_odt_rndr(3) - roff:
lowdown_roff_free(3),lowdown_roff_new(3),lowdown_roff_rndr(3) - UTF-8 ANSI terminal:
lowdown_term_free(3),lowdown_term_new(3),lowdown_term_rndr(3) - debugging:
lowdown_tree_rndr(3)
To compile and link, use pkg-config(1):
% cc `pkg-config --cflags lowdown` -c -o sample.o sample.c
% cc -o sample sample.o `pkg-config --libs lowdown`
๐ก๏ธ Pledge Promises
The lowdown library is built to operate in security-sensitive environments, like the ones using pledge(2) on OpenBSD. The only promise required is stdio for lowdown_file_diff(3) and lowdown_file(3): both need access to the stream for reading input. That's it, bestie.
๐ฆ TYPES
All lowdown functions use one or more of the following structures.
The main structure for configuring parsing and output is struct lowdown_opts. It has the following fields:
enum lowdown_type typeโ The output medium:LOWDOWN_HTMLโ HTML5LOWDOWN_LATEXโ LaTeXLOWDOWN_MANโ roff-manmacrosLOWDOWN_MDOCโ roff-mdocmacrosLOWDOWN_FODTโ โflatโ OpenDocumentLOWDOWN_TERMโ ANSI-compatible UTF-8 terminal outputLOWDOWN_GEMINIโ Gemini โgemtextโ formatLOWDOWN_MSโ roff-msmacrosLOWDOWN_TREEโ syntax tree (debugging)
unsigned int featโ Parse-time features. This bit-field may have the following bits OR'd:LOWDOWN_ATTRSโ Parse PHP extra link, header, and image attributes.LOWDOWN_AUTOLINKโ Parsehttp,https,ftp,mailto, and relative links or link fragments.LOWDOWN_CALLOUTSโ Parse MDN/GFM callouts (โadmonitionsโ).LOWDOWN_COMMONMARKโ Tighten input parsing to the CommonMark specification. Allows for the following features:- Using the first ordered list value instead of starting all lists at one.
- Lists immediately following paragraphs. This feature is experimental and incomplete. iykyk.
LOWDOWN_DEFLISTโ Parse PHP extra definition lists. This is currently constrained to single-key lists.LOWDOWN_FENCEDโ Parse GFM fenced (language-specific) code blocks.LOWDOWN_FOOTNOTESโ Parse MMD style footnotes. This only supports the referenced footnote style, not the โinlineโ style.LOWDOWN_HILITEโ Parse highlit sequences. These are disabled by default because they may be erroneously interpreted as section headers.LOWDOWN_IMG_EXTโ Deprecated. UseLOWDOWN_ATTRSinstead.LOWDOWN_MANTITLEโ Recognise manpage titles in Pandoc metadata title lines. Only applicable ifLOWDOWN_METADATAis also provided. Manpages titles must begin with a non-empty title followed by an open parenthesis, digit or โnโ, optional letters after, then a closing parenthesis. This may be optionally followed by a source and, if a vertical bar is detected, the content after as the volume. These are passed to the renderers as the title, volume, and optionally source and volume metadata key-value pairs. The original title is not recoverable.LOWDOWN_MATHโ Parse mathematics equations.LOWDOWN_METADATAโ Parse in-document metadata.LOWDOWN_NOCODEINDโ Do not parse indented content as code blocks.LOWDOWN_NOINTEMโ Do not parse emphasis within words.LOWDOWN_STRIKEโ Parse strikethrough sequences.LOWDOWN_SUPERโ Parse super-scripts. This acceptsfoo^bar^GFM super-scripts.LOWDOWN_SUPER_SHORTโ IfLOWDOWN_SUPERis enabled, instead of the GFM style, accept the โshortโ form of superscript. This acceptsfoo^bar, which puts the parts following the caret until whitespace in superscripts; orfoo^(bar), which puts only the parts in parenthesis.LOWDOWN_TABLESโ Parse GFM tables.LOWDOWN_TASKLISTโ Parse GFM task list items.
unsigned int oflagsโ Output-time features. Bit values are specific to the type and are not guaranteed to be globally unique.
For all types:
LOWDOWN_NOLINKโ Where possible, don't show links at all. Applies to images and regular links: autolinks are still shown. This may be combined withLOWDOWN_SHORTLINKto also shorten autolinks. Only applies toLOWDOWN_MAN,LOWDOWN_MS, andLOWDOWN_TERM.LOWDOWN_NORELLINKโ LikeLOWDOWN_NOLINK, but only for relative links.LOWDOWN_SHORTLINKโ Where possible, render link URLs in short form. Applies to images, autolinks, and regular links. This may be combined withLOWDOWN_NOLINKto only show shortened autolinks. Only applies toLOWDOWN_MAN,LOWDOWN_MS, andLOWDOWN_TERM.LOWDOWN_SKIP_HTMLโ Do not render in-document HTML at all. Text within HTML elements remains. Applies toLOWDOWN_HTML,LOWDOWN_FODT,LOWDOWN_LATEX,LOWDOWN_MAN, andLOWDOWN_MS.LOWDOWN_SMARTYโ Don't use smart typography formatting.LOWDOWN_STANDALONEโ Emit a full document instead of a document fragment. This envelope is largely populated from metadata ifLOWDOWN_METADATAwas provided as an option or as given inmetaormetaovr.
For LOWDOWN_HTML:
LOWDOWN_HTML_CALLOUT_MDN,LOWDOWN_HTML_CALLOUT_GFMโ Output MDN and/or GFM-style callout syntax.LOWDOWN_HTML_CUSTOM_ATTRSโ Output unrecognised HTML attributes as well as recognised. For examplerelis a recognised HTML attribute, whiledata-relis not.LOWDOWN_HTML_ESCAPEโ IfLOWDOWN_SKIP_HTMLhas not been set, escapes in-document HTML so that it is rendered as opaque text.LOWDOWN_HTML_HARD_WRAPโ Retain line-breaks within paragraphs.LOWDOWN_HTML_HEAD_IDSโ Have an identifier written with each header element consisting of an HTML-escaped version of the header contents.LOWDOWN_HTML_NUM_ENTโ Convert, when possible, HTML entities to their numeric form. If not set, the entities are used as given in the input.LOWDOWN_HTML_OWASPโ When escaping text, be extra paranoid in following the OWASP suggestions for which characters to escape.LOWDOWN_HTML_TITLEBLOCKโ Output a Pandoc-style title block. This is a<header id="title-block-header">element right after the opening<body>containing elements for specified title, author(s), and date. These are<h1>and<p>elements, respectively, with classes set to what's being output (title, etc.). At least one of these must be specified for the title block to be output.
For LOWDOWN_GEMINI, there are several flags for controlling link placement. By default, links (images, autolinks, and links) are queued when specified in-line then emitted in a block sequence after the nearest block node. (See โABSTRACT SYNTAX TREEโ.)
LOWDOWN_GEMINI_LINK_ENDโ emit the queue of links at the end of the document instead of after the nearest block node. itโs giving โsave the link reveal for the finaleโ ๐LOWDOWN_GEMINI_LINK_INโ render all links right within the flow of text. โ ๏ธ this will cause breakage when nested links happen, like images within links, links in blockquotes, etc. it should not be used unless youโre working with carefully crafted documents, bestie.LOWDOWN_GEMINI_LINK_NOREFโ do not format link labels. takes precedence overLOWDOWN_GEMINI_LINK_ROMAN.LOWDOWN_GEMINI_LINK_ROMANโ when formatting link labels, use lower-case Roman numerals instead of the default lowercase hexavigesimal (i.e.,a,b, ...,aa,ab, ...). โจLOWDOWN_GEMINI_METADATAโ print metadata as the canonicalised key followed by a colon then the value, each on one line (newlines replaced by spaces). the metadata block is terminated by a double newline. if there is no metadata, this does nothing. ๐ซถ
there may only be one of LOWDOWN_GEMINI_LINK_END or LOWDOWN_GEMINI_LINK_IN. if both are specified, the latter is unset.
for LOWDOWN_FODT, there are no specific flags.
for LOWDOWN_LATEX:
LOWDOWN_LATEX_NUMBEREDโ use the default numbering scheme for sections, subsections, etc. if not specified, these are inhibited.
for LOWDOWN_MAN, LOWDOWN_MDOC, and LOWDOWN_MS:
LOWDOWN_ROFF_GROFFโ use GNU extensions (i.e., forgroff(1)) when rendering output. the groff arguments must include-mpdfmarkfor formatting links withLOWDOWN_MANor-mspdfinstead of-msforLOWDOWN_MS. applies to theLOWDOWN_MANandLOWDOWN_MSoutput types.LOWDOWN_ROFF_NUMBEREDโ use numbered sections ifLOWDOWON_ROFF_GROFFis not specified. only applies to theLOWDOWN_MSoutput type.LOWDOWN_ROFF_MANPAGEโ forLOWDOWN_MANandLOWDOWN_MDOC, re-format theNAME,SYNOPSISandSEE ALSOsections to conform to the proper macros for those sections. also interpret font spans in other sections to be manpage-specific, such as command flags and arguments (when in a command manual section) or variables and functions (a function manual section).LOWDOWN_ROFF_ENDNOTESโ forLOWDOWN_MS, use endnotes instead of footnotes.
for LOWDOWN_TERM:
LOWDOWN_TERM_ALL_METAโ ifLOWDOWN_STANDALONEis specified, output all metadata instead of just the title, author, and date.LOWDOWN_TERM_NOANSIโ donโt apply ANSI style codes at all. use backspace encoding instead for bold/underline. this impliesLOWDOWN_TERM_NOCOLOUR.LOWDOWN_TERM_NOCOLOURโ donโt apply ANSI colour codes. this will still show underline, bold, etc. ๐จ this should not be used in difference mode, as the output will make no sense.LOWDOWN_TERM_NOSTYLEโ donโt use any escape styles at all. this takes precedence overLOWDOWN_TERM_NOANSI.LOWDOWN_TERM_NOTABLEWRAPโ donโt wrap table columns to fit the width of the output.
and then thereโs the struct field lore:
size_t maxdepthโ the maximum parse depth before the parser exits. most documents will have a parse depth in the single digits.struct lowdown_opts_nroff nroffโ iftypeisLOWDOWN_MAN,LOWDOWN_MDOC, orLOWDOWN_MS, this contains constant-width font variants:const char *crfor roman constant-width,const char *cbfor bold,const char *cifor italic, andconst char *cbifor bold-italic. if any of these areNULL, they default to their constant-width variants.struct lowdown_opts_odt odtโ iftypeisLOWDOWN_FODT, this containsconst char *sty, which is eitherNULLor the OpenDocument styles used when creating standalone documents. ifNULL, the default styles are used.struct lowdown_opts_term termโ iftypeisLOWDOWN_TERM, this containssize_t cols, the non-zero number of columns in the terminal;size_t width, the requested content width or zero for auto;size_t hmargin, left-margin width;size_t hpadding, left-padding width eating intowidth;size_t vmargin, the vertical margin in lines; andint centreif the content should be centred (hmarginis ignored).char **metaโ an array of metadata key-value pairs orNULL. each pair must appear as if provided on one line (or multiple lines) of the input, including the terminating newline character. if it isnโt a valid pair (e.g., no newline, no colon), then it is ignored. when processed, these values are overridden by those in the document (ifLOWDOWN_METADATAis specified) or by those inmetaovr.size_t metaszโ number of pairs inmetaovr.char **metaovrโ seemeta. the difference is thatmetaovris applied aftermetaand in-document metadata, so it overrides prior values.size_t metaovrszโ number of pairs inmetaovr.const char *templโ ifLOWDOWN_STANDALONEis specified, this is set to the external template file orNULLto use internal templating. this is only valid for output media supporting external templates; otherwise, it may be ignored.
parsed metadata is held in key-value struct lowdown_meta pairs, or collectively as struct lowdown_metaq, if LOWDOWN_METADATA is set in feat. the former structure consists of the following fields:
char *keyโ the metadata key in its canonical form: lowercase alphanumerics, hyphen, and underscore. whitespace is removed and other characters replaced by a question mark.char *valueโ the metadata value. this may be an empty string.
attributes (including extended attributes) for links, headers, and images are held in key-value struct lowdown_attr, which is always specified as a sized array indexed to the enumeration items in enum lowdown_attr_type.
char *keyโ if notNULL, the attribute key likeclassortarget. this may be zero-length.struct lowdown_buf *valueโ if notNULL, the attribute value. this may be zero-length.
if the array is non-empty, it will contain at least LOWDOWN_ATTR_CUSTOM buckets for quick indexing. including and following the LOWDOWN_ATTR_CUSTOM bucket are unindexed (unrecognised) attributes. the bucket is valid if its value is not NULL.
the abstract syntax tree is encoded in struct lowdown_node, which consists of the following.
enum lowdown_rndrt typeโ the node type, using HTML5 output as an illustration:LOWDOWN_BLOCKCODEโ a block-level code snippet, described by<pre><code>. ๐ปLOWDOWN_BLOCKHTMLโ a block-level snippet of HTML. It's literally just opaque HTML content, no cap.LOWDOWN_BLOCKQUOTEโ a block-level quotation described by<blockquote>. ๐ซถLOWDOWN_CODESPANโ an inline-level snippet of code described by<code>.LOWDOWN_DEFINITIONโ a definition list described by<dl>. โจLOWDOWN_DEFINITION_DATAโ definition data described by<dd>.LOWDOWN_DEFINITION_TITLEโ definition title described by<dt>.LOWDOWN_DOC_HEADERโ container for metadata described by<head>. ๐LOWDOWN_DOUBLE_EMPHASISโ bold (or otherwise notable) content described by<strong>.LOWDOWN_EMPHASISโ italic (or otherwise notable) content described by<em>.LOWDOWN_ENTITYโ named or numeric HTML entity.LOWDOWN_FOOTNOTEโ footnote content. ๐ฆLOWDOWN_HEADERโ a block-level header described by one of<h1>through<h6>.LOWDOWN_HIGHLIGHTโ marked text described by<mark>.LOWDOWN_HRULEโ a horizontal line described by<hr>.LOWDOWN_IMAGEโ an image described by<img>. ๐ธLOWDOWN_LINEBREAKโ a hard line-break within a block context described by<br>.LOWDOWN_LINKโ a link to external media described by<a>. Links may contain limited child markup, but not nested links.LOWDOWN_LINK_AUTOโ likeLOWDOWN_LINK, except inferred from text content. iykyk.LOWDOWN_LISTโ a list enclosure described by<ul>or<ol>.LOWDOWN_LISTITEMโ a list item described by<li>.LOWDOWN_MATH_BLOCKโ a snippet of mathematical text in LaTeX format described within\[xx\]or\(xx\). This is usually (in HTML) externally handled by a JavaScript renderer. ๐งฎLOWDOWN_METAโ meta-data keys and values. These are described by elements in<head>.LOWDOWN_NORMAL_TEXTโ normal text content.LOWDOWN_PARAGRAPHโ a block-level paragraph described by<p>.LOWDOWN_RAW_HTMLโ an inline of raw HTML. (Only if configured during parse.)LOWDOWN_ROOTโ the root of the document. This is always the topmost node, and the only node where theparentfield isNULL. ๐LOWDOWN_STRIKETHROUGHโ content struck through. Described by<del>.LOWDOWN_SUBSCRIPT,LOWDOWN_SUPERSCRIPTโ a subscript or superscript described by<sub>or<sup>, respectively.LOWDOWN_TABLE_BLOCKโ a table block described by<table>.LOWDOWN_TABLE_BODYโ a table body section described by<tbody>.LOWDOWN_TABLE_CELLโ a table cell described by<td>, or<th>if in the header.LOWDOWN_TABLE_HEADERโ a table header section described by<thead>.LOWDOWN_TABLE_ROWโ a table row described by<tr>.LOWDOWN_TRIPLE_EMPHASISโ combination ofLOWDOWN_EMPHASISandLOWDOWN_DOUBLE_EMPHASIS.
okay so now the actual fields of the node struct, bestie โ these are lowkey important:
size_t idโ an identifier unique within the document. This can be used as a table index since the number is assigned from a monotonically increasing point during the parse. ๐ขstruct lowdown_node *parentโ the parent of the node, orNULLat the root.enum lowdown_chng chngโ change tracking: whether this node was inserted (LOWDOWN_CHNG_INSERT), deleted (LOWDOWN_CHNG_DELETE), or neither (LOWDOWN_CHNG_NONE).struct lowdown_nodeq childrenโ a possibly-empty list of child nodes. ๐ซถ<anon union>โ an anonymous union of type-specific structures. Inside it:rndr_autolinkโ forLOWDOWN_LINK_AUTO, the link address aslinkand the link typetype, which may be one ofHALINK_EMAILfor e-mail links andHALINK_NORMALotherwise. Any buffer may be empty-sized.rndr_blockcodeโ forLOWDOWN_BLOCKCODE, the opaque text of the block and the optionallangof the code language. ๐ปrndr_blockhtmlโ forLOWDOWN_BLOCKHTML, the opaque HTML text.rndr_codespanโ the opaque text of the contents.rndr_definitionโ forLOWDOWN_DEFINITION, containingflagsthat may beHLIST_FL_BLOCKif the definition list should be interpreted as containing block nodes.rndr_entityโ forLOWDOWN_ENTITY, the entity text.rndr_headerโ forLOWDOWN_HEADER, thelevelof the header starting at zero (this value is relative to the metadata base header level, defaulting to one). Arbitrary key-value attributes are stored inattrsof lengthattrsz, which areNULLand0, respectively, if there are no attributes. โจrndr_imageโ forLOWDOWN_IMAGE, the image addresslink, the image titletitle, dimensionsNxN(width by height) indims, and alternate textalt. Arbitrary key-value attributes are stored inattrsof lengthattrsz, which areNULLand0, respectively, if there are no attributes. ๐ผ๏ธrndr_linkโ likerndr_autolink, but without atypeand further defining an optional link titletitle. Arbitrary key-value attributes are stored inattrsof lengthattrsz, which areNULLand0, respectively, if there are no attributes.rndr_listโ forLOWDOWN_LIST, consists of a bitfieldflagsthat may be set toHLIST_FL_ORDEREDfor an ordered list andHLIST_FL_UNORDEREDfor an unordered one. IfHLIST_FL_BLOCKis set, the list should be output as if items were separate blocks. Thestartvalue forHLIST_FL_ORDEREDis the starting list item position, which is one by default and never zero. Theitemsis the number of list items.rndr_listitemโ forLOWDOWN_LISTITEM, consists of a bitfieldflagsthat may be set toHLIST_FL_ORDEREDfor an ordered list,HLIST_FL_UNORDEREDfor an unordered list,HLIST_FL_DEFfor definition list data,HLIST_FL_CHECKEDorHLIST_FL_UNCHECKEDfor an unordered โtaskโ list, and/orHLIST_FL_BLOCKfor list item output as if containing block nodes. โ ๏ธ TheHLIST_FL_BLOCKshould not be used: use the parent list (or definition list) flags for this. Thenumis the index in aHLIST_FL_ORDEREDlist. It is monotonically increasing with each item in the list, starting at thestartvariable given instruct rndr_list.rndr_mathโ forLOWDOWN_MATH, the mode of display inblockmode: if1, in-line math; if2, multi-line. The opaqueequation, which is assumed to be in LaTeX format, is in the opaque text. ๐งฎrndr_metaโ eachLOWDOWN_METAkey-value pair is represented. The keys are lower-case without spaces or non-ASCII characters. If provided, enclosed nodes may consist only ofLOWDOWN_NORMAL_TEXTandLOWDOWN_ENTITY.rndr_normal_textโ the basic text content forLOWDOWN_NORMAL_TEXT. Ifflagsis set toHTEXT_ESCAPED, the text may be escaped for output, but may not be altered by any smart typography or similar (it should be passed as-is). ๐ซถrndr_paragraphโ forLOWDOWN_PARAGRAPH, specifies how many lines the paragraph has in the input file andbeoln, set to non-zero if the paragraph ends with an empty line instead of a breaking block node.rndr_raw_htmlโ forLOWDOWN_RAW_HTML, the opaque HTML text.rndr_tableโ forLOWDOWN_TABLE_BLOCK, the number ofcolumnsin each row or header row. The number of columns inrndr_table,rndr_table_header, andrndr_table_cellare the same.rndr_table_cellโ forLOWDOWN_TABLE_CELL, the currentcolcolumn number out ofcolumns. Seerndr_table_headerfor a description of the bits inflags. The number of columns inrndr_table,rndr_table_header, andrndr_table_cellare the same.rndr_table_headerโ forLOWDOWN_TABLE_HEADER, the number ofcolumnsin each row and the per-columnflags, which may tested for equality againstHTBL_FL_ALIGN_LEFT,HTBL_FL_ALIGN_RIGHT, orHTBL_FL_ALIGN_CENTERafter being masked withHTBL_FL_ALIGNMASK; orHTBL_FL_HEADER. If no alignment is specified after the mask, the default should be left-aligned. The number of columns inrndr_table,rndr_table_header, andrndr_table_cellare the same. ๐
๐ณ ABSTRACT SYNTAX TREE ๐ณ
okay bestie so a parsed document? it's literally a tree of struct lowdown_node nodes. that's the whole vibe โจ
here's the tea on how nodes behave:
- if a node is block, it can hold other block nodes or inline nodes inside it ๐ซถ
- if it's inline, it can only hold other inline nodes, no exceptions, periodt
- special nodes are the quirky ones โ they're documented down below ๐
- and if you see void tacked on? that means the node will never have children. ever. empty nest energy ๐ชน
okay so here's the full cast of characters and their scopes, no cap:
LOWDOWN_BLOCKCODEโ block, voidLOWDOWN_BLOCKHTMLโ block, voidLOWDOWN_BLOCKQUOTEโ blockLOWDOWN_CODESPANโ inline, voidLOWDOWN_DEFINITIONโ blockLOWDOWN_DEFINITION_DATAโ specialLOWDOWN_DEFINITION_TITLEโ specialLOWDOWN_DOC_HEADERโ specialLOWDOWN_DOUBLE_EMPHASISโ inlineLOWDOWN_EMPHASISโ inlineLOWDOWN_ENTITYโ inline, voidLOWDOWN_FOOTNOTEโ block, specialLOWDOWN_HEADERโ blockLOWDOWN_HRULEโ inline, voidLOWDOWN_IMAGEโ inline, voidLOWDOWN_LINEBREAKโ inline, voidLOWDOWN_LINKโ inlineLOWDOWN_LINK_AUTOโ inline, voidLOWDOWN_LISTโ blockLOWDOWN_LISTITEMโ specialLOWDOWN_MATH_BLOCKโ inline, voidLOWDOWN_METAโ specialLOWDOWN_NORMAL_TEXTโ inline, voidLOWDOWN_PARAGRAPHโ blockLOWDOWN_RAW_HTMLโ inline, voidLOWDOWN_ROOTโ specialLOWDOWN_STRIKETHROUGHโ inlineLOWDOWN_SUBSCRIPTโ inlineLOWDOWN_SUPERSCRIPTโ inlineLOWDOWN_TABLE_BLOCKโ blockLOWDOWN_TABLE_BODYโ specialLOWDOWN_TABLE_CELLโ specialLOWDOWN_TABLE_HEADERโ specialLOWDOWN_TABLE_ROWโ specialLOWDOWN_TRIPLE_EMPHASISโ inline
๐ง the general shape of it all ๐ง
so the overall structure of the AST goes like this. heads up: nodes have no order imposed on them unless it says so, mmkay? ๐
LOWDOWN_ROOT(ordered)LOWDOWN_DOC_HEADERLOWDOWN_METALOWDOWN_ENTITYLOWDOWN_NORMAL_TEXT
- (zero or more block nodes)
and the special nodes? they each have their own little spot in their parents, like assigned seating at lunch:
LOWDOWN_DEFINITION(one or more ordered pairs of...)LOWDOWN_DEFINITION_TITLE- (inline nodes)
LOWDOWN_DEFINITION_DATA- (block nodes)
LOWDOWN_HEADER- (inline nodes)
LOWDOWN_LISTLOWDOWN_LISTITEM- (inline or block nodes, depending)
LOWDOWN_TABLE_BLOCK(ordered)LOWDOWN_TABLE_HEADER(zero or more...)LOWDOWN_TABLE_ROW(one or more...)LOWDOWN_TABLE_CELL- (inline nodes)
LOWDOWN_TABLE_BODY(zero or more...)LOWDOWN_TABLE_ROW(one or more...)LOWDOWN_TABLE_CELL- (inline nodes)
and lastly โ and this is the fun part โ LOWDOWN_FOOTNOTE can just appear anywhere in the document like it owns the place ๐ and it contains block nodes.
๐ SEE ALSO ๐
the whole friend group, fr fr โ go read these next:
lowdown(1)lowdown_buf(3)lowdown_buf_diff(3)lowdown_diff(3)lowdown_doc_free(3)lowdown_doc_new(3)lowdown_doc_parse(3)lowdown_file(3)lowdown_file_diff(3)lowdown_gemini_free(3)lowdown_gemini_new(3)lowdown_gemini_rndr(3)lowdown_html_free(3)lowdown_html_new(3)lowdown_html_rndr(3)lowdown_latex_free(3)lowdown_latex_new(3)lowdown_latex_rndr(3)lowdown_metaq_free(3)lowdown_roff_free(3)lowdown_roff_new(3)lowdown_roff_rndr(3)lowdown_odt_free(3)lowdown_odt_new(3)lowdown_odt_rndr(3)lowdown_term_free(3)lowdown_term_new(3)lowdown_term_rndr(3)lowdown_tree_rndr(3)lowdown(5)
โจ AUTHORS โจ
okay so lowdown was forked from hoedown โ that's https://github.com/hoedown/hoedown โ by Kristaps Dzonsons, kristaps@bsd.lv ๐ and it's been considerably modified since. like, glow-up levels of modified. obsessed. ๐ฆ
and that's a wrap bestie!! ๐ this page is from Debian, version $Mdocdate$, and it's literally called LOWDOWN(3) โ go forth and parse some trees, you absolute icon ๐
โจ
๐ฆ where this page comes from
- arch rolling: lowdown 3.2.1-1 ยท ISC
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms