cmark-gfm 0.1.5 → 0.1.6
raw patch · 20 files changed
+207/−41 lines, 20 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- CMarkGFM: optSafe :: CMarkOption
+ CMarkGFM: optUnsafe :: CMarkOption
Files
- CMarkGFM.hsc +4/−4
- cbits/cmark-gfm-core-extensions.h +3/−0
- cbits/cmark-gfm-extension_api.h +19/−2
- cbits/cmark-gfm-extensions_export.h +1/−1
- cbits/cmark-gfm.h +16/−8
- cbits/cmark-gfm_export.h +1/−1
- cbits/cmark-gfm_version.h +2/−2
- cbits/commonmark.c +6/−2
- cbits/houdini_href_e.c +2/−2
- cbits/html.c +4/−4
- cbits/inlines.c +34/−3
- cbits/node.c +17/−3
- cbits/strikethrough.c +4/−1
- cbits/syntax_extension.c +10/−0
- cbits/syntax_extension.h +2/−0
- cbits/table.c +63/−1
- cbits/xml.c +9/−2
- changelog +5/−0
- cmark-gfm.cabal +2/−2
- test/test-cmark.hs +3/−3
CMarkGFM.hsc view
@@ -15,7 +15,7 @@ , optSourcePos , optHardBreaks , optSmart- , optSafe+ , optUnsafe , extStrikethrough , extTable , extAutolink@@ -278,10 +278,10 @@ optSmart :: CMarkOption optSmart = CMarkOption #const CMARK_OPT_SMART --- | Suppress rendering of raw HTML and potentially dangerous URLs in links+-- | Allow rendering of raw HTML and potentially dangerous URLs in links -- and images.-optSafe :: CMarkOption-optSafe = CMarkOption #const CMARK_OPT_SAFE+optUnsafe :: CMarkOption+optUnsafe = CMarkOption #const CMARK_OPT_UNSAFE newtype CMarkExtension = CMarkExtension { unCMarkExtension :: String }
cbits/cmark-gfm-core-extensions.h view
@@ -18,6 +18,9 @@ CMARK_GFM_EXTENSIONS_EXPORT uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node); +CMARK_GFM_EXTENSIONS_EXPORT+int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);+ #ifdef __cplusplus } #endif
cbits/cmark-gfm-extension_api.h view
@@ -106,8 +106,6 @@ * with 'cmark_syntax_extension_set_private', * and optionally define a free function for this data. */-typedef struct cmark_syntax_extension cmark_syntax_extension;- typedef struct subject cmark_inline_parser; /** Exposed raw for now */@@ -238,6 +236,9 @@ cmark_node *node, int c); +typedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension,+ cmark_node *node);+ typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension, struct cmark_html_renderer *renderer, cmark_node *node,@@ -254,6 +255,10 @@ typedef int (*cmark_ispunct_func) (char c); +typedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension,+ cmark_mem *mem,+ cmark_node *node);+ typedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension, cmark_mem *mem, cmark_node *node);@@ -343,6 +348,12 @@ /** See the documentation for 'cmark_syntax_extension' */ CMARK_GFM_EXPORT+void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,+ cmark_xml_attr_func func);++ /** See the documentation for 'cmark_syntax_extension'+ */+CMARK_GFM_EXPORT void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension, cmark_common_render_func func); @@ -381,6 +392,12 @@ CMARK_GFM_EXPORT void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension, cmark_postprocess_func func);++/** See the documentation for 'cmark_syntax_extension'+ */+CMARK_GFM_EXPORT+void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,+ cmark_opaque_alloc_func func); /** See the documentation for 'cmark_syntax_extension' */
cbits/cmark-gfm-extensions_export.h view
@@ -39,4 +39,4 @@ # endif #endif -#endif+#endif /* CMARK_GFM_EXTENSIONS_EXPORT_H */
cbits/cmark-gfm.h view
@@ -92,6 +92,7 @@ typedef struct cmark_node cmark_node; typedef struct cmark_parser cmark_parser; typedef struct cmark_iter cmark_iter;+typedef struct cmark_syntax_extension cmark_syntax_extension; /** * ## Custom memory allocator support@@ -187,6 +188,13 @@ CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem); +CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_ext(cmark_node_type type,+ cmark_syntax_extension *extension);++CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type,+ cmark_mem *mem,+ cmark_syntax_extension *extension);+ /** Frees the memory allocated for a node and any children. */ CMARK_GFM_EXPORT void cmark_node_free(cmark_node *node);@@ -682,14 +690,6 @@ */ #define CMARK_OPT_HARDBREAKS (1 << 2) -/** Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,- * `file:`, and `data:`, except for `image/png`, `image/gif`,- * `image/jpeg`, or `image/webp` mime types). Raw HTML is replaced- * by a placeholder HTML comment. Unsafe links are replaced by- * empty strings.- */-#define CMARK_OPT_SAFE (1 << 3)- /** Render `softbreak` elements as spaces. */ #define CMARK_OPT_NOBREAKS (1 << 4)@@ -737,6 +737,14 @@ * a separate attribute. */ #define CMARK_OPT_FULL_INFO_STRING (1 << 16)++/** Allow raw HTML and unsafe links, `javascript:`, `vbscript:`, `file:`, and+ * all `data:` URLs -- by default, only `image/png`, `image/gif`, `image/jpeg`,+ * or `image/webp` mime types are allowed. Without this option, raw HTML is+ * replaced by a placeholder HTML comment, and unsafe links are replaced by+ * empty strings.+ */+#define CMARK_OPT_UNSAFE (1 << 17) /** * ## Version information
cbits/cmark-gfm_export.h view
@@ -39,4 +39,4 @@ # endif #endif -#endif+#endif /* CMARK_GFM_EXPORT_H */
cbits/cmark-gfm_version.h view
@@ -1,7 +1,7 @@ #ifndef CMARK_GFM_VERSION_H #define CMARK_GFM_VERSION_H -#define CMARK_GFM_VERSION ((0 << 24) | (28 << 16) | (3 << 8) | 14)-#define CMARK_GFM_VERSION_STRING "0.28.3.gfm.14"+#define CMARK_GFM_VERSION ((0 << 24) | (28 << 16) | (3 << 8) | 18)+#define CMARK_GFM_VERSION_STRING "0.28.3.gfm.18" #endif
cbits/commonmark.c view
@@ -168,6 +168,7 @@ int list_number; cmark_delim_type list_delim; int numticks;+ bool extra_spaces; int i; bool entering = (ev_type == CMARK_EVENT_ENTER); const char *info, *code, *title;@@ -369,14 +370,17 @@ code = cmark_node_get_literal(node); code_len = strlen(code); numticks = shortest_unused_backtick_sequence(code);+ extra_spaces = code_len == 0 ||+ code[0] == '`' || code[code_len - 1] == '`' ||+ code[0] == ' ' || code[code_len - 1] == ' '; for (i = 0; i < numticks; i++) { LIT("`"); }- if (code_len == 0 || code[0] == '`') {+ if (extra_spaces) { LIT(" "); } OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);- if (code_len == 0 || code[code_len - 1] == '`') {+ if (extra_spaces) { LIT(" "); } for (i = 0; i < numticks; i++) {
cbits/houdini_href_e.c view
@@ -7,7 +7,7 @@ /* * The following characters will not be escaped: *- * -_.+!*'(),%#@?=;:/,+&$ alphanum+ * -_.+!*'(),%#@?=;:/,+&$~ alphanum * * Note that this character set is the addition of: *@@ -35,7 +35,7 @@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
cbits/html.c view
@@ -227,7 +227,7 @@ case CMARK_NODE_HTML_BLOCK: cmark_html_render_cr(html);- if (options & CMARK_OPT_SAFE) {+ if (!(options & CMARK_OPT_UNSAFE)) { cmark_strbuf_puts(html, "<!-- raw HTML omitted -->"); } else if (renderer->filter_extensions) { filter_html_block(renderer, node->as.literal.data, node->as.literal.len);@@ -305,7 +305,7 @@ break; case CMARK_NODE_HTML_INLINE:- if (options & CMARK_OPT_SAFE) {+ if (!(options & CMARK_OPT_UNSAFE)) { cmark_strbuf_puts(html, "<!-- raw HTML omitted -->"); } else { filtered = false;@@ -354,7 +354,7 @@ case CMARK_NODE_LINK: if (entering) { cmark_strbuf_puts(html, "<a href=\"");- if (!((options & CMARK_OPT_SAFE) &&+ if (!(!(options & CMARK_OPT_UNSAFE) && scan_dangerous_url(&node->as.link.url, 0))) { houdini_escape_href(html, node->as.link.url.data, node->as.link.url.len);@@ -372,7 +372,7 @@ case CMARK_NODE_IMAGE: if (entering) { cmark_strbuf_puts(html, "<img src=\"");- if (!((options & CMARK_OPT_SAFE) &&+ if (!(!(options & CMARK_OPT_UNSAFE) && scan_dangerous_url(&node->as.link.url, 0))) { houdini_escape_href(html, node->as.link.url.data, node->as.link.url.len);
cbits/inlines.c view
@@ -321,6 +321,37 @@ return 0; } +// Destructively modify string, converting newlines to+// spaces, then removing a single leading + trailing space.+static void S_normalize_code(cmark_strbuf *s) {+ bufsize_t r, w;++ for (r = 0, w = 0; r < s->size; ++r) {+ switch (s->ptr[r]) {+ case '\r':+ if (s->ptr[r + 1] != '\n') {+ s->ptr[w++] = ' ';+ }+ break;+ case '\n':+ s->ptr[w++] = ' ';+ break;+ default:+ s->ptr[w++] = s->ptr[r];+ }+ }++ // begins and ends with space?+ if (s->ptr[0] == ' ' && s->ptr[w - 1] == ' ') {+ cmark_strbuf_drop(s, 1);+ cmark_strbuf_truncate(s, w - 2);+ } else {+ cmark_strbuf_truncate(s, w);+ }++}++ // Parse backtick code section or raw backticks, return an inline. // Assumes that the subject has a backtick at the current position. static cmark_node *handle_backticks(subject *subj, int options) {@@ -336,8 +367,7 @@ cmark_strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);- cmark_strbuf_trim(&buf);- cmark_strbuf_normalize_whitespace(&buf);+ S_normalize_code(&buf); cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf)); adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);@@ -345,6 +375,7 @@ } } + // Scan ***, **, or * and return number scanned, or 0. // Advances position. static int scan_delims(subject *subj, unsigned char c, bool *can_open,@@ -1410,7 +1441,7 @@ // parse optional link_title beforetitle = subj.pos; spnl(&subj);- matchlen = scan_link_title(&subj.input, subj.pos);+ matchlen = subj.pos == beforetitle ? 0 : scan_link_title(&subj.input, subj.pos); if (matchlen) { title = cmark_chunk_dup(&subj.input, subj.pos, matchlen); subj.pos += matchlen;
cbits/node.c view
@@ -69,10 +69,11 @@ return cmark_node_can_contain_type(node, (cmark_node_type) child->type); } -cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {+cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type, cmark_mem *mem, cmark_syntax_extension *extension) { cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node)); cmark_strbuf_init(mem, &node->content, 0); node->type = (uint16_t)type;+ node->extension = extension; switch (node->type) { case CMARK_NODE_HEADING:@@ -91,12 +92,25 @@ break; } + if (node->extension && node->extension->opaque_alloc_func) {+ node->extension->opaque_alloc_func(node->extension, mem, node);+ }+ return node; } -cmark_node *cmark_node_new(cmark_node_type type) {+cmark_node *cmark_node_new_with_ext(cmark_node_type type, cmark_syntax_extension *extension) { extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;- return cmark_node_new_with_mem(type, &CMARK_DEFAULT_MEM_ALLOCATOR);+ return cmark_node_new_with_mem_and_ext(type, &CMARK_DEFAULT_MEM_ALLOCATOR, extension);+}++cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem)+{+ return cmark_node_new_with_mem_and_ext(type, mem, NULL);+}++cmark_node *cmark_node_new(cmark_node_type type) {+ return cmark_node_new_with_ext(type, NULL); } static void free_node_as(cmark_node *node) {
cbits/strikethrough.c view
@@ -28,7 +28,7 @@ res->start_column = cmark_inline_parser_get_column(inline_parser) - delims; if ((left_flanking || right_flanking) &&- (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) || delims == 2)) {+ (delims == 2 || (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) && delims == 1))) { cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking, right_flanking, res); }@@ -45,6 +45,9 @@ delimiter *res = closer->next; strikethrough = opener->inl_text;++ if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)+ goto done; if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH)) goto done;
cbits/syntax_extension.c view
@@ -97,6 +97,11 @@ extension->latex_render_func = func; } +void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,+ cmark_xml_attr_func func) {+ extension->xml_attr_func = func;+}+ void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension, cmark_common_render_func func) { extension->man_render_func = func;@@ -126,6 +131,11 @@ void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) { return extension->priv;+}++void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,+ cmark_opaque_alloc_func func) {+ extension->opaque_alloc_func = func; } void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,
cbits/syntax_extension.h view
@@ -21,10 +21,12 @@ cmark_common_render_func commonmark_render_func; cmark_common_render_func plaintext_render_func; cmark_common_render_func latex_render_func;+ cmark_xml_attr_func xml_attr_func; cmark_common_render_func man_render_func; cmark_html_render_func html_render_func; cmark_html_filter_func html_filter_func; cmark_postprocess_func postprocess_func;+ cmark_opaque_alloc_func opaque_alloc_func; cmark_opaque_free_func opaque_free_func; cmark_commonmark_escape_func commonmark_escape_func; };
cbits/table.c view
@@ -9,6 +9,7 @@ #include "ext_scanners.h" #include "strikethrough.h" #include "table.h"+#include "cmark-gfm-core-extensions.h" cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW, CMARK_NODE_TABLE_CELL;@@ -380,7 +381,8 @@ child_type == CMARK_NODE_EMPH || child_type == CMARK_NODE_STRONG || child_type == CMARK_NODE_LINK || child_type == CMARK_NODE_IMAGE || child_type == CMARK_NODE_STRIKETHROUGH ||- child_type == CMARK_NODE_HTML_INLINE;+ child_type == CMARK_NODE_HTML_INLINE ||+ child_type == CMARK_NODE_FOOTNOTE_REFERENCE; } return false; }@@ -487,6 +489,27 @@ } } +static const char *xml_attr(cmark_syntax_extension *extension,+ cmark_node *node) {+ if (node->type == CMARK_NODE_TABLE_CELL) {+ if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {+ uint8_t *alignments = get_table_alignments(node->parent->parent);+ int i = 0;+ cmark_node *n;+ for (n = node->parent->first_child; n; n = n->next, ++i)+ if (n == node)+ break;+ switch (alignments[i]) {+ case 'l': return " align=\"left\"";+ case 'c': return " align=\"center\"";+ case 'r': return " align=\"right\"";+ }+ }+ }++ return NULL;+}+ static void man_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {@@ -647,6 +670,16 @@ } } +static void opaque_alloc(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {+ if (node->type == CMARK_NODE_TABLE) {+ node->as.opaque = mem->calloc(1, sizeof(node_table));+ } else if (node->type == CMARK_NODE_TABLE_ROW) {+ node->as.opaque = mem->calloc(1, sizeof(node_table_row));+ } else if (node->type == CMARK_NODE_TABLE_CELL) {+ node->as.opaque = mem->calloc(1, sizeof(node_cell));+ }+}+ static void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) { if (node->type == CMARK_NODE_TABLE) { free_node_table(mem, node->as.opaque);@@ -674,8 +707,10 @@ cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render); cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render); cmark_syntax_extension_set_latex_render_func(self, latex_render);+ cmark_syntax_extension_set_xml_attr_func(self, xml_attr); cmark_syntax_extension_set_man_render_func(self, man_render); cmark_syntax_extension_set_html_render_func(self, html_render);+ cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc); cmark_syntax_extension_set_opaque_free_func(self, opaque_free); cmark_syntax_extension_set_commonmark_escape_func(self, escape); CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);@@ -697,4 +732,31 @@ return 0; return ((node_table *)node->as.opaque)->alignments;+}++int cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns) {+ return set_n_table_columns(node, n_columns);+}++int cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments) {+ uint8_t *a = (uint8_t *)cmark_node_mem(node)->calloc(1, ncols);+ memcpy(a, alignments, ncols);+ return set_table_alignments(node, a);+}++int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node)+{+ if (!node || node->type != CMARK_NODE_TABLE_ROW)+ return 0;++ return ((node_table_row *)node->as.opaque)->is_header;+}++int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header)+{+ if (!node || node->type != CMARK_NODE_TABLE_ROW)+ return 0;++ ((node_table_row *)node->as.opaque)->is_header = (is_header != 0);+ return 1; }
cbits/xml.c view
@@ -8,6 +8,7 @@ #include "node.h" #include "buffer.h" #include "houdini.h"+#include "syntax_extension.h" #define BUFFER_SIZE 100 @@ -50,6 +51,12 @@ cmark_strbuf_puts(xml, buffer); } + if (node->extension && node->extension->xml_attr_func) {+ const char* r = node->extension->xml_attr_func(node->extension, node);+ if (r != NULL)+ cmark_strbuf_puts(xml, r);+ }+ literal = false; switch (node->type) {@@ -60,7 +67,7 @@ case CMARK_NODE_CODE: case CMARK_NODE_HTML_BLOCK: case CMARK_NODE_HTML_INLINE:- cmark_strbuf_puts(xml, ">");+ cmark_strbuf_puts(xml, " xml:space=\"preserve\">"); escape_xml(xml, node->as.literal.data, node->as.literal.len); cmark_strbuf_puts(xml, "</"); cmark_strbuf_puts(xml, cmark_node_get_type_string(node));@@ -100,7 +107,7 @@ escape_xml(xml, node->as.code.info.data, node->as.code.info.len); cmark_strbuf_putc(xml, '"'); }- cmark_strbuf_puts(xml, ">");+ cmark_strbuf_puts(xml, " xml:space=\"preserve\">"); escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len); cmark_strbuf_puts(xml, "</"); cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
changelog view
@@ -1,3 +1,8 @@+cmark-gfm 0.1.6 (17 Oct 2018)++ * Update to cmark-gfm 0.28.3.gfm.18.+ * `optUnsafe` is now exposed, instead of `optSafe`. + cmark-gfm 0.1.5 (21 Aug 2018) * Update to cmark-gfm 0.28.3.gfm.15.
cmark-gfm.cabal view
@@ -1,5 +1,5 @@ name: cmark-gfm-version: 0.1.5+version: 0.1.6 synopsis: Fast, accurate GitHub Flavored Markdown parser and renderer description: This package provides Haskell bindings for@@ -76,7 +76,7 @@ default-language: Haskell2010 ghc-options: -Wall -fno-warn-unused-do-bind if flag(pkgconfig)- Extra-Libraries: cmark-gfm cmark-gfmextensions+ Extra-Libraries: cmark-gfm cmark-gfm-extensions else cc-options: -Wall -std=c99 Include-dirs: cbits
test/test-cmark.hs view
@@ -18,7 +18,7 @@ tests = TestList [ "<h1>Hi</h1>\n" ~=? commonmarkToHtml [] [] "# Hi" , "<p>dog’s</p>\n" ~=? commonmarkToHtml [optSmart] [] "dog's"- , "<p><a href=\"\">trick</a></p>\n" ~=? commonmarkToHtml [optSafe] [] "[trick](javascript:alert('hi'))"+ , "<p><a href=\"\">trick</a></p>\n" ~=? commonmarkToHtml [] [] "[trick](javascript:alert('hi'))" , ".RS\n.PP\nquote\n.RE\n" ~=? commonmarkToMan [] [] Nothing "> quote" , (Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 1, endColumn = 13})) DOCUMENT [Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 1, endColumn = 13})) PARAGRAPH [Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 1, endColumn = 6})) (TEXT "Hello ") [],Node (Just (PosInfo {startLine = 1, startColumn = 7, endLine = 1, endColumn = 13})) EMPH [Node (Just (PosInfo {startLine = 1, startColumn = 8, endLine = 1, endColumn = 12})) (TEXT "world") []]]]) ~=? commonmarkToNode [] [] "Hello *world*" , "> Hello\n> *world*\n" ~=? nodeToCommonmark [] (Just 12) (Node Nothing DOCUMENT [Node Nothing BLOCK_QUOTE [Node Nothing PARAGRAPH [Node Nothing (TEXT "Hello ") [],Node Nothing EMPH [Node Nothing (TEXT "world") []]]]])@@ -30,6 +30,6 @@ , "<p>| a |\n| --- |\n| b |</p>\n" ~=? commonmarkToHtml [] [] "| a |\n| --- |\n| b |\n" , "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>\n" ~=? commonmarkToHtml [] [extTable] "| a |\n| --- |\n| b |\n" , Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 3, endColumn = 17})) DOCUMENT [Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 3, endColumn = 17})) (TABLE [LeftAligned,CenterAligned,NoAlignment,RightAligned]) [Node (Just (PosInfo {startLine = 1, startColumn = 1, endLine = 1, endColumn = 17})) TABLE_ROW [Node (Just (PosInfo {startLine = 1, startColumn = 2, endLine = 1, endColumn = 4})) TABLE_CELL [Node (Just (PosInfo {startLine = 1, startColumn = 3, endLine = 1, endColumn = 3})) (TEXT "a") []],Node (Just (PosInfo {startLine = 1, startColumn = 6, endLine = 1, endColumn = 8})) TABLE_CELL [Node (Just (PosInfo {startLine = 1, startColumn = 7, endLine = 1, endColumn = 7})) (TEXT "b") []],Node (Just (PosInfo {startLine = 1, startColumn = 10, endLine = 1, endColumn = 12})) TABLE_CELL [Node (Just (PosInfo {startLine = 1, startColumn = 11, endLine = 1, endColumn = 11})) (TEXT "c") []],Node (Just (PosInfo {startLine = 1, startColumn = 14, endLine = 1, endColumn = 16})) TABLE_CELL [Node (Just (PosInfo {startLine = 1, startColumn = 15, endLine = 1, endColumn = 15})) (TEXT "d") []]],Node (Just (PosInfo {startLine = 3, startColumn = 1, endLine = 3, endColumn = 17})) TABLE_ROW [Node (Just (PosInfo {startLine = 3, startColumn = 2, endLine = 3, endColumn = 4})) TABLE_CELL [Node (Just (PosInfo {startLine = 3, startColumn = 3, endLine = 3, endColumn = 3})) (TEXT "y") []],Node (Just (PosInfo {startLine = 3, startColumn = 6, endLine = 3, endColumn = 8})) TABLE_CELL [Node (Just (PosInfo {startLine = 3, startColumn = 7, endLine = 3, endColumn = 7})) (TEXT "o") []],Node (Just (PosInfo {startLine = 3, startColumn = 10, endLine = 3, endColumn = 12})) TABLE_CELL [Node (Just (PosInfo {startLine = 3, startColumn = 11, endLine = 3, endColumn = 11})) (TEXT "s") []],Node (Just (PosInfo {startLine = 3, startColumn = 14, endLine = 3, endColumn = 16})) TABLE_CELL [Node (Just (PosInfo {startLine = 3, startColumn = 15, endLine = 3, endColumn = 15})) (TEXT "h") []]]]] ~=? commonmarkToNode [] [extTable] "| a | b | c | d |\n| :-- | :-: | --- | --: |\n| y | o | s | h |"- , "<xmp>\n" ~=? commonmarkToHtml [] [] "<xmp>"- , "<xmp>\n" ~=? commonmarkToHtml [] [extTagfilter] "<xmp>"+ , "<xmp>\n" ~=? commonmarkToHtml [optUnsafe] [] "<xmp>"+ , "<xmp>\n" ~=? commonmarkToHtml [optUnsafe] [extTagfilter] "<xmp>" ]