summaryrefslogtreecommitdiff
path: root/src/node.c
diff options
context:
space:
mode:
authorJohn MacFarlane <fiddlosopher@gmail.com>2014-12-11 13:55:21 -0800
committerJohn MacFarlane <fiddlosopher@gmail.com>2014-12-12 15:24:05 -0800
commit4cc37256fdc47faeefe6296cdcce022ec6a60719 (patch)
tree48828269a62913d9725a35d1d39e4963cb4b8915 /src/node.c
parent550230aa5575b120782ef307a17317c6827f032e (diff)
Added cmark_node_handler and cmark_walk to header.
Diffstat (limited to 'src/node.c')
-rw-r--r--src/node.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/node.c b/src/node.c
index 243c3e6..040aeda 100644
--- a/src/node.c
+++ b/src/node.c
@@ -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;
+}