From 8d6efe632aaeb1831c86b27e120a344c5e3ee7d4 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Sat, 13 Dec 2014 12:08:19 -0800 Subject: API improvements: cmark_event_type parameter for walk handlers. Added cmark_event_type enum, which is used as the second parameter of the handler passed to cmark_walk. See #224. --- api_test/main.c | 4 ++-- man/man3/cmark.3 | 4 ++-- src/cmark.h | 11 +++++++++-- src/html.c | 4 +++- src/node.c | 14 ++++++++------ 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/api_test/main.c b/api_test/main.c index 25521d0..c975060 100644 --- a/api_test/main.c +++ b/api_test/main.c @@ -294,10 +294,10 @@ node_check(test_batch_runner *runner) { } static int -S_handler(cmark_node *node, int entering, void *state) +S_handler(cmark_node *node, cmark_event_type ev_type, void *state) { int *textnodes = state; - if (entering) { + if (ev_type == CMARK_EVENT_ENTER) { if (node->type == CMARK_NODE_TEXT) { *textnodes += 1; } diff --git a/man/man3/cmark.3 b/man/man3/cmark.3 index 30165a1..4a28e4a 100644 --- a/man/man3/cmark.3 +++ b/man/man3/cmark.3 @@ -1,4 +1,4 @@ -.TH cmark 3 "December 12, 2014" "LOCAL" "Library Functions Manual" +.TH cmark 3 "December 13, 2014" "LOCAL" "Library Functions Manual" .SH NAME .B cmark @@ -277,7 +277,7 @@ typedef enum { Walks the tree starting from root, applying handler to each node. Nodes that can have children are visited twice, once on the way in and once on the way out. handler is a function that takes a node -pointer, an integer direction (1 for entering, 0 for leaving), +pointer, a cmark_event_type, and a pointer to a state structure that can be consulted and updated by the handler. The handler should return 1 on success, 0 on failure. cmark_walk returns 1 if it traversed the entire diff --git a/src/cmark.h b/src/cmark.h index 224ef3a..a43703a 100644 --- a/src/cmark.h +++ b/src/cmark.h @@ -85,7 +85,14 @@ typedef enum { typedef struct cmark_node cmark_node; typedef struct cmark_parser cmark_parser; -typedef int (*cmark_node_handler)(cmark_node*, int, void*); +typedef enum { + CMARK_EVENT_DONE, + CMARK_EVENT_ENTER, + CMARK_EVENT_EXIT +} cmark_event_type; + +typedef int (*cmark_node_handler)(cmark_node *node, cmark_event_type ev_type, + void *state); /** * .SH CREATING AND DESTROYING NODES @@ -311,7 +318,7 @@ char *cmark_render_html(cmark_node *root); /** Walks the tree starting from root, applying handler to each node. * Nodes that can have children are visited twice, once on the way in * and once on the way out. handler is a function that takes a node - * pointer, an integer direction (1 for entering, 0 for leaving), + * pointer, a cmark_event_type, * and a pointer to a state structure that can be consulted and * updated by the handler. The handler should return 1 on success, * 0 on failure. cmark_walk returns 1 if it traversed the entire diff --git a/src/html.c b/src/html.c index 12d4659..1ccb57a 100644 --- a/src/html.c +++ b/src/html.c @@ -39,7 +39,7 @@ struct render_state { }; static int -S_render_node(cmark_node *node, int entering, void *vstate) +S_render_node(cmark_node *node, cmark_event_type ev_type, void *vstate) { struct render_state *state = vstate; cmark_node *parent; @@ -50,6 +50,8 @@ S_render_node(cmark_node *node, int entering, void *vstate) strbuf *info; bool tight; + bool entering = (ev_type == CMARK_EVENT_ENTER); + if (state->plain == node) { // back at original node state->plain = NULL; } diff --git a/src/node.c b/src/node.c index a7083ca..72eb619 100644 --- a/src/node.c +++ b/src/node.c @@ -786,7 +786,7 @@ int S_is_leaf_node(cmark_node *current_node) int cmark_walk(cmark_node *root, cmark_node_handler handler, void *state) { - int begin = 1; + int ev_type = CMARK_EVENT_ENTER; cmark_node *current_node = root; int depth = 0; cmark_node *next, *parent, *first_child; @@ -796,14 +796,15 @@ int cmark_walk(cmark_node *root, cmark_node_handler handler, void *state) next = current_node->next; parent = current_node->parent; - if (!handler(current_node, begin, state)) { + if (!handler(current_node, ev_type, state)) { return 0; } - if (begin && !S_is_leaf_node(current_node)) { + if (ev_type == CMARK_EVENT_ENTER && + !S_is_leaf_node(current_node)) { first_child = current_node->first_child; if (first_child == NULL) { - begin = 0; // stay on this node + ev_type = CMARK_EVENT_EXIT; // stay on this node } else { depth += 1; current_node = first_child; @@ -816,13 +817,14 @@ int cmark_walk(cmark_node *root, cmark_node_handler handler, void *state) if (next) { // don't go past root: if (current_node == root) { + ev_type = CMARK_EVENT_DONE; return 1; } else { - begin = 1; + ev_type = CMARK_EVENT_ENTER; current_node = next; } } else { - begin = 0; + ev_type = CMARK_EVENT_EXIT; depth -= 1; current_node = parent; } -- cgit v1.2.3