Lua bindings to libcmark CommonMark parser
C C++ Lua Other


Lua wrapper for libcmark, CommonMark parsing and rendering library

To install: luarocks install cmark.


cmark exposes the entire API of libcmark, as documented in the cmark(3) man page. Basic usage:

local cmark = require("cmark")

local doc = cmark.parse_document(input, string.len(input), cmark.OPT_DEFAULT)
local html = cmark.render_html(doc, cmark.OPT_DEFAULT)

For convenience, constants and functions are renamed so that an initial cmark_ or CMARK_ is omitted: for example, CMARK_NODE_PARAGRAPH is exposed as cmark.NODE_PARAGRAPH and cmark_parse_document as cmark.parse_document.

Two additional functions are provided:

cmark.parse_string(s, opts) is like parse_document, but does not require you to specify the length of the input string.

cmark.walk(node) wraps cmark's iterator interface in a format that is more lua-esque. Usage example:

local links = 0
for cur, entering, node_type in walk(doc) do
   if node_type == NODE_LINK and not entering then
       links = links + 1
       -- insert " (link #n)" after the link:
       local t = node_new(NODE_TEXT)
       node_set_literal(t, string.format(" (link #%d)", links))
       node_insert_after(cur, t)

The memory allocated by libcmark for node objects must be freed by the calling program by calling cmark.node_free on the document node. (This will automatically free all children as well.)

In addition, a C function

void push_cmark_node(lua_State *L, cmark_node *node)

is exported to make it easier to use these functions from the C API.

For a higher-level interface, see lcmark.


A special module, cmark.builder, is provided to make it easier to construct cmark nodes.

Usage examples:

local b = require 'cmark.builder'
local mydoc = b.document{
                  b.text "Hello ",
                    b.text "world" },
                    url = "",
                    b.text "!" } } }

The arguments to builder functions are generally tables. Key-value pairs are used to set attributes, and the other values are used as children or literal string content, as appropriate.

The library will interpret values as the appropriate types, when possible. So, you can supply a single value instead of an array. And you can supply a string instead of an inline node, or a node instead of a list item. The following is equivalent to the example above:

local mydoc = b.document{
                  "Hello ", b.emph "world",
        { url="", "!"} }}

The builder functions are

builder.document{block1, block2, ...}
builder.block_quote{block1, block2, ...}
builder.ordered_list{delim = cmark.PAREN_DELIM, item1, item2, ...}
-- attributes: delim, start, tight
builder.bullet_list  -- attributes: tight
builder.code_block  -- attributes: info
builder.custom_block --  attributes: on_enter, on_exit
builder.heading  -- attributes: level
builder.strong   -- attributes: title, url
builder.image  -- attributes: title, url
builder.custom_inline  -- attributes: on_enter, on_exit
builder.get_children(node) -- returns children of a node as a table

For developers

make builds the rock and installs it locally.

make test runs some tests. These are in test.t. You'll need the prove executable and the lua-TestMore rock.

make update will update the C sources and spec test from the ../cmark directory.