@@ -34,6 +34,10 @@ static bool S_last_line_blank(const cmark_node *node) {
34
34
return (node -> flags & CMARK_NODE__LAST_LINE_BLANK ) != 0 ;
35
35
}
36
36
37
+ static bool S_last_line_checked (const cmark_node * node ) {
38
+ return (node -> flags & CMARK_NODE__LAST_LINE_CHECKED ) != 0 ;
39
+ }
40
+
37
41
static CMARK_INLINE cmark_node_type S_type (const cmark_node * node ) {
38
42
return (cmark_node_type )node -> type ;
39
43
}
@@ -45,6 +49,10 @@ static void S_set_last_line_blank(cmark_node *node, bool is_blank) {
45
49
node -> flags &= ~CMARK_NODE__LAST_LINE_BLANK ;
46
50
}
47
51
52
+ static void S_set_last_line_checked (cmark_node * node ) {
53
+ node -> flags |= CMARK_NODE__LAST_LINE_CHECKED ;
54
+ }
55
+
48
56
static CMARK_INLINE bool S_is_line_end_char (char c ) {
49
57
return (c == '\n' || c == '\r' );
50
58
}
@@ -208,20 +216,16 @@ static void remove_trailing_blank_lines(cmark_strbuf *ln) {
208
216
// Check to see if a node ends with a blank line, descending
209
217
// if needed into lists and sublists.
210
218
static bool ends_with_blank_line (cmark_node * node ) {
211
- cmark_node * cur = node ;
212
- while (cur != NULL ) {
213
- if (S_last_line_blank (cur )) {
214
- S_set_last_line_blank (node , true);
215
- return true;
216
- }
217
- if (S_type (cur ) == CMARK_NODE_LIST || S_type (cur ) == CMARK_NODE_ITEM ) {
218
- cur = cur -> last_child ;
219
- } else {
220
- cur = NULL ;
221
- }
219
+ if (S_last_line_checked (node )) {
220
+ return (S_last_line_blank (node ));
221
+ } else if ((S_type (node ) == CMARK_NODE_LIST ||
222
+ S_type (node ) == CMARK_NODE_ITEM ) && node -> last_child ) {
223
+ S_set_last_line_checked (node );
224
+ return (ends_with_blank_line (node -> last_child ));
225
+ } else {
226
+ S_set_last_line_checked (node );
227
+ return (S_last_line_blank (node ));
222
228
}
223
- S_set_last_line_blank (node , false);
224
- return false;
225
229
}
226
230
227
231
static cmark_node * finalize (cmark_parser * parser , cmark_node * b ) {
0 commit comments