Skip to content

Commit

Permalink
Merge pull request #236 from anticomputer/update-to-0.29.0.gfm.10
Browse files Browse the repository at this point in the history
Release 0.23.9 --> update to 0.29.0.gfm.11
  • Loading branch information
phillmv authored Apr 11, 2023
2 parents 94c0af9 + d793fbf commit 42cfc90
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 111 deletions.
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,3 @@ ext/commonmarker/cmark-gfm_export.h: ext/commonmarker/cmark-upstream/build/src/c

ext/commonmarker/cmark-gfm_version.h: ext/commonmarker/cmark-upstream/build/src/cmark-gfm_version.h
cp $< $@

ext/commonmarker/cmark-gfm-extensions_export.h: ext/commonmarker/cmark-upstream/build/extensions/cmark-gfm-extensions_export.h
cp $< $@
12 changes: 11 additions & 1 deletion ext/commonmarker/blocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
#define CODE_INDENT 4
#define TAB_STOP 4

/**
* Very deeply nested lists can cause quadratic performance issues.
* This constant is used in open_new_blocks() to limit the nesting
* depth. It is unlikely that a non-contrived markdown document will
* be nested this deeply.
*/
#define MAX_LIST_DEPTH 100

#ifndef MIN
#define MIN(x, y) ((x < y) ? x : y)
#endif
Expand Down Expand Up @@ -1119,10 +1127,11 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
bool has_content;
int save_offset;
int save_column;
size_t depth = 0;

while (cont_type != CMARK_NODE_CODE_BLOCK &&
cont_type != CMARK_NODE_HTML_BLOCK) {

depth++;
S_find_first_nonspace(parser, input);
indented = parser->indent >= CODE_INDENT;

Expand Down Expand Up @@ -1224,6 +1233,7 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
(*container)->internal_offset = matched;
} else if ((!indented || cont_type == CMARK_NODE_LIST) &&
parser->indent < 4 &&
depth < MAX_LIST_DEPTH &&
(matched = parse_list_marker(
parser->mem, input, parser->first_nonspace,
(*container)->type == CMARK_NODE_PARAGRAPH, &data))) {
Expand Down
11 changes: 11 additions & 0 deletions ext/commonmarker/cmark-gfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,17 @@ CMARK_GFM_EXPORT int cmark_node_get_list_tight(cmark_node *node);
*/
CMARK_GFM_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight);

/**
* Returns item index of 'node'. This is only used when rendering output
* formats such as commonmark, which need to output the index. It is not
* required for formats such as html or latex.
*/
CMARK_GFM_EXPORT int cmark_node_get_item_index(cmark_node *node);

/** Sets item index of 'node'. Returns 1 on success, 0 on failure.
*/
CMARK_GFM_EXPORT int cmark_node_set_item_index(cmark_node *node, int idx);

/** Returns the info string from a fenced code block.
*/
CMARK_GFM_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);
Expand Down
4 changes: 2 additions & 2 deletions ext/commonmarker/cmark-gfm_version.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef CMARK_GFM_VERSION_H
#define CMARK_GFM_VERSION_H

#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 6)
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.6"
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 11)
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.11"

#endif
51 changes: 18 additions & 33 deletions ext/commonmarker/commonmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,23 +153,8 @@ static bool is_autolink(cmark_node *node) {
link_text->as.literal.len) == 0);
}

// if node is a block node, returns node.
// otherwise returns first block-level node that is an ancestor of node.
// if there is no block-level ancestor, returns NULL.
static cmark_node *get_containing_block(cmark_node *node) {
while (node) {
if (CMARK_NODE_BLOCK_P(node)) {
return node;
} else {
node = node->parent;
}
}
return NULL;
}

static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
cmark_node *tmp;
int list_number;
cmark_delim_type list_delim;
int numticks;
Expand All @@ -189,14 +174,17 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
// Don't adjust tight list status til we've started the list.
// Otherwise we loose the blank line between a paragraph and
// a following list.
if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && entering)) {
tmp = get_containing_block(node);
renderer->in_tight_list_item =
tmp && // tmp might be NULL if there is no containing block
((tmp->type == CMARK_NODE_ITEM &&
cmark_node_get_list_tight(tmp->parent)) ||
(tmp && tmp->parent && tmp->parent->type == CMARK_NODE_ITEM &&
cmark_node_get_list_tight(tmp->parent->parent)));
if (entering) {
if (node->parent && node->parent->type == CMARK_NODE_ITEM) {
renderer->in_tight_list_item = node->parent->parent->as.list.tight;
}
} else {
if (node->type == CMARK_NODE_LIST) {
renderer->in_tight_list_item =
node->parent &&
node->parent->type == CMARK_NODE_ITEM &&
node->parent->parent->as.list.tight;
}
}

if (node->extension && node->extension->commonmark_render_func) {
Expand Down Expand Up @@ -234,13 +222,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
marker_width = 4;
} else {
list_number = cmark_node_get_list_start(node->parent);
list_number = cmark_node_get_item_index(node);
list_delim = cmark_node_get_list_delim(node->parent);
tmp = node;
while (tmp->prev) {
tmp = tmp->prev;
list_number += 1;
}
// we ensure a width of at least 4 so
// we get nice transition from single digits
// to double
Expand Down Expand Up @@ -405,10 +388,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_STRONG:
if (entering) {
LIT("**");
} else {
LIT("**");
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
if (entering) {
LIT("**");
} else {
LIT("**");
}
}
break;

Expand Down
10 changes: 6 additions & 4 deletions ext/commonmarker/html.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,12 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_STRONG:
if (entering) {
cmark_strbuf_puts(html, "<strong>");
} else {
cmark_strbuf_puts(html, "</strong>");
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
if (entering) {
cmark_strbuf_puts(html, "<strong>");
} else {
cmark_strbuf_puts(html, "</strong>");
}
}
break;

Expand Down
10 changes: 6 additions & 4 deletions ext/commonmarker/latex.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_STRONG:
if (entering) {
LIT("\\textbf{");
} else {
LIT("}");
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
if (entering) {
LIT("\\textbf{");
} else {
LIT("}");
}
}
break;

Expand Down
18 changes: 7 additions & 11 deletions ext/commonmarker/man.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ static void S_outc(cmark_renderer *renderer, cmark_node *node,

static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
cmark_node *tmp;
int list_number;
bool entering = (ev_type == CMARK_EVENT_ENTER);
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
Expand Down Expand Up @@ -123,12 +122,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
LIT("\\[bu] 2");
} else {
list_number = cmark_node_get_list_start(node->parent);
tmp = node;
while (tmp->prev) {
tmp = tmp->prev;
list_number += 1;
}
list_number = cmark_node_get_item_index(node);
char list_number_s[LIST_NUMBER_SIZE];
snprintf(list_number_s, LIST_NUMBER_SIZE, "\"%d.\" 4", list_number);
LIT(list_number_s);
Expand Down Expand Up @@ -225,10 +219,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_STRONG:
if (entering) {
LIT("\\f[B]");
} else {
LIT("\\f[]");
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
if (entering) {
LIT("\\f[B]");
} else {
LIT("\\f[]");
}
}
break;

Expand Down
57 changes: 46 additions & 11 deletions ext/commonmarker/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
#include "node.h"
#include "syntax_extension.h"

/**
* Expensive safety checks are off by default, but can be enabled
* by calling cmark_enable_safety_checks().
*/
static bool enable_safety_checks = false;

void cmark_enable_safety_checks(bool enable) {
enable_safety_checks = enable;
}

static void S_node_unlink(cmark_node *node);

#define NODE_MEM(node) cmark_node_mem(node)
Expand All @@ -29,7 +39,7 @@ void cmark_register_node_flag(cmark_node_internal_flags *flags) {
nextflag <<= 1;
}

void cmark_init_standard_node_flags() {}
void cmark_init_standard_node_flags(void) {}

bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
if (child_type == CMARK_NODE_DOCUMENT) {
Expand Down Expand Up @@ -70,23 +80,23 @@ bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
}

static bool S_can_contain(cmark_node *node, cmark_node *child) {
cmark_node *cur;

if (node == NULL || child == NULL) {
return false;
}
if (NODE_MEM(node) != NODE_MEM(child)) {
return 0;
}

// Verify that child is not an ancestor of node or equal to node.
cur = node;
do {
if (cur == child) {
return false;
}
cur = cur->parent;
} while (cur != NULL);
if (enable_safety_checks) {
// Verify that child is not an ancestor of node or equal to node.
cmark_node *cur = node;
do {
if (cur == child) {
return false;
}
cur = cur->parent;
} while (cur != NULL);
}

return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
}
Expand Down Expand Up @@ -554,6 +564,31 @@ int cmark_node_set_list_tight(cmark_node *node, int tight) {
}
}

int cmark_node_get_item_index(cmark_node *node) {
if (node == NULL) {
return 0;
}

if (node->type == CMARK_NODE_ITEM) {
return node->as.list.start;
} else {
return 0;
}
}

int cmark_node_set_item_index(cmark_node *node, int idx) {
if (node == NULL || idx < 0) {
return 0;
}

if (node->type == CMARK_NODE_ITEM) {
node->as.list.start = idx;
return 1;
} else {
return 0;
}
}

const char *cmark_node_get_fence_info(cmark_node *node) {
if (node == NULL) {
return NULL;
Expand Down
17 changes: 16 additions & 1 deletion ext/commonmarker/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ struct cmark_node {

cmark_syntax_extension *extension;

/**
* Used during cmark_render() to cache the most recent non-NULL
* extension, if you go up the parent chain like this:
*
* node->parent->...parent->extension
*/
cmark_syntax_extension *ancestor_extension;

union {
int ref_ix;
int def_count;
Expand Down Expand Up @@ -119,7 +127,7 @@ void cmark_register_node_flag(cmark_node_internal_flags *flags);
* library. It is now a no-op.
*/
CMARK_GFM_EXPORT
void cmark_init_standard_node_flags();
void cmark_init_standard_node_flags(void);

static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
return node->content.mem;
Expand All @@ -144,6 +152,13 @@ static CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {

CMARK_GFM_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);

/**
* Enable (or disable) extra safety checks. These extra checks cause
* extra performance overhead (in some cases quadratic), so they are only
* intended to be used during testing.
*/
CMARK_GFM_EXPORT void cmark_enable_safety_checks(bool enable);

#ifdef __cplusplus
}
#endif
Expand Down
Loading

0 comments on commit 42cfc90

Please sign in to comment.