Skip to content

Commit

Permalink
Added iterator interface to API, removed cmark_walk.
Browse files Browse the repository at this point in the history
* Added `iterator.c`, `iterator.h`.
* Removed `cmark_walk`.
* Replaced `cmark_walk` with iterator in HTML renderer.
* Replaced API test for `cmark_walk` with simple iterator test.
  • Loading branch information
jgm committed Dec 14, 2014
1 parent 8d6efe6 commit a3030f9
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 133 deletions.
35 changes: 16 additions & 19 deletions api_test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,27 +293,24 @@ node_check(test_batch_runner *runner) {
cmark_node_free(doc);
}

static int
S_handler(cmark_node *node, cmark_event_type ev_type, void *state)
{
int *textnodes = state;
if (ev_type == CMARK_EVENT_ENTER) {
if (node->type == CMARK_NODE_TEXT) {
*textnodes += 1;
}
}
return 1;
}

static void
walk(test_batch_runner *runner) {
// Construct an incomplete tree.
iterator(test_batch_runner *runner) {
cmark_node *doc = cmark_parse_document("> a *b*\n\nc", 10);
int textnodes = 0;
INT_EQ(runner, cmark_walk(doc, S_handler, &textnodes), 1,
"walk succeeds");
INT_EQ(runner, textnodes, 3, "walk correctly counts text nodes");
int parnodes = 0;
cmark_event_type ev_type;
cmark_iter *iter = cmark_iter_new(doc);
cmark_node *cur;

while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
if (cur->type == CMARK_NODE_PARAGRAPH &&
ev_type == CMARK_EVENT_ENTER) {
parnodes += 1;
}
}
INT_EQ(runner, parnodes, 2, "iterate correctly counts paragraphs");

cmark_iter_free(iter);
cmark_node_free(doc);
}

Expand Down Expand Up @@ -627,7 +624,7 @@ int main() {
constructor(runner);
accessors(runner);
node_check(runner);
walk(runner);
iterator(runner);
create_tree(runner);
hierarchy(runner);
parser(runner);
Expand Down
50 changes: 29 additions & 21 deletions man/man3/cmark.3
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
.B cmark
\- CommonMark parsing, manipulating, and rendering

.SH SIMPLE INTERFACE
.SH DESCRIPTION

.SS Simple Interface

.nf
\f[C]
Expand All @@ -24,7 +26,7 @@ Convert \fItext\fR (assumed to be a UTF-8 encoded string with length
\fIlen\fR from CommonMark Markdown to HTML, returning a null-terminated,
UTF-8-encoded string.

.SH NODE STRUCTURE
.SS Node Structure

.nf
\f[C]
Expand Down Expand Up @@ -95,7 +97,7 @@ typedef enum {
.PP


.SH CREATING AND DESTROYING NODES
.SS Creating and Destroying Nodes

\fIcmark_node*\fR \fBcmark_node_new\fR(\fIcmark_node_type type\fR)

Expand All @@ -109,7 +111,7 @@ typedef enum {

.PP

.SH TREE TRAVERSAL
.SS Tree Traversal

\fIcmark_node*\fR \fBcmark_node_previous\fR(\fIcmark_node *node\fR)

Expand All @@ -128,7 +130,26 @@ typedef enum {
.PP


.SH ACCESSORS
.SS Iterator

\fIcmark_iter*\fR \fBcmark_iter_new\fR(\fIcmark_node *root\fR)

.PP

\fIvoid\fR \fBcmark_iter_free\fR(\fIcmark_iter *iter\fR)

.PP

\fIcmark_event_type\fR \fBcmark_iter_next\fR(\fIcmark_iter *iter\fR)

.PP

\fIcmark_node*\fR \fBcmark_iter_get_node\fR(\fIcmark_iter *iter\fR)

.PP


.SS Accessors

\fIcmark_node_type\fR \fBcmark_node_get_type\fR(\fIcmark_node *node\fR)

Expand Down Expand Up @@ -211,7 +232,7 @@ typedef enum {
.PP


.SH TREE MANIPULATION
.SS Tree Manipulation

\fIvoid\fR \fBcmark_node_unlink\fR(\fIcmark_node *node\fR)

Expand All @@ -234,7 +255,7 @@ typedef enum {
.PP


.SH PARSING
.SS Parsing

\fIcmark_parser *\fR \fBcmark_parser_new\fR(\fI\fR)

Expand All @@ -261,7 +282,7 @@ typedef enum {
.PP


.SH RENDERING
.SS Rendering

\fIchar *\fR \fBcmark_render_ast\fR(\fIcmark_node *root\fR)

Expand All @@ -271,19 +292,6 @@ typedef enum {

.PP

\fIint\fR \fBcmark_walk\fR(\fIcmark_node *root\fR, \fIcmark_node_handler handler\fR, \fIvoid *state\fR)

.PP
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, 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
tree, 0 if it quit early in response to a 0 status from the
handler.

.SH AUTHORS

John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer.
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(HEADERS
parser.h
buffer.h
node.h
iterator.h
chunk.h
references.h
debug.h
Expand All @@ -18,6 +19,7 @@ set(HEADERS
set(LIBRARY_SOURCES
cmark.c
node.c
iterator.c
blocks.c
inlines.c
print.c
Expand Down
60 changes: 39 additions & 21 deletions src/cmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ extern "C" {
* \- CommonMark parsing, manipulating, and rendering
*/

/** .SH SIMPLE INTERFACE
/** .SH DESCRIPTION
*
* .SS Simple Interface
*/

/** Current version of library.
Expand All @@ -28,7 +30,7 @@ extern "C" {
CMARK_EXPORT
char *cmark_markdown_to_html(const char *text, int len);

/** .SH NODE STRUCTURE
/** .SS Node Structure
*/

/**
Expand Down Expand Up @@ -84,6 +86,7 @@ typedef enum {

typedef struct cmark_node cmark_node;
typedef struct cmark_parser cmark_parser;
typedef struct cmark_iter cmark_iter;

typedef enum {
CMARK_EVENT_DONE,
Expand All @@ -95,7 +98,7 @@ typedef int (*cmark_node_handler)(cmark_node *node, cmark_event_type ev_type,
void *state);

/**
* .SH CREATING AND DESTROYING NODES
* .SS Creating and Destroying Nodes
*/

/**
Expand All @@ -109,7 +112,7 @@ CMARK_EXPORT void
cmark_node_free(cmark_node *node);

/**
* .SH TREE TRAVERSAL
* .SS Tree Traversal
*/
CMARK_EXPORT cmark_node*
cmark_node_next(cmark_node *node);
Expand All @@ -135,7 +138,35 @@ CMARK_EXPORT cmark_node*
cmark_node_last_child(cmark_node *node);

/**
* .SH ACCESSORS
* .SS Iterator
*/

/**
*/
CMARK_EXPORT
cmark_iter*
cmark_iter_new(cmark_node *root);

/**
*/
CMARK_EXPORT
void
cmark_iter_free(cmark_iter *iter);

/**
*/
CMARK_EXPORT
cmark_event_type
cmark_iter_next(cmark_iter *iter);

/**
*/
CMARK_EXPORT
cmark_node*
cmark_iter_get_node(cmark_iter *iter);

/**
* .SS Accessors
*/

/**
Expand Down Expand Up @@ -239,7 +270,7 @@ CMARK_EXPORT int
cmark_node_get_end_line(cmark_node *node);

/**
* .SH TREE MANIPULATION
* .SS Tree Manipulation
*/

/**
Expand Down Expand Up @@ -268,7 +299,7 @@ CMARK_EXPORT int
cmark_node_append_child(cmark_node *node, cmark_node *child);

/**
* .SH PARSING
* .SS Parsing
*/

/**
Expand Down Expand Up @@ -302,7 +333,7 @@ CMARK_EXPORT
cmark_node *cmark_parse_file(FILE *f);

/**
* .SH RENDERING
* .SS Rendering
*/

/**
Expand All @@ -315,19 +346,6 @@ char *cmark_render_ast(cmark_node *root);
CMARK_EXPORT
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, 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
* tree, 0 if it quit early in response to a 0 status from the
* handler.
*/
CMARK_EXPORT
int cmark_walk(cmark_node *root, cmark_node_handler handler, void *state);

/** .SH AUTHORS
*
* John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer.
Expand Down
18 changes: 12 additions & 6 deletions src/html.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,18 @@ char *cmark_render_html(cmark_node *root)
{
char *result;
strbuf html = GH_BUF_INIT;
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = { &html, NULL };
if (cmark_walk(root, S_render_node, &state)) {
result = (char *)strbuf_detach(&html);
strbuf_free(&html);
return result;
} else {
return NULL;
cmark_iter *iter = cmark_iter_new(root);

while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
S_render_node(cur, ev_type, &state);
}
result = (char *)strbuf_detach(&html);

cmark_iter_free(iter);
strbuf_free(&html);
return result;
}
Loading

0 comments on commit a3030f9

Please sign in to comment.