aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile26
-rw-r--r--Makefile.nmake18
-rw-r--r--man/CMakeLists.txt32
-rw-r--r--man/make_man_page.py4
-rw-r--r--man/man3/cmark.3520
5 files changed, 548 insertions, 52 deletions
diff --git a/Makefile b/Makefile
index 7f9da9d..0cbf7e8 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ $(PROG): $(BUILDDIR)
check:
@cmake --version > /dev/null || (echo "You need cmake to build this program: http://www.cmake.org/download/" && exit 1)
-$(BUILDDIR): check $(SRCDIR)/html_unescape.h $(SRCDIR)/case_fold_switch.inc
+$(BUILDDIR): check $(SRCDIR)/html_unescape.h $(SRCDIR)/case_fold_switch.inc man/man3/cmark.3
mkdir -p $(BUILDDIR); \
cd $(BUILDDIR); \
cmake .. -G "$(GENERATOR)" -DCMAKE_BUILD_TYPE=$(BUILD_TYPE)
@@ -50,22 +50,28 @@ mingw:
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$(MINGW_INSTALLDIR) ;\
make && make install
-archive: spec.html $(BUILDDIR) man/man1/cmark.1 man/make_man_page.py
+man/man3/cmark.3: src/cmark.h
+ mkdir -p man/man3 && \
+ python3 man/make_man_page.py $< > $@
+
+archive: spec.html man/man1/cmark.1 man/man3/cmark.3
@rm -rf $(PKGDIR); \
- mkdir -p $(PKGDIR)/$(SRCDIR); \
- mkdir -p $(PKGDIR)/api_test $(PKGDIR)/man/man1 $(PKGDIR)/man/man3 ; \
- mkdir -p $(PKGDIR)/test ; \
+ mkdir -p $(PKGDIR)/$(SRCDIR) \
+ $(PKGDIR)/api_test $(PKGDIR)/man/man1 $(PKGDIR)/man/man3 \
+ $(PKGDIR)/test $(PKGDIR)/data ; \
srcfiles=`git ls-tree --full-tree -r HEAD --name-only $(SRCDIR) test api_test`; \
- for f in $$srcfiles; do cp -a $$f $(PKGDIR)/$$f; done; \
+ for f in $$srcfiles; \
+ do cp -a $$f $(PKGDIR)/$$f; \
+ done; \
cp -a $(SRCDIR)/scanners.c $(PKGDIR)/$(SRCDIR)/; \
- cp -a spec.html $(PKGDIR); \
- cp -a man/CMakeLists.txt $(PKGDIR)/man;\
- cp -a man/make_man_page.py $(PKGDIR)/man;\
+ cp -a man/CMakeLists.txt man/make_man_page.py $(PKGDIR)/man;\
cp -a man/man1/cmark.1 $(PKGDIR)/man/man1;\
+ cp -a man/man3/cmark.3 $(PKGDIR)/man/man3;\
+ cp -a data/CaseFolding-3.2.0.txt $(PKGDIR)/data/;\
cp CMakeLists.txt $(PKGDIR); \
perl -ne '$$p++ if /^### JavaScript/; print if (!$$p)' Makefile > $(PKGDIR)/Makefile; \
cp -a Makefile.nmake nmake.bat $(PKGDIR); \
- cp -a README.md COPYING spec.txt $(PKGDIR)/; \
+ cp -a README.md COPYING spec.txt spec.html $(PKGDIR)/; \
tar czf $(TARBALL) $(PKGDIR); \
zip -q -r $(ZIPARCHIVE) $(PKGDIR); \
rm -rf $(PKGDIR) ; \
diff --git a/Makefile.nmake b/Makefile.nmake
index 54034c4..3f3bbce 100644
--- a/Makefile.nmake
+++ b/Makefile.nmake
@@ -29,9 +29,6 @@ clean:
$(SRCDIR)\case_fold_switch.inc: $(DATADIR)\CaseFolding-3.2.0.txt
perl mkcasefold.pl < $? > $@
-man\man1\cmark.1: man\cmark.1.md
- pandoc $? -o $@ -s -t man
-
test: $(SPEC) all
@pushd $(BUILDDIR) && $(MAKE) /nologo test ARGS="-V" && popd
@@ -41,17 +38,14 @@ distclean: clean
### Spec ###
-spec.md: $(SPEC)
- perl spec2md.pl < $? > $@
+spec.html: spec.txt template.html $(PROG)
+ python3 makespec.py html > $@
-spec.html: spec.md template.html
- pandoc --no-highlight --number-sections --template template.html -s --toc -S $? | \
- perl -pe "s/a href=\"@([^"]*)\"/a id=\"\\1\" href=\"#\\1\" class=\"definition\"/g" | \
- perl -pe "s/\\x{2423}/<span class=\"space\"> <\\/span>/g" \
- > $@
+spec.md: spec.txt
+ python3 makespec.py markdown > $@
spec.pdf: spec.md template.tex specfilter.hs
- pandoc -s $? --template template.tex \
- --filter specfilter.hs -o $@ --latex-engine=xelatex --toc \
+ pandoc -s $< --template template.tex \
+ --filter ./specfilter.hs -o $@ --latex-engine=xelatex --toc \
--number-sections -V documentclass=report -V tocdepth=2 \
-V classoption=twosides
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index 1540812..443996e 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -1,32 +1,8 @@
if (NOT MSVC)
- set(PYTHON python)
- set(LIBRARY "libcmark")
-
- add_custom_target(man ALL
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/cmark.3
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/cmark.1
- )
-
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cmark.3
- DEPENDS ${CMAKE_SOURCE_DIR}/src/cmark.h
- DEPENDS ${LIBRARY}
- COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/make_man_page.py
- ${CMAKE_SOURCE_DIR}/src/cmark.h >
- ${CMAKE_CURRENT_BINARY_DIR}/cmark.3
- )
-
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cmark.1
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
- COMMAND cp
- ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
- ${CMAKE_CURRENT_BINARY_DIR}/cmark.1
- )
-
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmark.1
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
DESTINATION share/man/man1)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmark.3
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark.3
DESTINATION share/man/man3)
-endif(NOT MSVC) \ No newline at end of file
+endif(NOT MSVC)
+
diff --git a/man/make_man_page.py b/man/make_man_page.py
index 2202309..fe968b4 100644
--- a/man/make_man_page.py
+++ b/man/make_man_page.py
@@ -21,9 +21,9 @@ from ctypes import CDLL, c_char_p, c_long, c_void_p
sysname = platform.system()
if sysname == 'Darwin':
- cmark = CDLL("../src/libcmark.dylib")
+ cmark = CDLL("build/src/libcmark.dylib")
else:
- cmark = CDLL("../src/libcmark.so")
+ cmark = CDLL("build/src/libcmark.so")
parse_document = cmark.cmark_parse_document
parse_document.restype = c_void_p
diff --git a/man/man3/cmark.3 b/man/man3/cmark.3
new file mode 100644
index 0000000..5df89c3
--- /dev/null
+++ b/man/man3/cmark.3
@@ -0,0 +1,520 @@
+.TH cmark 3 "January 11, 2015" "LOCAL" "Library Functions Manual"
+.SH
+NAME
+.PP
+\f[B]cmark\f[] \- CommonMark parsing, manipulating, and rendering
+
+.SH
+DESCRIPTION
+.SS
+Simple Interface
+
+.PP
+.nf
+\fC
+.RS 0n
+#define CMARK_VERSION "0.1"
+.RE
+\f[]
+.fi
+
+.PP
+Current version of library.
+
+.PP
+\fIchar *\f[] \fBcmark_markdown_to_html\f[](\fIconst char *text\f[], \fIint len\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.
+
+.SS
+Node Structure
+
+.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
+\fIvoid\f[] \fBcmark_node_free\f[](\fIcmark_node *node\f[])
+
+.PP
+Frees the memory allocated for a node.
+
+.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 headers 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
+.IP \[bu] 2
+CMARK_NODE_HRULE
+.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_INLINE_HTML
+.PP
+Nodes must only be modified after an \f[C]EXIT\f[] event, or an \f[C]ENTER\f[] event for
+leaf nodes.
+
+.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[C]cmark_iter_next\f[] is called for the first time.
+
+.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
+\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
+\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]"<unknown>"\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 NULL if none.
+
+.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_header_level\f[](\fIcmark_node *node\f[])
+
+.PP
+Returns the header level of \f[I]node\f[], or 0 if \f[I]node\f[] is not a header.
+
+.PP
+\fIint\f[] \fBcmark_node_set_header_level\f[](\fIcmark_node *node\f[], \fIint level\f[])
+
+.PP
+Sets the header 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, or NULL if none.
+
+.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
+Gets the URL of a link or image \f[I]node\f[], or NULL if none.
+
+.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
+Gets the title of a link or image \f[I]node\f[], or NULL if none.
+
+.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
+\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_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*", 12);
+\f[]
+.fi
+.PP
+Streaming interface:
+.IP
+.nf
+\f[C]
+cmark_parser *parser = cmark_parser_new();
+FILE *fp = fopen("myfile.md", "r");
+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[](\fI\f[])
+
+.PP
+Creates a new parser object.
+
+.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[])
+
+.PP
+Parse a CommonMark document in \f[I]buffer\f[] of length \f[I]len\f[]\&.
+Returns a pointer to a tree of nodes.
+
+.PP
+\fIcmark_node *\f[] \fBcmark_parse_file\f[](\fIFILE *f\f[])
+
+.PP
+Parse a CommonMark document in file \f[I]f\f[], returning a pointer to
+a tree of nodes.
+
+.SS
+Rendering
+
+.PP
+\fIchar *\f[] \fBcmark_render_xml\f[](\fIcmark_node *root\f[], \fIlong options\f[])
+
+.PP
+Render a \f[I]node\f[] tree as XML.
+
+.PP
+\fIchar *\f[] \fBcmark_render_html\f[](\fIcmark_node *root\f[], \fIlong 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.
+
+.PP
+\fIchar *\f[] \fBcmark_render_man\f[](\fIcmark_node *root\f[], \fIlong options\f[])
+
+.PP
+Render a \f[I]node\f[] tree as a groff man page, without the header.
+
+.PP
+.nf
+\fC
+.RS 0n
+#define CMARK_OPT_DEFAULT 0
+.RE
+\f[]
+.fi
+
+.PP
+Default writer options.
+
+.PP
+.nf
+\fC
+.RS 0n
+#define CMARK_OPT_SOURCEPOS 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 2
+.RE
+\f[]
+.fi
+
+.PP
+Render \f[C]softbreak\f[] elements as hard line breaks.
+
+.PP
+.nf
+\fC
+.RS 0n
+#define CMARK_OPT_NORMALIZE 4
+.RE
+\f[]
+.fi
+
+.PP
+Normalize tree by consolidating adjacent text nodes.
+
+.SH
+AUTHORS
+.PP
+John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer.
+