cmark
My personal build of CMark ✏️
- Commit
- 8d6efe632aaeb1831c86b27e120a344c5e3ee7d4
- Parent
- a6a7d2f8f47df7144e636ae2875a8d2ffc0173ae
- Author
- John MacFarlane <jgm@berkeley.edu>
- Date
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.
Diffstat
5 files changed, 24 insertions, 13 deletions
diff --git 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
@@ -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
@@ -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
@@ -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;
}