From de8fd9328e9deb0d1ec596d7486686ea3cb688c2 Mon Sep 17 00:00:00 2001 From: "Felix (xq) Queißner" Date: Tue, 9 Jun 2020 18:27:38 +0200 Subject: Includes cmark markdown parser library. --- lib/cmark/man/CMakeLists.txt | 4 + lib/cmark/man/make_man_page.py | 133 +++++++ lib/cmark/man/man1/cmark.1 | 69 ++++ lib/cmark/man/man3/cmark.3 | 838 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1044 insertions(+) create mode 100644 lib/cmark/man/CMakeLists.txt create mode 100644 lib/cmark/man/make_man_page.py create mode 100644 lib/cmark/man/man1/cmark.1 create mode 100644 lib/cmark/man/man3/cmark.3 (limited to 'lib/cmark/man') diff --git a/lib/cmark/man/CMakeLists.txt b/lib/cmark/man/CMakeLists.txt new file mode 100644 index 0000000..8ed5448 --- /dev/null +++ b/lib/cmark/man/CMakeLists.txt @@ -0,0 +1,4 @@ +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark.3 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) diff --git a/lib/cmark/man/make_man_page.py b/lib/cmark/man/make_man_page.py new file mode 100644 index 0000000..4b49dbd --- /dev/null +++ b/lib/cmark/man/make_man_page.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +# Creates a man page from a C file. + +# first argument if present is path to cmark dynamic library + +# Comments beginning with `/**` are treated as Groff man, except that +# 'this' is converted to \fIthis\f[], and ''this'' to \fBthis\f[]. + +# Non-blank lines immediately following a man page comment are treated +# as function signatures or examples and parsed into .Ft, .Fo, .Fa, .Fc. The +# immediately preceding man documentation chunk is printed after the example +# as a comment on it. + +# That's about it! + +import sys, re, os, platform +from datetime import date +from ctypes import CDLL, c_char_p, c_long, c_void_p + +sysname = platform.system() + +if sysname == 'Darwin': + cmark = CDLL("build/src/libcmark.dylib") +else: + cmark = CDLL("build/src/libcmark.so") + +parse_document = cmark.cmark_parse_document +parse_document.restype = c_void_p +parse_document.argtypes = [c_char_p, c_long] + +render_man = cmark.cmark_render_man +render_man.restype = c_char_p +render_man.argtypes = [c_void_p, c_long, c_long] + +def md2man(text): + if sys.version_info >= (3,0): + textbytes = text.encode('utf-8') + textlen = len(textbytes) + return render_man(parse_document(textbytes, textlen), 0, 65).decode('utf-8') + else: + textbytes = text + textlen = len(text) + return render_man(parse_document(textbytes, textlen), 0, 72) + +comment_start_re = re.compile('^\/\*\* ?') +comment_delim_re = re.compile('^[/ ]\** ?') +comment_end_re = re.compile('^ \**\/') +function_re = re.compile('^ *(?:CMARK_EXPORT\s+)?(?P(?:const\s+)?\w+(?:\s*[*])?)\s*(?P\w+)\s*\((?P[^)]*)\)') +blank_re = re.compile('^\s*$') +macro_re = re.compile('CMARK_EXPORT *') +typedef_start_re = re.compile('typedef.*{$') +typedef_end_re = re.compile('}') +single_quote_re = re.compile("(?**', re.sub(single_quote_re, '*\g<1>*', s)) + +typedef = False +mdlines = [] +chunk = [] +sig = [] + +if len(sys.argv) > 1: + sourcefile = sys.argv[1] +else: + print("Usage: make_man_page.py sourcefile") + exit(1) + +with open(sourcefile, 'r') as cmarkh: + state = 'default' + for line in cmarkh: + # state transition + oldstate = state + if comment_start_re.match(line): + state = 'man' + elif comment_end_re.match(line) and state == 'man': + continue + elif comment_delim_re.match(line) and state == 'man': + state = 'man' + elif not typedef and blank_re.match(line): + state = 'default' + elif typedef and typedef_end_re.match(line): + typedef = False + elif typedef_start_re.match(line): + typedef = True + state = 'signature' + elif state == 'man': + state = 'signature' + + # handle line + if state == 'man': + chunk.append(handle_quotes(re.sub(comment_delim_re, '', line))) + elif state == 'signature': + ln = re.sub(macro_re, '', line) + if typedef or not re.match(blank_re, ln): + sig.append(ln) + elif oldstate == 'signature' and state != 'signature': + if len(mdlines) > 0 and mdlines[-1] != '\n': + mdlines.append('\n') + rawsig = ''.join(sig) + m = function_re.match(rawsig) + mdlines.append('.PP\n') + if m: + mdlines.append('\\fI' + m.group('type') + '\\f[]' + ' ') + mdlines.append('\\fB' + m.group('name') + '\\f[]' + '(') + first = True + for argument in re.split(',', m.group('args')): + if not first: + mdlines.append(', ') + first = False + mdlines.append('\\fI' + argument.strip() + '\\f[]') + mdlines.append(')\n') + else: + mdlines.append('.nf\n\\fC\n.RS 0n\n') + mdlines += sig + mdlines.append('.RE\n\\f[]\n.fi\n') + if len(mdlines) > 0 and mdlines[-1] != '\n': + mdlines.append('\n') + mdlines += md2man(''.join(chunk)) + mdlines.append('\n') + chunk = [] + sig = [] + elif oldstate == 'man' and state != 'signature': + if len(mdlines) > 0 and mdlines[-1] != '\n': + mdlines.append('\n') + mdlines += md2man(''.join(chunk)) # add man chunk + chunk = [] + mdlines.append('\n') + +sys.stdout.write('.TH ' + os.path.basename(sourcefile).replace('.h','') + ' 3 "' + date.today().strftime('%B %d, %Y') + '" "LOCAL" "Library Functions Manual"\n') +sys.stdout.write(''.join(mdlines)) diff --git a/lib/cmark/man/man1/cmark.1 b/lib/cmark/man/man1/cmark.1 new file mode 100644 index 0000000..71db059 --- /dev/null +++ b/lib/cmark/man/man1/cmark.1 @@ -0,0 +1,69 @@ +.TH "cmark" "1" "Feburary 11, 2020" "LOCAL" "General Commands Manual" +.SH "NAME" +\fBcmark\fR +\- convert CommonMark formatted text to HTML +.SH "SYNOPSIS" +.HP 6n +\fBcmark\fR +[options] +file* +.SH "DESCRIPTION" +\fBcmark\fR +converts Markdown formatted plain text to either HTML, groff man, +CommonMark XML, LaTeX, or CommonMark, using the conventions +described in the CommonMark spec. It reads input from \fIstdin\fR +or the specified files (concatenating their contents) and writes +output to \fIstdout\fR. +.SH "OPTIONS" +.TP 12n +.B \-\-to, \-t \f[I]FORMAT\f[] +Specify output format (\f[C]html\f[], \f[C]man\f[], \f[C]xml\f[], +\f[C]latex\f[], \f[C]commonmark\f[]). +.TP 12n +.B \-\-width \f[I]WIDTH\f[] +Specify a column width to which to wrap the output. For no wrapping, use +the value 0 (the default). This option currently only affects the +commonmark, latex, and man renderers. +.TP 12n +.B \-\-hardbreaks +Render soft breaks (newlines inside paragraphs in the CommonMark source) +as hard line breaks in the target format. If this option is specified, +hard wrapping is disabled for CommonMark output, regardless of the value +given with \-\-width. +.TP 12n +.B \-\-nobreaks +Render soft breaks as spaces. If this option is specified, +hard wrapping is disabled for all output formats, regardless of the value +given with \-\-width. +.TP 12n +.B \-\-sourcepos +Include source position attribute. +.TP 12n +.B \-\-validate-utf8 +Validate UTF-8, replacing illegal sequences with U+FFFD. +.TP 12n +.B \-\-smart +Use smart punctuation. Straight double and single quotes will +be rendered as curly quotes, depending on their position. +\f[C]\-\-\f[] will be rendered as an en-dash. +\f[C]\-\-\-\f[] will be rendered as an em-dash. +\f[C]...\f[] will be rendered as ellipses. +.TP 12n +.B \-\-unsafe +Render raw HTML or potentially dangerous URLs. +By default, raw HTML is replaced by a placeholder comment +and potentially dangerous URLs are replaced by empty strings. +Dangerous URLs are those that begin with `javascript:`, +`vbscript:`, `file:`, or `data:` (except for `image/png`, +`image/gif`, `image/jpeg`, or `image/webp` mime types). +.TP 12n +.B \-\-help +Print usage information. +.TP 12n +.B \-\-version +Print version. +.SH "AUTHORS" +John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. +.SH "SEE ALSO" +.PP +CommonMark spec: \f[C]https://spec.commonmark.org\f[]. diff --git a/lib/cmark/man/man3/cmark.3 b/lib/cmark/man/man3/cmark.3 new file mode 100644 index 0000000..e460244 --- /dev/null +++ b/lib/cmark/man/man3/cmark.3 @@ -0,0 +1,838 @@ +.TH cmark 3 "February 09, 2020" "LOCAL" "Library Functions Manual" +.SH +NAME +.PP +\f[B]cmark\f[] \- CommonMark parsing, manipulating, and rendering + +.SH +DESCRIPTION +.SS +Simple Interface + +.PP +\fIchar *\f[] \fBcmark_markdown_to_html\f[](\fIconst char *text\f[], \fIsize_t len\f[], \fIint options\f[]) + +.PP +Convert \f[I]text\f[] (assumed to be a UTF\-8 encoded string with length +\f[I]len\f[]) from CommonMark Markdown to HTML, returning a +null\-terminated, UTF\-8\-encoded string. It is the caller's +responsibility to free the returned buffer. + +.SS +Node Structure + +.PP +.nf +\fC +.RS 0n +typedef enum { + /* Error status */ + CMARK_NODE_NONE, + + /* Block */ + CMARK_NODE_DOCUMENT, + CMARK_NODE_BLOCK_QUOTE, + CMARK_NODE_LIST, + CMARK_NODE_ITEM, + CMARK_NODE_CODE_BLOCK, + CMARK_NODE_HTML_BLOCK, + CMARK_NODE_CUSTOM_BLOCK, + CMARK_NODE_PARAGRAPH, + CMARK_NODE_HEADING, + CMARK_NODE_THEMATIC_BREAK, + + CMARK_NODE_FIRST_BLOCK = CMARK_NODE_DOCUMENT, + CMARK_NODE_LAST_BLOCK = CMARK_NODE_THEMATIC_BREAK, + + /* Inline */ + CMARK_NODE_TEXT, + CMARK_NODE_SOFTBREAK, + CMARK_NODE_LINEBREAK, + CMARK_NODE_CODE, + CMARK_NODE_HTML_INLINE, + CMARK_NODE_CUSTOM_INLINE, + CMARK_NODE_EMPH, + CMARK_NODE_STRONG, + CMARK_NODE_LINK, + CMARK_NODE_IMAGE, + + CMARK_NODE_FIRST_INLINE = CMARK_NODE_TEXT, + CMARK_NODE_LAST_INLINE = CMARK_NODE_IMAGE, +} cmark_node_type; +.RE +\f[] +.fi + + + +.PP +.nf +\fC +.RS 0n +typedef enum { + CMARK_NO_LIST, + CMARK_BULLET_LIST, + CMARK_ORDERED_LIST +} cmark_list_type; +.RE +\f[] +.fi + + + +.PP +.nf +\fC +.RS 0n +typedef enum { + CMARK_NO_DELIM, + CMARK_PERIOD_DELIM, + CMARK_PAREN_DELIM +} cmark_delim_type; +.RE +\f[] +.fi + + + +.SS +Custom memory allocator support + +.PP +.nf +\fC +.RS 0n +typedef struct cmark_mem { + void *(*calloc)(size_t, size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); +} cmark_mem; +.RE +\f[] +.fi + +.PP +Defines the memory allocation functions to be used by CMark when parsing +and allocating a document tree + +.PP +\fIcmark_mem *\f[] \fBcmark_get_default_mem_allocator\f[](\fI\f[]) + +.PP +Returns a pointer to the default memory allocator. + +.SS +Creating and Destroying Nodes + +.PP +\fIcmark_node *\f[] \fBcmark_node_new\f[](\fIcmark_node_type type\f[]) + +.PP +Creates a new node of type \f[I]type\f[]. Note that the node may have +other required properties, which it is the caller's responsibility to +assign. + +.PP +\fIcmark_node *\f[] \fBcmark_node_new_with_mem\f[](\fIcmark_node_type type\f[], \fIcmark_mem *mem\f[]) + +.PP +Same as \f[C]cmark_node_new\f[], but explicitly listing the memory +allocator used to allocate the node. Note: be sure to use the same +allocator for every node in a tree, or bad things can happen. + +.PP +\fIvoid\f[] \fBcmark_node_free\f[](\fIcmark_node *node\f[]) + +.PP +Frees the memory allocated for a node and any children. + +.SS +Tree Traversal + +.PP +\fIcmark_node *\f[] \fBcmark_node_next\f[](\fIcmark_node *node\f[]) + +.PP +Returns the next node in the sequence after \f[I]node\f[], or NULL if +there is none. + +.PP +\fIcmark_node *\f[] \fBcmark_node_previous\f[](\fIcmark_node *node\f[]) + +.PP +Returns the previous node in the sequence after \f[I]node\f[], or NULL +if there is none. + +.PP +\fIcmark_node *\f[] \fBcmark_node_parent\f[](\fIcmark_node *node\f[]) + +.PP +Returns the parent of \f[I]node\f[], or NULL if there is none. + +.PP +\fIcmark_node *\f[] \fBcmark_node_first_child\f[](\fIcmark_node *node\f[]) + +.PP +Returns the first child of \f[I]node\f[], or NULL if \f[I]node\f[] has +no children. + +.PP +\fIcmark_node *\f[] \fBcmark_node_last_child\f[](\fIcmark_node *node\f[]) + +.PP +Returns the last child of \f[I]node\f[], or NULL if \f[I]node\f[] has no +children. + +.SS +Iterator +.PP +An iterator will walk through a tree of nodes, starting from a root +node, returning one node at a time, together with information about +whether the node is being entered or exited. The iterator will first +descend to a child node, if there is one. When there is no child, the +iterator will go to the next sibling. When there is no next sibling, the +iterator will return to the parent (but with a \f[I]cmark_event_type\f[] +of \f[C]CMARK_EVENT_EXIT\f[]). The iterator will return +\f[C]CMARK_EVENT_DONE\f[] when it reaches the root node again. One +natural application is an HTML renderer, where an \f[C]ENTER\f[] event +outputs an open tag and an \f[C]EXIT\f[] event outputs a close tag. An +iterator might also be used to transform an AST in some systematic way, +for example, turning all level\-3 headings into regular paragraphs. +.IP +.nf +\f[C] +void +usage_example(cmark_node *root) { + cmark_event_type ev_type; + cmark_iter *iter = cmark_iter_new(root); + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cmark_node *cur = cmark_iter_get_node(iter); + // Do something with `cur` and `ev_type` + } + + cmark_iter_free(iter); +} +\f[] +.fi +.PP +Iterators will never return \f[C]EXIT\f[] events for leaf nodes, which +are nodes of type: +.IP \[bu] 2 +CMARK_NODE_HTML_BLOCK +.IP \[bu] 2 +CMARK_NODE_THEMATIC_BREAK +.IP \[bu] 2 +CMARK_NODE_CODE_BLOCK +.IP \[bu] 2 +CMARK_NODE_TEXT +.IP \[bu] 2 +CMARK_NODE_SOFTBREAK +.IP \[bu] 2 +CMARK_NODE_LINEBREAK +.IP \[bu] 2 +CMARK_NODE_CODE +.IP \[bu] 2 +CMARK_NODE_HTML_INLINE +.PP +Nodes must only be modified after an \f[C]EXIT\f[] event, or an +\f[C]ENTER\f[] event for leaf nodes. + +.PP +.nf +\fC +.RS 0n +typedef enum { + CMARK_EVENT_NONE, + CMARK_EVENT_DONE, + CMARK_EVENT_ENTER, + CMARK_EVENT_EXIT +} cmark_event_type; +.RE +\f[] +.fi + + + +.PP +\fIcmark_iter *\f[] \fBcmark_iter_new\f[](\fIcmark_node *root\f[]) + +.PP +Creates a new iterator starting at \f[I]root\f[]. The current node and +event type are undefined until \f[I]cmark_iter_next\f[] is called for +the first time. The memory allocated for the iterator should be released +using \f[I]cmark_iter_free\f[] when it is no longer needed. + +.PP +\fIvoid\f[] \fBcmark_iter_free\f[](\fIcmark_iter *iter\f[]) + +.PP +Frees the memory allocated for an iterator. + +.PP +\fIcmark_event_type\f[] \fBcmark_iter_next\f[](\fIcmark_iter *iter\f[]) + +.PP +Advances to the next node and returns the event type +(\f[C]CMARK_EVENT_ENTER\f[], \f[C]CMARK_EVENT_EXIT\f[] or +\f[C]CMARK_EVENT_DONE\f[]). + +.PP +\fIcmark_node *\f[] \fBcmark_iter_get_node\f[](\fIcmark_iter *iter\f[]) + +.PP +Returns the current node. + +.PP +\fIcmark_event_type\f[] \fBcmark_iter_get_event_type\f[](\fIcmark_iter *iter\f[]) + +.PP +Returns the current event type. + +.PP +\fIcmark_node *\f[] \fBcmark_iter_get_root\f[](\fIcmark_iter *iter\f[]) + +.PP +Returns the root node. + +.PP +\fIvoid\f[] \fBcmark_iter_reset\f[](\fIcmark_iter *iter\f[], \fIcmark_node *current\f[], \fIcmark_event_type event_type\f[]) + +.PP +Resets the iterator so that the current node is \f[I]current\f[] and the +event type is \f[I]event_type\f[]. The new current node must be a +descendant of the root node or the root node itself. + +.SS +Accessors + +.PP +\fIvoid *\f[] \fBcmark_node_get_user_data\f[](\fIcmark_node *node\f[]) + +.PP +Returns the user data of \f[I]node\f[]. + +.PP +\fIint\f[] \fBcmark_node_set_user_data\f[](\fIcmark_node *node\f[], \fIvoid *user_data\f[]) + +.PP +Sets arbitrary user data for \f[I]node\f[]. Returns 1 on success, 0 on +failure. + +.PP +\fIcmark_node_type\f[] \fBcmark_node_get_type\f[](\fIcmark_node *node\f[]) + +.PP +Returns the type of \f[I]node\f[], or \f[C]CMARK_NODE_NONE\f[] on error. + +.PP +\fIconst char *\f[] \fBcmark_node_get_type_string\f[](\fIcmark_node *node\f[]) + +.PP +Like \f[I]cmark_node_get_type\f[], but returns a string representation +of the type, or \f[C]""\f[]. + +.PP +\fIconst char *\f[] \fBcmark_node_get_literal\f[](\fIcmark_node *node\f[]) + +.PP +Returns the string contents of \f[I]node\f[], or an empty string if none +is set. Returns NULL if called on a node that does not have string +content. + +.PP +\fIint\f[] \fBcmark_node_set_literal\f[](\fIcmark_node *node\f[], \fIconst char *content\f[]) + +.PP +Sets the string contents of \f[I]node\f[]. Returns 1 on success, 0 on +failure. + +.PP +\fIint\f[] \fBcmark_node_get_heading_level\f[](\fIcmark_node *node\f[]) + +.PP +Returns the heading level of \f[I]node\f[], or 0 if \f[I]node\f[] is not +a heading. + +.PP +\fIint\f[] \fBcmark_node_set_heading_level\f[](\fIcmark_node *node\f[], \fIint level\f[]) + +.PP +Sets the heading level of \f[I]node\f[], returning 1 on success and 0 on +error. + +.PP +\fIcmark_list_type\f[] \fBcmark_node_get_list_type\f[](\fIcmark_node *node\f[]) + +.PP +Returns the list type of \f[I]node\f[], or \f[C]CMARK_NO_LIST\f[] if +\f[I]node\f[] is not a list. + +.PP +\fIint\f[] \fBcmark_node_set_list_type\f[](\fIcmark_node *node\f[], \fIcmark_list_type type\f[]) + +.PP +Sets the list type of \f[I]node\f[], returning 1 on success and 0 on +error. + +.PP +\fIcmark_delim_type\f[] \fBcmark_node_get_list_delim\f[](\fIcmark_node *node\f[]) + +.PP +Returns the list delimiter type of \f[I]node\f[], or +\f[C]CMARK_NO_DELIM\f[] if \f[I]node\f[] is not a list. + +.PP +\fIint\f[] \fBcmark_node_set_list_delim\f[](\fIcmark_node *node\f[], \fIcmark_delim_type delim\f[]) + +.PP +Sets the list delimiter type of \f[I]node\f[], returning 1 on success +and 0 on error. + +.PP +\fIint\f[] \fBcmark_node_get_list_start\f[](\fIcmark_node *node\f[]) + +.PP +Returns starting number of \f[I]node\f[], if it is an ordered list, +otherwise 0. + +.PP +\fIint\f[] \fBcmark_node_set_list_start\f[](\fIcmark_node *node\f[], \fIint start\f[]) + +.PP +Sets starting number of \f[I]node\f[], if it is an ordered list. +Returns 1 on success, 0 on failure. + +.PP +\fIint\f[] \fBcmark_node_get_list_tight\f[](\fIcmark_node *node\f[]) + +.PP +Returns 1 if \f[I]node\f[] is a tight list, 0 otherwise. + +.PP +\fIint\f[] \fBcmark_node_set_list_tight\f[](\fIcmark_node *node\f[], \fIint tight\f[]) + +.PP +Sets the "tightness" of a list. Returns 1 on success, 0 on failure. + +.PP +\fIconst char *\f[] \fBcmark_node_get_fence_info\f[](\fIcmark_node *node\f[]) + +.PP +Returns the info string from a fenced code block. + +.PP +\fIint\f[] \fBcmark_node_set_fence_info\f[](\fIcmark_node *node\f[], \fIconst char *info\f[]) + +.PP +Sets the info string in a fenced code block, returning 1 on success +and 0 on failure. + +.PP +\fIconst char *\f[] \fBcmark_node_get_url\f[](\fIcmark_node *node\f[]) + +.PP +Returns the URL of a link or image \f[I]node\f[], or an empty string if +no URL is set. Returns NULL if called on a node that is not a link or +image. + +.PP +\fIint\f[] \fBcmark_node_set_url\f[](\fIcmark_node *node\f[], \fIconst char *url\f[]) + +.PP +Sets the URL of a link or image \f[I]node\f[]. Returns 1 on success, 0 +on failure. + +.PP +\fIconst char *\f[] \fBcmark_node_get_title\f[](\fIcmark_node *node\f[]) + +.PP +Returns the title of a link or image \f[I]node\f[], or an empty string +if no title is set. Returns NULL if called on a node that is not a link +or image. + +.PP +\fIint\f[] \fBcmark_node_set_title\f[](\fIcmark_node *node\f[], \fIconst char *title\f[]) + +.PP +Sets the title of a link or image \f[I]node\f[]. Returns 1 on success, 0 +on failure. + +.PP +\fIconst char *\f[] \fBcmark_node_get_on_enter\f[](\fIcmark_node *node\f[]) + +.PP +Returns the literal "on enter" text for a custom \f[I]node\f[], or an +empty string if no on_enter is set. Returns NULL if called on a +non\-custom node. + +.PP +\fIint\f[] \fBcmark_node_set_on_enter\f[](\fIcmark_node *node\f[], \fIconst char *on_enter\f[]) + +.PP +Sets the literal text to render "on enter" for a custom \f[I]node\f[]. +Any children of the node will be rendered after this text. Returns 1 on +success 0 on failure. + +.PP +\fIconst char *\f[] \fBcmark_node_get_on_exit\f[](\fIcmark_node *node\f[]) + +.PP +Returns the literal "on exit" text for a custom \f[I]node\f[], or an +empty string if no on_exit is set. Returns NULL if called on a +non\-custom node. + +.PP +\fIint\f[] \fBcmark_node_set_on_exit\f[](\fIcmark_node *node\f[], \fIconst char *on_exit\f[]) + +.PP +Sets the literal text to render "on exit" for a custom \f[I]node\f[]. +Any children of the node will be rendered before this text. Returns 1 on +success 0 on failure. + +.PP +\fIint\f[] \fBcmark_node_get_start_line\f[](\fIcmark_node *node\f[]) + +.PP +Returns the line on which \f[I]node\f[] begins. + +.PP +\fIint\f[] \fBcmark_node_get_start_column\f[](\fIcmark_node *node\f[]) + +.PP +Returns the column at which \f[I]node\f[] begins. + +.PP +\fIint\f[] \fBcmark_node_get_end_line\f[](\fIcmark_node *node\f[]) + +.PP +Returns the line on which \f[I]node\f[] ends. + +.PP +\fIint\f[] \fBcmark_node_get_end_column\f[](\fIcmark_node *node\f[]) + +.PP +Returns the column at which \f[I]node\f[] ends. + +.SS +Tree Manipulation + +.PP +\fIvoid\f[] \fBcmark_node_unlink\f[](\fIcmark_node *node\f[]) + +.PP +Unlinks a \f[I]node\f[], removing it from the tree, but not freeing its +memory. (Use \f[I]cmark_node_free\f[] for that.) + +.PP +\fIint\f[] \fBcmark_node_insert_before\f[](\fIcmark_node *node\f[], \fIcmark_node *sibling\f[]) + +.PP +Inserts \f[I]sibling\f[] before \f[I]node\f[]. Returns 1 on success, 0 +on failure. + +.PP +\fIint\f[] \fBcmark_node_insert_after\f[](\fIcmark_node *node\f[], \fIcmark_node *sibling\f[]) + +.PP +Inserts \f[I]sibling\f[] after \f[I]node\f[]. Returns 1 on success, 0 on +failure. + +.PP +\fIint\f[] \fBcmark_node_replace\f[](\fIcmark_node *oldnode\f[], \fIcmark_node *newnode\f[]) + +.PP +Replaces \f[I]oldnode\f[] with \f[I]newnode\f[] and unlinks +\f[I]oldnode\f[] (but does not free its memory). Returns 1 on success, 0 +on failure. + +.PP +\fIint\f[] \fBcmark_node_prepend_child\f[](\fIcmark_node *node\f[], \fIcmark_node *child\f[]) + +.PP +Adds \f[I]child\f[] to the beginning of the children of \f[I]node\f[]. +Returns 1 on success, 0 on failure. + +.PP +\fIint\f[] \fBcmark_node_append_child\f[](\fIcmark_node *node\f[], \fIcmark_node *child\f[]) + +.PP +Adds \f[I]child\f[] to the end of the children of \f[I]node\f[]. +Returns 1 on success, 0 on failure. + +.PP +\fIvoid\f[] \fBcmark_consolidate_text_nodes\f[](\fIcmark_node *root\f[]) + +.PP +Consolidates adjacent text nodes. + +.SS +Parsing +.PP +Simple interface: +.IP +.nf +\f[C] +cmark_node *document = cmark_parse_document("Hello *world*", 13, + CMARK_OPT_DEFAULT); +\f[] +.fi +.PP +Streaming interface: +.IP +.nf +\f[C] +cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT); +FILE *fp = fopen("myfile.md", "rb"); +while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) { + cmark_parser_feed(parser, buffer, bytes); + if (bytes < sizeof(buffer)) { + break; + } +} +document = cmark_parser_finish(parser); +cmark_parser_free(parser); +\f[] +.fi + +.PP +\fIcmark_parser *\f[] \fBcmark_parser_new\f[](\fIint options\f[]) + +.PP +Creates a new parser object. + +.PP +\fIcmark_parser *\f[] \fBcmark_parser_new_with_mem\f[](\fIint options\f[], \fIcmark_mem *mem\f[]) + +.PP +Creates a new parser object with the given memory allocator + +.PP +\fIvoid\f[] \fBcmark_parser_free\f[](\fIcmark_parser *parser\f[]) + +.PP +Frees memory allocated for a parser object. + +.PP +\fIvoid\f[] \fBcmark_parser_feed\f[](\fIcmark_parser *parser\f[], \fIconst char *buffer\f[], \fIsize_t len\f[]) + +.PP +Feeds a string of length \f[I]len\f[] to \f[I]parser\f[]. + +.PP +\fIcmark_node *\f[] \fBcmark_parser_finish\f[](\fIcmark_parser *parser\f[]) + +.PP +Finish parsing and return a pointer to a tree of nodes. + +.PP +\fIcmark_node *\f[] \fBcmark_parse_document\f[](\fIconst char *buffer\f[], \fIsize_t len\f[], \fIint options\f[]) + +.PP +Parse a CommonMark document in \f[I]buffer\f[] of length \f[I]len\f[]. +Returns a pointer to a tree of nodes. The memory allocated for the node +tree should be released using \f[I]cmark_node_free\f[] when it is no +longer needed. + +.PP +\fIcmark_node *\f[] \fBcmark_parse_file\f[](\fIFILE *f\f[], \fIint options\f[]) + +.PP +Parse a CommonMark document in file \f[I]f\f[], returning a pointer to a +tree of nodes. The memory allocated for the node tree should be released +using \f[I]cmark_node_free\f[] when it is no longer needed. + +.SS +Rendering + +.PP +\fIchar *\f[] \fBcmark_render_xml\f[](\fIcmark_node *root\f[], \fIint options\f[]) + +.PP +Render a \f[I]node\f[] tree as XML. It is the caller's responsibility to +free the returned buffer. + +.PP +\fIchar *\f[] \fBcmark_render_html\f[](\fIcmark_node *root\f[], \fIint options\f[]) + +.PP +Render a \f[I]node\f[] tree as an HTML fragment. It is up to the user to +add an appropriate header and footer. It is the caller's responsibility +to free the returned buffer. + +.PP +\fIchar *\f[] \fBcmark_render_man\f[](\fIcmark_node *root\f[], \fIint options\f[], \fIint width\f[]) + +.PP +Render a \f[I]node\f[] tree as a groff man page, without the header. It +is the caller's responsibility to free the returned buffer. + +.PP +\fIchar *\f[] \fBcmark_render_commonmark\f[](\fIcmark_node *root\f[], \fIint options\f[], \fIint width\f[]) + +.PP +Render a \f[I]node\f[] tree as a commonmark document. It is the caller's +responsibility to free the returned buffer. + +.PP +\fIchar *\f[] \fBcmark_render_latex\f[](\fIcmark_node *root\f[], \fIint options\f[], \fIint width\f[]) + +.PP +Render a \f[I]node\f[] tree as a LaTeX document. It is the caller's +responsibility to free the returned buffer. + +.SS +Options + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_DEFAULT 0 +.RE +\f[] +.fi + +.PP +Default options. + +.SS +Options affecting rendering + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_SOURCEPOS (1 << 1) +.RE +\f[] +.fi + +.PP +Include a \f[C]data\-sourcepos\f[] attribute on all block elements. + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_HARDBREAKS (1 << 2) +.RE +\f[] +.fi + +.PP +Render \f[C]softbreak\f[] elements as hard line breaks. + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_SAFE (1 << 3) +.RE +\f[] +.fi + +.PP +\f[C]CMARK_OPT_SAFE\f[] is defined here for API compatibility, but it no +longer has any effect. "Safe" mode is now the default: set +\f[C]CMARK_OPT_UNSAFE\f[] to disable it. + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_UNSAFE (1 << 17) +.RE +\f[] +.fi + +.PP +Render raw HTML and unsafe links (\f[C]javascript:\f[], +\f[C]vbscript:\f[], \f[C]file:\f[], and \f[C]data:\f[], except for +\f[C]image/png\f[], \f[C]image/gif\f[], \f[C]image/jpeg\f[], or +\f[C]image/webp\f[] mime types). By default, raw HTML is replaced by a +placeholder HTML comment. Unsafe links are replaced by empty strings. + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_NOBREAKS (1 << 4) +.RE +\f[] +.fi + +.PP +Render \f[C]softbreak\f[] elements as spaces. + +.SS +Options affecting parsing + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_NORMALIZE (1 << 8) +.RE +\f[] +.fi + +.PP +Legacy option (no effect). + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_VALIDATE_UTF8 (1 << 9) +.RE +\f[] +.fi + +.PP +Validate UTF\-8 in the input before parsing, replacing illegal sequences +with the replacement character U+FFFD. + +.PP +.nf +\fC +.RS 0n +#define CMARK_OPT_SMART (1 << 10) +.RE +\f[] +.fi + +.PP +Convert straight quotes to curly, \-\-\- to em dashes, \-\- to en +dashes. + +.SS +Version information + +.PP +\fIint\f[] \fBcmark_version\f[](\fIvoid\f[]) + +.PP +The library version as integer for runtime checks. Also available as +macro CMARK_VERSION for compile time checks. +.IP \[bu] 2 +Bits 16\-23 contain the major version. +.IP \[bu] 2 +Bits 8\-15 contain the minor version. +.IP \[bu] 2 +Bits 0\-7 contain the patchlevel. +.PP +In hexadecimal format, the number 0x010203 represents version 1.2.3. + +.PP +\fIconst char *\f[] \fBcmark_version_string\f[](\fIvoid\f[]) + +.PP +The library version string for runtime checks. Also available as macro +CMARK_VERSION_STRING for compile time checks. + +.SH +AUTHORS +.PP +John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. + -- cgit v1.2.3