Skip to content

Commit 763587e

Browse files
Fix quadratic performance issue in list numbering.
1 parent f7e31f8 commit 763587e

File tree

5 files changed

+9
-20
lines changed

5 files changed

+9
-20
lines changed

src/commonmark.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,19 +231,15 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
231231
LIT("<!-- end list -->");
232232
BLANKLINE();
233233
}
234+
renderer->list_number = cmark_node_get_list_start(node);
234235
break;
235236

236237
case CMARK_NODE_ITEM:
237238
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
238239
marker_width = 4;
239240
} else {
240-
list_number = cmark_node_get_list_start(node->parent);
241+
list_number = renderer->list_number++;
241242
list_delim = cmark_node_get_list_delim(node->parent);
242-
tmp = node;
243-
while (tmp->prev) {
244-
tmp = tmp->prev;
245-
list_number += 1;
246-
}
247243
// we ensure a width of at least 4 so
248244
// we get nice transition from single digits
249245
// to double

src/man.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
114114
break;
115115

116116
case CMARK_NODE_LIST:
117+
renderer->list_number = cmark_node_get_list_start(node);
117118
break;
118119

119120
case CMARK_NODE_ITEM:
@@ -123,12 +124,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
123124
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
124125
LIT("\\[bu] 2");
125126
} else {
126-
list_number = cmark_node_get_list_start(node->parent);
127-
tmp = node;
128-
while (tmp->prev) {
129-
tmp = tmp->prev;
130-
list_number += 1;
131-
}
127+
list_number = renderer->list_number++;
132128
char list_number_s[LIST_NUMBER_SIZE];
133129
snprintf(list_number_s, LIST_NUMBER_SIZE, "\"%d.\" 4", list_number);
134130
LIT(list_number_s);

src/plaintext.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,15 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
7676
node->next->type == CMARK_NODE_LIST)) {
7777
CR();
7878
}
79+
renderer->list_number = cmark_node_get_list_start(node);
7980
break;
8081

8182
case CMARK_NODE_ITEM:
8283
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
8384
marker_width = 4;
8485
} else {
85-
list_number = cmark_node_get_list_start(node->parent);
86+
list_number = renderer->list_number++;
8687
list_delim = cmark_node_get_list_delim(node->parent);
87-
tmp = node;
88-
while (tmp->prev) {
89-
tmp = tmp->prev;
90-
list_number += 1;
91-
}
9288
// we ensure a width of at least 4 so
9389
// we get nice transition from single digits
9490
// to double

src/render.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
177177

178178
cmark_renderer renderer = {mem, &buf, &pref, 0, width,
179179
0, 0, true, true, false,
180-
false, outc, S_cr, S_blankline, S_out,
181-
0};
180+
false, 0, outc, S_cr, S_blankline,
181+
S_out, 0};
182182

183183
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
184184
cur = cmark_iter_get_node(iter);

src/render.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct cmark_renderer {
2323
bool begin_content;
2424
bool no_linebreaks;
2525
bool in_tight_list_item;
26+
int list_number;
2627
void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);
2728
void (*cr)(struct cmark_renderer *);
2829
void (*blankline)(struct cmark_renderer *);

0 commit comments

Comments
 (0)