Hello community,
here is the log from the commit of package ghc-cmark for openSUSE:Factory checked in at 2016-03-31 13:02:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-cmark (Old)
and /work/SRC/openSUSE:Factory/.ghc-cmark.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-cmark"
Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-cmark/ghc-cmark.changes 2016-02-05 00:31:25.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-cmark.new/ghc-cmark.changes 2016-03-31 13:02:37.000000000 +0200
@@ -1,0 +2,7 @@
+Tue Mar 29 06:55:28 UTC 2016 - mimi.vx@gmail.com
+
+- update to 0.5.2
+* Add flag to allow building with an installed libcmark (Jens Petersen).
+* Updated to libcmark 0.25.2.
+
+-------------------------------------------------------------------
Old:
----
cmark-0.5.1.tar.gz
New:
----
cmark-0.5.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-cmark.spec ++++++
--- /var/tmp/diff_new_pack.TiilDK/_old 2016-03-31 13:02:38.000000000 +0200
+++ /var/tmp/diff_new_pack.TiilDK/_new 2016-03-31 13:02:38.000000000 +0200
@@ -21,7 +21,7 @@
%bcond_with tests
Name: ghc-cmark
-Version: 0.5.1
+Version: 0.5.2
Release: 0
Summary: Fast, accurate CommonMark (Markdown) parser and renderer
License: BSD-3-Clause and BSD-2-Clause and MIT
++++++ cmark-0.5.1.tar.gz -> cmark-0.5.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/README.md new/cmark-0.5.2/README.md
--- old/cmark-0.5.1/README.md 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/README.md 2016-03-26 21:36:02.000000000 +0100
@@ -3,8 +3,8 @@
This package provides Haskell bindings for [libcmark], the reference
parser for [CommonMark], a fully specified variant of Markdown.
-It includes sources for [libcmark] (version 0.23.0, implementing
-version 0.23 of the spec) and does not require prior installation of
+It includes sources for [libcmark] (version 0.25.2, implementing
+version 0.25 of the spec) and does not require prior installation of
the C library.
cmark provides the following advantages over existing Markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/blocks.c new/cmark-0.5.2/cbits/blocks.c
--- old/cmark-0.5.1/cbits/blocks.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/blocks.c 2016-03-26 21:36:02.000000000 +0100
@@ -1,3 +1,10 @@
+/**
+ * Block parsing implementation.
+ *
+ * For a high-level overview of the block parsing process,
+ * see http://spec.commonmark.org/0.24/#phase-1-block-structure
+ */
+
#include
#include
#include
@@ -17,12 +24,20 @@
#define CODE_INDENT 4
#define TAB_STOP 4
+#ifndef MIN
+#define MIN(x, y) ((x < y) ? x : y)
+#endif
+
#define peek_at(i, n) (i)->data[n]
-static inline bool S_is_line_end_char(char c) {
+static CMARK_INLINE bool S_is_line_end_char(char c) {
return (c == '\n' || c == '\r');
}
+static CMARK_INLINE bool S_is_space_or_tab(char c) {
+ return (c == ' ' || c == '\t');
+}
+
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
size_t len, bool eof);
@@ -70,10 +85,12 @@
parser->first_nonspace_column = 0;
parser->indent = 0;
parser->blank = false;
+ parser->partially_consumed_tab = false;
parser->curline = line;
parser->last_line_length = 0;
parser->linebuf = buf;
parser->options = options;
+ parser->last_buffer_ended_with_cr = false;
return parser;
}
@@ -110,7 +127,7 @@
return true;
}
-static inline bool can_contain(cmark_node_type parent_type,
+static CMARK_INLINE bool can_contain(cmark_node_type parent_type,
cmark_node_type child_type) {
return (parent_type == CMARK_NODE_DOCUMENT ||
parent_type == CMARK_NODE_BLOCK_QUOTE ||
@@ -118,15 +135,32 @@
(parent_type == CMARK_NODE_LIST && child_type == CMARK_NODE_ITEM));
}
-static inline bool accepts_lines(cmark_node_type block_type) {
+static CMARK_INLINE bool accepts_lines(cmark_node_type block_type) {
return (block_type == CMARK_NODE_PARAGRAPH ||
block_type == CMARK_NODE_HEADING ||
block_type == CMARK_NODE_CODE_BLOCK);
}
-static void add_line(cmark_node *node, cmark_chunk *ch, bufsize_t offset) {
+static CMARK_INLINE bool contains_inlines(cmark_node_type block_type) {
+ return (block_type == CMARK_NODE_PARAGRAPH ||
+ block_type == CMARK_NODE_HEADING);
+}
+
+static void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {
+ int chars_to_tab;
+ int i;
assert(node->open);
- cmark_strbuf_put(&node->string_content, ch->data + offset, ch->len - offset);
+ if (parser->partially_consumed_tab) {
+ parser->offset += 1; // skip over tab
+ // add space characters:
+ chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
+ for (i = 0; i < chars_to_tab; i++) {
+ cmark_strbuf_putc(&node->string_content, ' ');
+ }
+ }
+ cmark_strbuf_put(&node->string_content,
+ ch->data + parser->offset,
+ ch->len - parser->offset);
}
static void remove_trailing_blank_lines(cmark_strbuf *ln) {
@@ -336,8 +370,7 @@
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
if (ev_type == CMARK_EVENT_ENTER) {
- if (cur->type == CMARK_NODE_PARAGRAPH ||
- cur->type == CMARK_NODE_HEADING) {
+ if (contains_inlines(cur->type)) {
cmark_parse_inlines(cur, refmap, options);
}
}
@@ -474,6 +507,11 @@
const unsigned char *end = buffer + len;
static const uint8_t repl[] = {239, 191, 189};
+ if (parser->last_buffer_ended_with_cr && *buffer == '\n') {
+ // skip NL if last buffer ended with CR ; see #117
+ buffer++;
+ }
+ parser->last_buffer_ended_with_cr = false;
while (buffer < end) {
const unsigned char *eol;
bufsize_t chunk_len;
@@ -514,8 +552,11 @@
buffer += chunk_len;
// skip over line ending characters:
- if (buffer < end && *buffer == '\r')
+ if (buffer < end && *buffer == '\r') {
buffer++;
+ if (buffer == end)
+ parser->last_buffer_ended_with_cr = true;
+ }
if (buffer < end && *buffer == '\n')
buffer++;
}
@@ -532,13 +573,15 @@
n--;
// Check for a space before the final #s:
- if (n != orig_n && n >= 0 &&
- (peek_at(ch, n) == ' ' || peek_at(ch, n) == '\t')) {
+ if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) {
ch->len = n;
cmark_chunk_rtrim(ch);
}
}
+// Find first nonspace character from current offset, setting
+// parser->first_nonspace, parser->first_nonspace_column,
+// parser->indent, and parser->blank. Does not advance parser->offset.
static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
char c;
int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
@@ -566,17 +609,37 @@
parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));
}
+// Advance parser->offset and parser->column. parser->offset is the
+// byte position in input; parser->column is a virtual column number
+// that takes into account tabs. (Multibyte characters are not taken
+// into account, because the Markdown line prefixes we are interested in
+// analyzing are entirely ASCII.) The count parameter indicates
+// how far to advance the offset. If columns is true, then count
+// indicates a number of columns; otherwise, a number of bytes.
+// If advancing a certain number of columns partially consumes
+// a tab character, parser->partially_consumed_tab is set to true.
static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
bufsize_t count, bool columns) {
char c;
int chars_to_tab;
+ int chars_to_advance;
while (count > 0 && (c = peek_at(input, parser->offset))) {
if (c == '\t') {
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
- parser->column += chars_to_tab;
- parser->offset += 1;
- count -= (columns ? chars_to_tab : 1);
+ if (columns) {
+ parser->partially_consumed_tab = chars_to_tab > count;
+ chars_to_advance = MIN(count, chars_to_tab);
+ parser->column += chars_to_advance;
+ parser->offset += (parser->partially_consumed_tab ? 0 : 1);
+ count -= chars_to_advance;
+ } else {
+ parser->partially_consumed_tab = false;
+ parser->column += chars_to_tab;
+ parser->offset += 1;
+ count -= 1;
+ }
} else {
+ parser->partially_consumed_tab = false;
parser->offset += 1;
parser->column += 1; // assume ascii; block starts are ascii
count -= 1;
@@ -584,263 +647,314 @@
}
}
-static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
- bufsize_t bytes) {
- cmark_node *last_matched_container;
- bufsize_t matched = 0;
- int lev = 0;
- int i;
- cmark_list *data = NULL;
- bool all_matched = true;
- cmark_node *container;
- bool indented;
- cmark_chunk input;
- bool maybe_lazy;
-
- if (parser->options & CMARK_OPT_VALIDATE_UTF8) {
- cmark_utf8proc_check(parser->curline, buffer, bytes);
- } else {
- cmark_strbuf_put(parser->curline, buffer, bytes);
- }
- // ensure line ends with a newline:
- if (bytes == 0 || !S_is_line_end_char(parser->curline->ptr[bytes - 1])) {
- cmark_strbuf_putc(parser->curline, '\n');
- }
- parser->offset = 0;
- parser->column = 0;
- parser->blank = false;
-
- input.data = parser->curline->ptr;
- input.len = parser->curline->size;
-
- // container starts at the document root.
- container = parser->root;
+static bool S_last_child_is_open(cmark_node *container) {
+ return container->last_child && container->last_child->open;
+}
- parser->line_number++;
+static bool parse_block_quote_prefix(cmark_parser *parser,
+ cmark_chunk *input)
+{
+ bool res = false;
+ bufsize_t matched = 0;
- // for each containing node, try to parse the associated line start.
- // bail out on failure: container will point to the last matching node.
+ matched =
+ parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>';
+ if (matched) {
+
+ S_advance_offset(parser, input, parser->indent + 1, true);
+
+ if (S_is_space_or_tab(peek_at(input, parser->offset))) {
+ S_advance_offset(parser, input, 1, true);
+ }
+
+ res = true;
+ }
+ return res;
+}
+
+static bool parse_node_item_prefix(cmark_parser *parser,
+ cmark_chunk *input,
+ cmark_node *container)
+{
+ bool res = false;
+
+ if (parser->indent >=
+ container->as.list.marker_offset + container->as.list.padding) {
+ S_advance_offset(parser, input, container->as.list.marker_offset +
+ container->as.list.padding,
+ true);
+ res = true;
+ } else if (parser->blank && container->first_child != NULL) {
+ // if container->first_child is NULL, then the opening line
+ // of the list item was blank after the list marker; in this
+ // case, we are done with the list item.
+ S_advance_offset(parser, input,
+ parser->first_nonspace - parser->offset, false);
+ res = true;
+ }
+ return res;
+}
+
+static bool parse_code_block_prefix(cmark_parser *parser,
+ cmark_chunk *input,
+ cmark_node *container,
+ bool *should_continue)
+{
+ bool res = false;
+
+ if (!container->as.code.fenced) { // indented
+ if (parser->indent >= CODE_INDENT) {
+ S_advance_offset(parser, input, CODE_INDENT, true);
+ res = true;
+ } else if (parser->blank) {
+ S_advance_offset(parser, input,
+ parser->first_nonspace - parser->offset, false);
+ res = true;
+ }
+ } else { // fenced
+ bufsize_t matched = 0;
+
+ if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) ==
+ container->as.code.fence_char)) {
+ matched = scan_close_code_fence(input, parser->first_nonspace);
+ }
+
+ if (matched >= container->as.code.fence_length) {
+ // closing fence - and since we're at
+ // the end of a line, we can stop processing it:
+ *should_continue = false;
+ S_advance_offset(parser, input, matched, false);
+ parser->current = finalize(parser, container);
+ } else {
+ // skip opt. spaces of fence parser->offset
+ int i = container->as.code.fence_offset;
- while (container->last_child && container->last_child->open) {
- container = container->last_child;
+ while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) {
+ S_advance_offset(parser, input, 1, true);
+ i--;
+ }
+ res = true;
+ }
+ }
- S_find_first_nonspace(parser, &input);
+ return res;
+}
- if (container->type == CMARK_NODE_BLOCK_QUOTE) {
- matched =
- parser->indent <= 3 && peek_at(&input, parser->first_nonspace) == '>';
- if (matched) {
- S_advance_offset(parser, &input, parser->indent + 1, true);
- if (peek_at(&input, parser->offset) == ' ')
- parser->offset++;
- } else {
- all_matched = false;
- }
+static bool parse_html_block_prefix(cmark_parser *parser,
+ cmark_node *container)
+{
+ bool res = false;
+ int html_block_type = container->as.html_block_type;
- } else if (container->type == CMARK_NODE_ITEM) {
- if (parser->indent >=
- container->as.list.marker_offset + container->as.list.padding) {
- S_advance_offset(parser, &input, container->as.list.marker_offset +
- container->as.list.padding,
- true);
- } else if (parser->blank && container->first_child != NULL) {
- // if container->first_child is NULL, then the opening line
- // of the list item was blank after the list marker; in this
- // case, we are done with the list item.
- S_advance_offset(parser, &input,
- parser->first_nonspace - parser->offset, false);
- } else {
- all_matched = false;
- }
+ assert(html_block_type >= 1 && html_block_type <= 7);
+ switch (html_block_type) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ // these types of blocks can accept blanks
+ res = true;
+ break;
+ case 6:
+ case 7:
+ res = !parser->blank;
+ break;
+ }
- } else if (container->type == CMARK_NODE_CODE_BLOCK) {
+ return res;
+}
- if (!container->as.code.fenced) { // indented
- if (parser->indent >= CODE_INDENT) {
- S_advance_offset(parser, &input, CODE_INDENT, true);
- } else if (parser->blank) {
- S_advance_offset(parser, &input,
- parser->first_nonspace - parser->offset, false);
- } else {
- all_matched = false;
- }
- } else { // fenced
- matched = 0;
- if (parser->indent <= 3 && (peek_at(&input, parser->first_nonspace) ==
- container->as.code.fence_char)) {
- matched = scan_close_code_fence(&input, parser->first_nonspace);
- }
- if (matched >= container->as.code.fence_length) {
- // closing fence - and since we're at
- // the end of a line, we can return:
- all_matched = false;
- S_advance_offset(parser, &input, matched, false);
- parser->current = finalize(parser, container);
- goto finished;
- } else {
- // skip opt. spaces of fence parser->offset
- i = container->as.code.fence_offset;
- while (i > 0 && peek_at(&input, parser->offset) == ' ') {
- S_advance_offset(parser, &input, 1, false);
- i--;
- }
- }
- }
- } else if (container->type == CMARK_NODE_HEADING) {
+/**
+ * For each containing node, try to parse the associated line start.
+ *
+ * Will not close unmatched blocks, as we may have a lazy continuation
+ * line -> http://spec.commonmark.org/0.24/#lazy-continuation-line
+ *
+ * Returns: The last matching node, or NULL
+ */
+static cmark_node *check_open_blocks(cmark_parser *parser,
+ cmark_chunk *input,
+ bool *all_matched)
+{
+ bool should_continue = true;
+ *all_matched = false;
+ cmark_node *container = parser->root;
+ cmark_node_type cont_type;
- // a heading can never contain more than one line
- all_matched = false;
+ while (S_last_child_is_open(container)) {
+ container = container->last_child;
+ cont_type = container->type;
- } else if (container->type == CMARK_NODE_HTML_BLOCK) {
+ S_find_first_nonspace(parser, input);
- switch (container->as.html_block_type) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- // these types of blocks can accept blanks
+ switch (cont_type) {
+ case CMARK_NODE_BLOCK_QUOTE:
+ if (!parse_block_quote_prefix(parser, input))
+ goto done;
break;
- case 6:
- case 7:
- if (parser->blank) {
- all_matched = false;
- }
+ case CMARK_NODE_ITEM:
+ if (!parse_node_item_prefix(parser, input, container))
+ goto done;
+ break;
+ case CMARK_NODE_CODE_BLOCK:
+ if (!parse_code_block_prefix(parser, input, container, &should_continue))
+ goto done;
+ break;
+ case CMARK_NODE_HEADING:
+ // a heading can never contain more than one line
+ goto done;
+ case CMARK_NODE_HTML_BLOCK:
+ if (!parse_html_block_prefix(parser, container))
+ goto done;
+ break;
+ case CMARK_NODE_PARAGRAPH:
+ if (parser->blank)
+ goto done;
break;
default:
- fprintf(stderr, "Error (%s:%d): Unknown HTML block type %d\n", __FILE__,
- __LINE__, container->as.html_block_type);
- exit(1);
- }
+ break;
+ }
+ }
- } else if (container->type == CMARK_NODE_PARAGRAPH) {
+ *all_matched = true;
- if (parser->blank) {
- all_matched = false;
- }
- }
+done:
+ if (!*all_matched) {
+ container = container->parent; // back up to last matching node
+ }
- if (!all_matched) {
- container = container->parent; // back up to last matching node
- break;
- }
+ if (!should_continue) {
+ container = NULL;
}
- last_matched_container = container;
+ return container;
+}
- // check to see if we've hit 2nd blank line, break out of list:
- if (parser->blank && container->last_line_blank) {
- break_out_of_lists(parser, &container);
- }
+static void open_new_blocks(cmark_parser *parser,
+ cmark_node **container,
+ cmark_chunk *input,
+ bool all_matched)
+{
+ bool indented;
+ cmark_list *data = NULL;
+ bool maybe_lazy = parser->current->type == CMARK_NODE_PARAGRAPH;
+ cmark_node_type cont_type = (*container)->type;
+ bufsize_t matched = 0;
+ int lev = 0;
+ bool save_partially_consumed_tab;
+ int save_offset;
+ int save_column;
- maybe_lazy = parser->current->type == CMARK_NODE_PARAGRAPH;
- // try new container starts:
- while (container->type != CMARK_NODE_CODE_BLOCK &&
- container->type != CMARK_NODE_HTML_BLOCK) {
+ while (cont_type != CMARK_NODE_CODE_BLOCK &&
+ cont_type != CMARK_NODE_HTML_BLOCK) {
- S_find_first_nonspace(parser, &input);
+ S_find_first_nonspace(parser, input);
indented = parser->indent >= CODE_INDENT;
- if (!indented && peek_at(&input, parser->first_nonspace) == '>') {
+ if (!indented && peek_at(input, parser->first_nonspace) == '>') {
- S_advance_offset(parser, &input,
+ S_advance_offset(parser, input,
parser->first_nonspace + 1 - parser->offset, false);
// optional following character
- if (peek_at(&input, parser->offset) == ' ')
- S_advance_offset(parser, &input, 1, false);
- container = add_child(parser, container, CMARK_NODE_BLOCK_QUOTE,
+ if (S_is_space_or_tab(peek_at(input, parser->offset))) {
+ S_advance_offset(parser, input, 1, true);
+ }
+ *container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE,
parser->offset + 1);
} else if (!indented && (matched = scan_atx_heading_start(
- &input, parser->first_nonspace))) {
+ input, parser->first_nonspace))) {
+ bufsize_t hashpos;
+ int level = 0;
- S_advance_offset(parser, &input,
+ S_advance_offset(parser, input,
parser->first_nonspace + matched - parser->offset,
false);
- container =
- add_child(parser, container, CMARK_NODE_HEADING, parser->offset + 1);
+ *container =
+ add_child(parser, *container, CMARK_NODE_HEADING, parser->offset + 1);
- bufsize_t hashpos =
- cmark_chunk_strchr(&input, '#', parser->first_nonspace);
- int level = 0;
+ hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace);
- while (peek_at(&input, hashpos) == '#') {
+ while (peek_at(input, hashpos) == '#') {
level++;
hashpos++;
}
- container->as.heading.level = level;
- container->as.heading.setext = false;
- } else if (!indented && (matched = scan_open_code_fence(
- &input, parser->first_nonspace))) {
+ (*container)->as.heading.level = level;
+ (*container)->as.heading.setext = false;
- container = add_child(parser, container, CMARK_NODE_CODE_BLOCK,
+ } else if (!indented && (matched = scan_open_code_fence(
+ input, parser->first_nonspace))) {
+ *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
parser->first_nonspace + 1);
- container->as.code.fenced = true;
- container->as.code.fence_char = peek_at(&input, parser->first_nonspace);
- container->as.code.fence_length = matched;
- container->as.code.fence_offset =
+ (*container)->as.code.fenced = true;
+ (*container)->as.code.fence_char = peek_at(input, parser->first_nonspace);
+ (*container)->as.code.fence_length = matched;
+ (*container)->as.code.fence_offset =
(int8_t)(parser->first_nonspace - parser->offset);
- container->as.code.info = cmark_chunk_literal("");
- S_advance_offset(parser, &input,
+ (*container)->as.code.info = cmark_chunk_literal("");
+ S_advance_offset(parser, input,
parser->first_nonspace + matched - parser->offset,
false);
} else if (!indented && ((matched = scan_html_block_start(
- &input, parser->first_nonspace)) ||
- (container->type != CMARK_NODE_PARAGRAPH &&
+ input, parser->first_nonspace)) ||
+ (cont_type != CMARK_NODE_PARAGRAPH &&
(matched = scan_html_block_start_7(
- &input, parser->first_nonspace))))) {
-
- container = add_child(parser, container, CMARK_NODE_HTML_BLOCK,
+ input, parser->first_nonspace))))) {
+ *container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK,
parser->first_nonspace + 1);
- container->as.html_block_type = matched;
+ (*container)->as.html_block_type = matched;
// note, we don't adjust parser->offset because the tag is part of the
// text
-
- } else if (!indented && container->type == CMARK_NODE_PARAGRAPH &&
+ } else if (!indented && cont_type == CMARK_NODE_PARAGRAPH &&
(lev =
- scan_setext_heading_line(&input, parser->first_nonspace))) {
-
- container->type = CMARK_NODE_HEADING;
- container->as.heading.level = lev;
- container->as.heading.setext = true;
- S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);
-
+ scan_setext_heading_line(input, parser->first_nonspace))) {
+ (*container)->type = CMARK_NODE_HEADING;
+ (*container)->as.heading.level = lev;
+ (*container)->as.heading.setext = true;
+ S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
} else if (!indented &&
- !(container->type == CMARK_NODE_PARAGRAPH && !all_matched) &&
+ !(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) &&
(matched =
- scan_thematic_break(&input, parser->first_nonspace))) {
-
+ scan_thematic_break(input, parser->first_nonspace))) {
// it's only now that we know the line is not part of a setext heading:
- container = add_child(parser, container, CMARK_NODE_THEMATIC_BREAK,
+ *container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK,
parser->first_nonspace + 1);
- S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);
-
+ S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
} else if ((matched =
- parse_list_marker(&input, parser->first_nonspace, &data)) &&
- (!indented || container->type == CMARK_NODE_LIST)) {
+ parse_list_marker(input, parser->first_nonspace, &data)) &&
+ (!indented || cont_type == CMARK_NODE_LIST)) {
// Note that we can have new list items starting with >= 4
// spaces indent, as long as the list container is still open.
+ int i = 0;
// compute padding:
- S_advance_offset(parser, &input,
+ S_advance_offset(parser, input,
parser->first_nonspace + matched - parser->offset,
false);
- i = 0;
- while (i <= 5 && peek_at(&input, parser->offset + i) == ' ') {
- i++;
- }
- // i = number of spaces after marker, up to 5
- if (i >= 5 || i < 1 ||
- S_is_line_end_char(peek_at(&input, parser->offset))) {
+
+ save_partially_consumed_tab = parser->partially_consumed_tab;
+ save_offset = parser->offset;
+ save_column = parser->column;
+
+ while (parser->column - save_column <= 5 &&
+ S_is_space_or_tab(peek_at(input, parser->offset))) {
+ S_advance_offset(parser, input, 1, true);
+ }
+
+ i = parser->column - save_column;
+ if (i >= 5 || i < 1) {
data->padding = matched + 1;
+ parser->offset = save_offset;
+ parser->column = save_column;
+ parser->partially_consumed_tab = save_partially_consumed_tab;
if (i > 0) {
- S_advance_offset(parser, &input, 1, false);
+ S_advance_offset(parser, input, 1, true);
}
} else {
data->padding = matched + i;
- S_advance_offset(parser, &input, i, true);
}
// check container; if it's a list, see if this list item
@@ -848,50 +962,57 @@
data->marker_offset = parser->indent;
- if (container->type != CMARK_NODE_LIST ||
- !lists_match(&container->as.list, data)) {
- container = add_child(parser, container, CMARK_NODE_LIST,
+ if (cont_type != CMARK_NODE_LIST ||
+ !lists_match(&((*container)->as.list), data)) {
+ *container = add_child(parser, *container, CMARK_NODE_LIST,
parser->first_nonspace + 1);
- memcpy(&container->as.list, data, sizeof(*data));
+ memcpy(&((*container)->as.list), data, sizeof(*data));
}
// add the list item
- container = add_child(parser, container, CMARK_NODE_ITEM,
+ *container = add_child(parser, *container, CMARK_NODE_ITEM,
parser->first_nonspace + 1);
/* TODO: static */
- memcpy(&container->as.list, data, sizeof(*data));
+ memcpy(&((*container)->as.list), data, sizeof(*data));
free(data);
-
} else if (indented && !maybe_lazy && !parser->blank) {
- S_advance_offset(parser, &input, CODE_INDENT, true);
- container = add_child(parser, container, CMARK_NODE_CODE_BLOCK,
+ S_advance_offset(parser, input, CODE_INDENT, true);
+ *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
parser->offset + 1);
- container->as.code.fenced = false;
- container->as.code.fence_char = 0;
- container->as.code.fence_length = 0;
- container->as.code.fence_offset = 0;
- container->as.code.info = cmark_chunk_literal("");
+ (*container)->as.code.fenced = false;
+ (*container)->as.code.fence_char = 0;
+ (*container)->as.code.fence_length = 0;
+ (*container)->as.code.fence_offset = 0;
+ (*container)->as.code.info = cmark_chunk_literal("");
} else {
break;
}
- if (accepts_lines(container->type)) {
+ if (accepts_lines((*container)->type)) {
// if it's a line container, it can't contain other containers
break;
}
+
+ cont_type = (*container)->type;
maybe_lazy = false;
}
+}
+static void add_text_to_container (cmark_parser *parser,
+ cmark_node *container,
+ cmark_node *last_matched_container,
+ cmark_chunk *input)
+{
+ cmark_node *tmp;
// what remains at parser->offset is a text line. add the text to the
// appropriate container.
- S_find_first_nonspace(parser, &input);
+ S_find_first_nonspace(parser, input);
- if (parser->blank && container->last_child) {
+ if (parser->blank && container->last_child)
container->last_child->last_line_blank = true;
- }
// block quote lines are never blank as they start with >
// and we don't count blanks in fenced code for purposes of tight/loose
@@ -906,61 +1027,61 @@
!(container->type == CMARK_NODE_ITEM && container->first_child == NULL &&
container->start_line == parser->line_number));
- cmark_node *cont = container;
- while (cont->parent) {
- cont->parent->last_line_blank = false;
- cont = cont->parent;
+ tmp = container;
+ while (tmp->parent) {
+ tmp->parent->last_line_blank = false;
+ tmp = tmp->parent;
}
+ // If the last line processed belonged to a paragraph node,
+ // and we didn't match all of the line prefixes for the open containers,
+ // and we didn't start any new containers,
+ // and the line isn't blank,
+ // then treat this as a "lazy continuation line" and add it to
+ // the open paragraph.
if (parser->current != last_matched_container &&
- container == last_matched_container && !parser->blank &&
- parser->current->type == CMARK_NODE_PARAGRAPH &&
- cmark_strbuf_len(&parser->current->string_content) > 0) {
-
- add_line(parser->current, &input, parser->offset);
-
+ container == last_matched_container &&
+ !parser->blank &&
+ parser->current->type == CMARK_NODE_PARAGRAPH) {
+ add_line(parser->current, input, parser);
} else { // not a lazy continuation
-
- // finalize any blocks that were not matched and set cur to container:
+ // Finalize any blocks that were not matched and set cur to container:
while (parser->current != last_matched_container) {
parser->current = finalize(parser, parser->current);
assert(parser->current != NULL);
}
if (container->type == CMARK_NODE_CODE_BLOCK) {
-
- add_line(container, &input, parser->offset);
-
+ add_line(container, input, parser);
} else if (container->type == CMARK_NODE_HTML_BLOCK) {
-
- add_line(container, &input, parser->offset);
+ add_line(container, input, parser);
int matches_end_condition;
switch (container->as.html_block_type) {
case 1:
// </script>, </style>, </pre>
matches_end_condition =
- scan_html_block_end_1(&input, parser->first_nonspace);
+ scan_html_block_end_1(input, parser->first_nonspace);
break;
case 2:
// -->
matches_end_condition =
- scan_html_block_end_2(&input, parser->first_nonspace);
+ scan_html_block_end_2(input, parser->first_nonspace);
break;
case 3:
// ?>
matches_end_condition =
- scan_html_block_end_3(&input, parser->first_nonspace);
+ scan_html_block_end_3(input, parser->first_nonspace);
break;
case 4:
// >
matches_end_condition =
- scan_html_block_end_4(&input, parser->first_nonspace);
+ scan_html_block_end_4(input, parser->first_nonspace);
break;
case 5:
// ]]>
matches_end_condition =
- scan_html_block_end_5(&input, parser->first_nonspace);
+ scan_html_block_end_5(input, parser->first_nonspace);
break;
default:
matches_end_condition = 0;
@@ -971,28 +1092,69 @@
container = finalize(parser, container);
assert(parser->current != NULL);
}
-
} else if (parser->blank) {
-
// ??? do nothing
-
} else if (accepts_lines(container->type)) {
-
if (container->type == CMARK_NODE_HEADING &&
container->as.heading.setext == false) {
- chop_trailing_hashtags(&input);
+ chop_trailing_hashtags(input);
}
- add_line(container, &input, parser->first_nonspace);
-
+ S_advance_offset(parser, input, parser->first_nonspace - parser->offset, false);
+ add_line(container, input, parser);
} else {
// create paragraph container for line
container = add_child(parser, container, CMARK_NODE_PARAGRAPH,
parser->first_nonspace + 1);
- add_line(container, &input, parser->first_nonspace);
+ S_advance_offset(parser, input, parser->first_nonspace - parser->offset, false);
+ add_line(container, input, parser);
}
parser->current = container;
}
+}
+
+/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */
+static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
+ bufsize_t bytes) {
+ cmark_node *last_matched_container;
+ bool all_matched = true;
+ cmark_node *container;
+ cmark_chunk input;
+
+ if (parser->options & CMARK_OPT_VALIDATE_UTF8)
+ cmark_utf8proc_check(parser->curline, buffer, bytes);
+ else
+ cmark_strbuf_put(parser->curline, buffer, bytes);
+
+ // ensure line ends with a newline:
+ if (bytes == 0 || !S_is_line_end_char(parser->curline->ptr[bytes - 1]))
+ cmark_strbuf_putc(parser->curline, '\n');
+
+ parser->offset = 0;
+ parser->column = 0;
+ parser->blank = false;
+ parser->partially_consumed_tab = false;
+
+ input.data = parser->curline->ptr;
+ input.len = parser->curline->size;
+
+ parser->line_number++;
+
+ last_matched_container = check_open_blocks(parser, &input, &all_matched);
+
+ if (!last_matched_container)
+ goto finished;
+
+ container = last_matched_container;
+
+ // check to see if we've hit 2nd blank line, break out of list:
+ if (parser->blank && container->last_line_blank)
+ break_out_of_lists(parser, &container);
+
+ open_new_blocks(parser, &container, &input, all_matched);
+
+ add_text_to_container(parser, container, last_matched_container, &input);
+
finished:
parser->last_line_length = input.len;
if (parser->last_line_length &&
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/buffer.c new/cmark-0.5.2/cbits/buffer.c
--- old/cmark-0.5.1/cbits/buffer.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/buffer.c 2016-03-26 21:36:02.000000000 +0100
@@ -33,7 +33,7 @@
abort();
}
-static inline void S_strbuf_grow_by(cmark_strbuf *buf, size_t add) {
+static CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, size_t add) {
size_t target_size = (size_t)buf->size + add;
if (target_size < add /* Integer overflow. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/cmark.h new/cmark-0.5.2/cbits/cmark.h
--- old/cmark-0.5.1/cbits/cmark.h 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/cmark.h 2016-03-26 21:36:02.000000000 +0100
@@ -20,7 +20,7 @@
*/
/** Convert 'text' (assumed to be a UTF-8 encoded string with length
- * 'len' from CommonMark Markdown to HTML, returning a null-terminated,
+ * 'len') from CommonMark Markdown to HTML, returning a null-terminated,
* UTF-8-encoded string.
*/
CMARK_EXPORT
@@ -96,7 +96,7 @@
*/
CMARK_EXPORT cmark_node *cmark_node_new(cmark_node_type type);
-/** Frees the memory allocated for a node.
+/** Frees the memory allocated for a node and any children.
*/
CMARK_EXPORT void cmark_node_free(cmark_node *node);
@@ -418,7 +418,7 @@
* Streaming interface:
*
* cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT);
- * FILE *fp = fopen("myfile.md", "r");
+ * 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)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/cmark_version.h new/cmark-0.5.2/cbits/cmark_version.h
--- old/cmark-0.5.1/cbits/cmark_version.h 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/cmark_version.h 2016-03-26 21:36:02.000000000 +0100
@@ -1,7 +1,7 @@
#ifndef CMARK_VERSION_H
#define CMARK_VERSION_H
-#define CMARK_VERSION ((0 << 16) | (23 << 8) | 0)
-#define CMARK_VERSION_STRING "0.23.0"
+#define CMARK_VERSION ((0 << 16) | (25 << 8) | 2)
+#define CMARK_VERSION_STRING "0.25.2"
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/commonmark.c new/cmark-0.5.2/cbits/commonmark.c
--- old/cmark-0.5.1/cbits/commonmark.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/commonmark.c 2016-03-26 21:36:02.000000000 +0100
@@ -17,16 +17,17 @@
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
#define CR() renderer->cr(renderer)
#define BLANKLINE() renderer->blankline(renderer)
+#define ENCODED_SIZE 20
+#define LISTMARKER_SIZE 20
// Functions to convert cmark_nodes to commonmark strings.
-static inline void outc(cmark_renderer *renderer, cmark_escaping escape,
+static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
bool needs_escaping = false;
bool follows_digit =
renderer->buffer->size > 0 &&
cmark_isdigit(renderer->buffer->ptr[renderer->buffer->size - 1]);
- const size_t ENCODED_SIZE = 20;
char encoded[ENCODED_SIZE];
needs_escaping =
@@ -168,7 +169,6 @@
bool entering = (ev_type == CMARK_EVENT_ENTER);
const char *info, *code, *title;
size_t info_len, code_len;
- const size_t LISTMARKER_SIZE = 20;
char listmarker[LISTMARKER_SIZE];
char *emph_delim;
bufsize_t marker_width;
@@ -273,8 +273,8 @@
// begin or end with a blank line, and code isn't
// first thing in a list item
if (info_len == 0 &&
- (code_len > 2 && !isspace(code[0]) &&
- !(isspace(code[code_len - 1]) && isspace(code[code_len - 2]))) &&
+ (code_len > 2 && !isspace((unsigned char)code[0]) &&
+ !(isspace((unsigned char)code[code_len - 1]) && isspace((unsigned char)code[code_len - 2]))) &&
!(node->prev == NULL && node->parent &&
node->parent->type == CMARK_NODE_ITEM)) {
LIT(" ");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/config.h new/cmark-0.5.2/cbits/config.h
--- old/cmark-0.5.1/cbits/config.h 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/config.h 2016-03-26 21:36:02.000000000 +0100
@@ -1,3 +1,10 @@
+#ifndef CMARK_CONFIG_H
+#define CMARK_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define HAVE_STDBOOL_H
#ifdef HAVE_STDBOOL_H
@@ -23,3 +30,47 @@
#define CMARK_INLINE inline
#endif
#endif
+
+/* snprintf and vsnprintf fallbacks for MSVC before 2015,
+ due to Valentin Milea http://stackoverflow.com/questions/2915672/
+*/
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
+#include
+#include
+
+#define snprintf c99_snprintf
+#define vsnprintf c99_vsnprintf
+
+CMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
+{
+ int count = -1;
+
+ if (size != 0)
+ count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
+ if (count == -1)
+ count = _vscprintf(format, ap);
+
+ return count;
+}
+
+CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, format);
+ count = c99_vsnprintf(outBuf, size, format, ap);
+ va_end(ap);
+
+ return count;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/html.c new/cmark-0.5.2/cbits/html.c
--- old/cmark-0.5.1/cbits/html.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/html.c 2016-03-26 21:36:02.000000000 +0100
@@ -10,6 +10,8 @@
#include "houdini.h"
#include "scanners.h"
+#define BUFFER_SIZE 100
+
// Functions to convert cmark_nodes to HTML strings.
static void escape_html(cmark_strbuf *dest, const unsigned char *source,
@@ -17,7 +19,7 @@
houdini_escape_html0(dest, source, length, 0);
}
-static inline void cr(cmark_strbuf *html) {
+static CMARK_INLINE void cr(cmark_strbuf *html) {
if (html->size && html->ptr[html->size - 1] != '\n')
cmark_strbuf_putc(html, '\n');
}
@@ -29,7 +31,6 @@
static void S_render_sourcepos(cmark_node *node, cmark_strbuf *html,
int options) {
- const size_t BUFFER_SIZE = 100;
char buffer[BUFFER_SIZE];
if (CMARK_OPT_SOURCEPOS & options) {
snprintf(buffer, BUFFER_SIZE, " data-sourcepos=\"%d:%d-%d:%d\"",
@@ -47,7 +48,6 @@
char start_heading[] = "type = t;
@@ -81,7 +81,7 @@
}
// Create an inline with no value.
-static inline cmark_node *make_simple(cmark_node_type t) {
+static CMARK_INLINE cmark_node *make_simple(cmark_node_type t) {
cmark_node *e = (cmark_node *)calloc(1, sizeof(*e));
if (e != NULL) {
e->type = t;
@@ -141,7 +141,7 @@
return cmark_chunk_buf_detach(&buf);
}
-static inline cmark_node *make_autolink(cmark_chunk url, int is_email) {
+static CMARK_INLINE cmark_node *make_autolink(cmark_chunk url, int is_email) {
cmark_node *link = make_simple(CMARK_NODE_LINK);
link->as.link.url = cmark_clean_autolink(&url, is_email);
link->as.link.title = cmark_chunk_literal("");
@@ -159,28 +159,28 @@
e->last_delim = NULL;
}
-static inline int isbacktick(int c) { return (c == '`'); }
+static CMARK_INLINE int isbacktick(int c) { return (c == '`'); }
-static inline unsigned char peek_char(subject *subj) {
+static CMARK_INLINE unsigned char peek_char(subject *subj) {
// NULL bytes should have been stripped out by now. If they're
// present, it's a programming error:
assert(!(subj->pos < subj->input.len && subj->input.data[subj->pos] == 0));
return (subj->pos < subj->input.len) ? subj->input.data[subj->pos] : 0;
}
-static inline unsigned char peek_at(subject *subj, bufsize_t pos) {
+static CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) {
return subj->input.data[pos];
}
// Return true if there are more characters in the subject.
-static inline int is_eof(subject *subj) {
+static CMARK_INLINE int is_eof(subject *subj) {
return (subj->pos >= subj->input.len);
}
// Advance the subject. Doesn't check for eof.
#define advance(subj) (subj)->pos += 1
-static inline bool skip_spaces(subject *subj) {
+static CMARK_INLINE bool skip_spaces(subject *subj) {
bool skipped = false;
while (peek_char(subj) == ' ' || peek_char(subj) == '\t') {
advance(subj);
@@ -189,7 +189,7 @@
return skipped;
}
-static inline bool skip_line_end(subject *subj) {
+static CMARK_INLINE bool skip_line_end(subject *subj) {
bool seen_line_end_char = false;
if (peek_char(subj) == '\r') {
advance(subj);
@@ -203,7 +203,7 @@
}
// Take characters while a predicate holds, and return a string.
-static inline cmark_chunk take_while(subject *subj, int (*f)(int)) {
+static CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) {
unsigned char c;
bufsize_t startpos = subj->pos;
bufsize_t len = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/latex.c new/cmark-0.5.2/cbits/latex.c
--- old/cmark-0.5.1/cbits/latex.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/latex.c 2016-03-26 21:36:02.000000000 +0100
@@ -17,8 +17,9 @@
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
#define CR() renderer->cr(renderer)
#define BLANKLINE() renderer->blankline(renderer)
+#define LIST_NUMBER_STRING_SIZE 20
-static inline void outc(cmark_renderer *renderer, cmark_escaping escape,
+static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
if (escape == LITERAL) {
cmark_render_code_point(renderer, c);
@@ -217,7 +218,6 @@
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
int list_number;
- const size_t LIST_NUMBER_STRING_SIZE = 20;
char list_number_string[LIST_NUMBER_STRING_SIZE];
bool entering = (ev_type == CMARK_EVENT_ENTER);
cmark_list_type list_type;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/man.c new/cmark-0.5.2/cbits/man.c
--- old/cmark-0.5.1/cbits/man.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/man.c 2016-03-26 21:36:02.000000000 +0100
@@ -14,6 +14,7 @@
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
#define CR() renderer->cr(renderer)
#define BLANKLINE() renderer->blankline(renderer)
+#define LIST_NUMBER_SIZE 20
// Functions to convert cmark_nodes to groff man strings.
static void S_outc(cmark_renderer *renderer, cmark_escaping escape, int32_t c,
@@ -110,7 +111,6 @@
tmp = tmp->prev;
list_number += 1;
}
- const size_t LIST_NUMBER_SIZE = 20;
char list_number_s[LIST_NUMBER_SIZE];
snprintf(list_number_s, LIST_NUMBER_SIZE, "\"%d.\" 4", list_number);
LIT(list_number_s);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/node.c new/cmark-0.5.2/cbits/node.c
--- old/cmark-0.5.1/cbits/node.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/node.c 2016-03-26 21:36:02.000000000 +0100
@@ -6,7 +6,7 @@
static void S_node_unlink(cmark_node *node);
-static inline bool S_is_block(cmark_node *node) {
+static CMARK_INLINE bool S_is_block(cmark_node *node) {
if (node == NULL) {
return false;
}
@@ -14,7 +14,7 @@
node->type <= CMARK_NODE_LAST_BLOCK;
}
-static inline bool S_is_inline(cmark_node *node) {
+static CMARK_INLINE bool S_is_inline(cmark_node *node) {
if (node == NULL) {
return false;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/parser.h new/cmark-0.5.2/cbits/parser.h
--- old/cmark-0.5.1/cbits/parser.h 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/parser.h 2016-03-26 21:36:02.000000000 +0100
@@ -22,10 +22,12 @@
bufsize_t first_nonspace_column;
int indent;
bool blank;
+ bool partially_consumed_tab;
cmark_strbuf *curline;
bufsize_t last_line_length;
cmark_strbuf *linebuf;
int options;
+ bool last_buffer_ended_with_cr;
};
#ifdef __cplusplus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/render.c new/cmark-0.5.2/cbits/render.c
--- old/cmark-0.5.1/cbits/render.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/render.c 2016-03-26 21:36:02.000000000 +0100
@@ -5,13 +5,13 @@
#include "utf8.h"
#include "render.h"
-static inline void S_cr(cmark_renderer *renderer) {
+static CMARK_INLINE void S_cr(cmark_renderer *renderer) {
if (renderer->need_cr < 1) {
renderer->need_cr = 1;
}
}
-static inline void S_blankline(cmark_renderer *renderer) {
+static CMARK_INLINE void S_blankline(cmark_renderer *renderer) {
if (renderer->need_cr < 2) {
renderer->need_cr = 2;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cbits/xml.c new/cmark-0.5.2/cbits/xml.c
--- old/cmark-0.5.1/cbits/xml.c 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cbits/xml.c 2016-03-26 21:36:02.000000000 +0100
@@ -9,6 +9,8 @@
#include "buffer.h"
#include "houdini.h"
+#define BUFFER_SIZE 100
+
// Functions to convert cmark_nodes to XML strings.
static void escape_xml(cmark_strbuf *dest, const unsigned char *source,
@@ -21,7 +23,7 @@
int indent;
};
-static inline void indent(struct render_state *state) {
+static CMARK_INLINE void indent(struct render_state *state) {
int i;
for (i = 0; i < state->indent; i++) {
cmark_strbuf_putc(state->xml, ' ');
@@ -34,7 +36,6 @@
bool literal = false;
cmark_delim_type delim;
bool entering = (ev_type == CMARK_EVENT_ENTER);
- const size_t BUFFER_SIZE = 100;
char buffer[BUFFER_SIZE];
if (entering) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/changelog new/cmark-0.5.2/changelog
--- old/cmark-0.5.1/changelog 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/changelog 2016-03-26 21:36:02.000000000 +0100
@@ -1,3 +1,8 @@
+cmark 0.5.2 (26 Mar 2016)
+
+ * Add flag to allow building with an installed libcmark (Jens Petersen).
+ * Updated to libcmark 0.25.2.
+
cmark 0.5.1 (21 Jan 2016)
* Updated to libcmark 0.24.1.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cmark-0.5.1/cmark.cabal new/cmark-0.5.2/cmark.cabal
--- old/cmark-0.5.1/cmark.cabal 2016-01-23 06:14:38.000000000 +0100
+++ new/cmark-0.5.2/cmark.cabal 2016-03-26 21:36:02.000000000 +0100
@@ -1,12 +1,12 @@
name: cmark
-version: 0.5.1
+version: 0.5.2
synopsis: Fast, accurate CommonMark (Markdown) parser and renderer
description:
This package provides Haskell bindings for
<https://github.com/jgm/cmark libcmark>, the reference
parser for <http://commonmark.org CommonMark>, a fully
specified variant of Markdown. It includes sources for
- libcmark (0.24.1) and does not require prior installation of the
+ libcmark (0.25.2) and does not require prior installation of the
C library.
homepage: https://github.com/jgm/commonmark-hs
@@ -16,7 +16,7 @@
maintainer: jgm@berkeley.edu
copyright: (C) 2015 John MacFarlane
category: Text
-tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.2
+tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.2, GHC == 7.10.3
build-type: Simple
extra-source-files: README.md
changelog
@@ -48,6 +48,10 @@
type: git
location: git://github.com/jgm/cmark-hs.git
+flag pkgconfig
+ default: False
+ description: Use system libcmark via pkgconfig
+
library
exposed-modules: CMark
build-depends: base >=4.5 && < 4.9,
@@ -57,10 +61,13 @@
build-depends: ghc-prim >= 0.2
default-language: Haskell2010
ghc-options: -Wall -fno-warn-unused-do-bind
- cc-options: -Wall -std=c99
- Include-dirs: cbits
- Includes: cmark.h
- c-sources: cbits/houdini_html_u.c
+ if flag(pkgconfig)
+ pkgconfig-depends: libcmark
+ else
+ cc-options: -Wall -std=c99
+ Include-dirs: cbits
+ Includes: cmark.h
+ c-sources: cbits/houdini_html_u.c
cbits/references.c
cbits/utf8.c
cbits/inlines.c