diff options
author | John MacFarlane <fiddlosopher@gmail.com> | 2014-12-11 13:55:21 -0800 |
---|---|---|
committer | John MacFarlane <fiddlosopher@gmail.com> | 2014-12-12 15:24:05 -0800 |
commit | 4cc37256fdc47faeefe6296cdcce022ec6a60719 (patch) | |
tree | 48828269a62913d9725a35d1d39e4963cb4b8915 /src/node.c | |
parent | 550230aa5575b120782ef307a17317c6827f032e (diff) |
Added cmark_node_handler and cmark_walk to header.
Diffstat (limited to 'src/node.c')
-rw-r--r-- | src/node.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -767,3 +767,62 @@ cmark_node_check(cmark_node *node, FILE *out) return errors; } + +int S_is_leaf_node(cmark_node *current_node) +{ + switch (cmark_node_get_type(current_node)) { + case CMARK_NODE_HTML: + case CMARK_NODE_HRULE: + case CMARK_NODE_REFERENCE_DEF: + case CMARK_NODE_TEXT: + case CMARK_NODE_SOFTBREAK: + case CMARK_NODE_LINEBREAK: + case CMARK_NODE_INLINE_CODE: + case CMARK_NODE_INLINE_HTML: + return 1; + default: + return 0; + } +} + +int cmark_walk(cmark_node *root, cmark_node_handler handler, void *state) +{ + int begin = 1; + cmark_node *current_node = root; + int depth = 0; + cmark_node *next, *parent, *first_child; + + while (current_node != NULL && depth >= 0) { + + next = current_node->next; + parent = current_node->parent; + + if (!handler(current_node, begin, state)) { + return 0; + } + + if (begin && !S_is_leaf_node(current_node)) { + first_child = current_node->first_child; + if (first_child == NULL) { + begin = 0; // stay on this node + } else { + depth += 1; + current_node = first_child; + } + } else { + if (current_node) { + next = current_node->next; + parent = current_node->parent; + } + if (next) { + begin = 1; + current_node = next; + } else { + begin = 0; + depth -= 1; + current_node = parent; + } + } + } + return 1; +} |