diff options
Diffstat (limited to 'src/iterator.c')
-rw-r--r-- | src/iterator.c | 222 |
1 files changed, 96 insertions, 126 deletions
diff --git a/src/iterator.c b/src/iterator.c index f18e3bf..81b6f48 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -7,142 +7,112 @@ #include "iterator.h" static const int S_leaf_mask = - (1 << CMARK_NODE_HTML) | - (1 << CMARK_NODE_HRULE) | - (1 << CMARK_NODE_CODE_BLOCK) | - (1 << CMARK_NODE_TEXT) | - (1 << CMARK_NODE_SOFTBREAK) | - (1 << CMARK_NODE_LINEBREAK) | - (1 << CMARK_NODE_CODE) | - (1 << CMARK_NODE_INLINE_HTML); - -cmark_iter* -cmark_iter_new(cmark_node *root) -{ - if (root == NULL) { - return NULL; - } - cmark_iter *iter = (cmark_iter*)malloc(sizeof(cmark_iter)); - if (iter == NULL) { - return NULL; - } - iter->root = root; - iter->cur.ev_type = CMARK_EVENT_NONE; - iter->cur.node = NULL; - iter->next.ev_type = CMARK_EVENT_ENTER; - iter->next.node = root; - return iter; + (1 << CMARK_NODE_HTML) | (1 << CMARK_NODE_HRULE) | + (1 << CMARK_NODE_CODE_BLOCK) | (1 << CMARK_NODE_TEXT) | + (1 << CMARK_NODE_SOFTBREAK) | (1 << CMARK_NODE_LINEBREAK) | + (1 << CMARK_NODE_CODE) | (1 << CMARK_NODE_INLINE_HTML); + +cmark_iter *cmark_iter_new(cmark_node *root) { + if (root == NULL) { + return NULL; + } + cmark_iter *iter = (cmark_iter *)malloc(sizeof(cmark_iter)); + if (iter == NULL) { + return NULL; + } + iter->root = root; + iter->cur.ev_type = CMARK_EVENT_NONE; + iter->cur.node = NULL; + iter->next.ev_type = CMARK_EVENT_ENTER; + iter->next.node = root; + return iter; } -void -cmark_iter_free(cmark_iter *iter) -{ - free(iter); -} +void cmark_iter_free(cmark_iter *iter) { free(iter); } -static bool -S_is_leaf(cmark_node *node) -{ - return (1 << node->type) & S_leaf_mask; +static bool S_is_leaf(cmark_node *node) { + return (1 << node->type) & S_leaf_mask; } -cmark_event_type -cmark_iter_next(cmark_iter *iter) -{ - cmark_event_type ev_type = iter->next.ev_type; - cmark_node *node = iter->next.node; - - iter->cur.ev_type = ev_type; - iter->cur.node = node; - - if (ev_type == CMARK_EVENT_DONE) { - return ev_type; - } - - /* roll forward to next item, setting both fields */ - if (ev_type == CMARK_EVENT_ENTER && !S_is_leaf(node)) { - if (node->first_child == NULL) { - /* stay on this node but exit */ - iter->next.ev_type = CMARK_EVENT_EXIT; - } else { - iter->next.ev_type = CMARK_EVENT_ENTER; - iter->next.node = node->first_child; - } - } else if (node == iter->root) { - /* don't move past root */ - iter->next.ev_type = CMARK_EVENT_DONE; - iter->next.node = NULL; - } else if (node->next) { - iter->next.ev_type = CMARK_EVENT_ENTER; - iter->next.node = node->next; - } else if (node->parent) { - iter->next.ev_type = CMARK_EVENT_EXIT; - iter->next.node = node->parent; - } else { - assert(false); - iter->next.ev_type = CMARK_EVENT_DONE; - iter->next.node = NULL; - } - - return ev_type; +cmark_event_type cmark_iter_next(cmark_iter *iter) { + cmark_event_type ev_type = iter->next.ev_type; + cmark_node *node = iter->next.node; + + iter->cur.ev_type = ev_type; + iter->cur.node = node; + + if (ev_type == CMARK_EVENT_DONE) { + return ev_type; + } + + /* roll forward to next item, setting both fields */ + if (ev_type == CMARK_EVENT_ENTER && !S_is_leaf(node)) { + if (node->first_child == NULL) { + /* stay on this node but exit */ + iter->next.ev_type = CMARK_EVENT_EXIT; + } else { + iter->next.ev_type = CMARK_EVENT_ENTER; + iter->next.node = node->first_child; + } + } else if (node == iter->root) { + /* don't move past root */ + iter->next.ev_type = CMARK_EVENT_DONE; + iter->next.node = NULL; + } else if (node->next) { + iter->next.ev_type = CMARK_EVENT_ENTER; + iter->next.node = node->next; + } else if (node->parent) { + iter->next.ev_type = CMARK_EVENT_EXIT; + iter->next.node = node->parent; + } else { + assert(false); + iter->next.ev_type = CMARK_EVENT_DONE; + iter->next.node = NULL; + } + + return ev_type; } -void -cmark_iter_reset(cmark_iter *iter, cmark_node *current, - cmark_event_type event_type) -{ - iter->next.ev_type = event_type; - iter->next.node = current; - cmark_iter_next(iter); +void cmark_iter_reset(cmark_iter *iter, cmark_node *current, + cmark_event_type event_type) { + iter->next.ev_type = event_type; + iter->next.node = current; + cmark_iter_next(iter); } -cmark_node* -cmark_iter_get_node(cmark_iter *iter) -{ - return iter->cur.node; -} +cmark_node *cmark_iter_get_node(cmark_iter *iter) { return iter->cur.node; } -cmark_event_type -cmark_iter_get_event_type(cmark_iter *iter) -{ - return iter->cur.ev_type; +cmark_event_type cmark_iter_get_event_type(cmark_iter *iter) { + return iter->cur.ev_type; } -cmark_node* -cmark_iter_get_root(cmark_iter *iter) -{ - return iter->root; -} - - -void cmark_consolidate_text_nodes(cmark_node *root) -{ - cmark_iter *iter = cmark_iter_new(root); - cmark_strbuf buf = GH_BUF_INIT; - cmark_event_type ev_type; - cmark_node *cur, *tmp, *next; - - while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { - cur = cmark_iter_get_node(iter); - if (ev_type == CMARK_EVENT_ENTER && - cur->type == CMARK_NODE_TEXT && - cur->next && - cur->next->type == CMARK_NODE_TEXT) { - cmark_strbuf_clear(&buf); - cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len); - tmp = cur->next; - while (tmp && tmp->type == CMARK_NODE_TEXT) { - cmark_iter_next(iter); // advance pointer - cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len); - next = tmp->next; - cmark_node_free(tmp); - tmp = next; - } - cmark_chunk_free(&cur->as.literal); - cur->as.literal = cmark_chunk_buf_detach(&buf); - } - } - - cmark_strbuf_free(&buf); - cmark_iter_free(iter); +cmark_node *cmark_iter_get_root(cmark_iter *iter) { return iter->root; } + +void cmark_consolidate_text_nodes(cmark_node *root) { + cmark_iter *iter = cmark_iter_new(root); + cmark_strbuf buf = GH_BUF_INIT; + cmark_event_type ev_type; + cmark_node *cur, *tmp, *next; + + while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) { + cur = cmark_iter_get_node(iter); + if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT && + cur->next && cur->next->type == CMARK_NODE_TEXT) { + cmark_strbuf_clear(&buf); + cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len); + tmp = cur->next; + while (tmp && tmp->type == CMARK_NODE_TEXT) { + cmark_iter_next(iter); // advance pointer + cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len); + next = tmp->next; + cmark_node_free(tmp); + tmp = next; + } + cmark_chunk_free(&cur->as.literal); + cur->as.literal = cmark_chunk_buf_detach(&buf); + } + } + + cmark_strbuf_free(&buf); + cmark_iter_free(iter); } |