Switch to CommonMark iterators
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/73efb7c7 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/73efb7c7 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/73efb7c7 Branch: refs/heads/master Commit: 73efb7c705e9087a40520fb40808d2c6ac7ced73 Parents: eb17ed8 Author: Nick Wellnhofer <[email protected]> Authored: Sat Jan 10 22:43:20 2015 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Sun Jan 18 19:38:29 2015 +0100 ---------------------------------------------------------------------- compiler/src/CFCCHtml.c | 33 ++------ compiler/src/CFCCMan.c | 187 +++++++++++++++++------------------------ compiler/src/CFCPerlPod.c | 123 +++++++++++++-------------- 3 files changed, 143 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/73efb7c7/compiler/src/CFCCHtml.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c index e4b67f7..9252624 100644 --- a/compiler/src/CFCCHtml.c +++ b/compiler/src/CFCCHtml.c @@ -762,37 +762,18 @@ S_md_to_html(CFCClass *klass, const char *md) { static void S_convert_uris(CFCClass *klass, cmark_node *node) { - cmark_node *cur = node; + cmark_iter *iter = cmark_iter_new(node); + cmark_event_type ev_type; - while (cur) { - cmark_node_type type = cmark_node_get_type(cur); + while (CMARK_EVENT_DONE != (ev_type = cmark_iter_next(iter))) { + cmark_node *cur = cmark_iter_get_node(iter); - // Find the next node in the tree before possibly deleting cur. - cmark_node *tree_next = NULL; - - cmark_node *child = cmark_node_first_child(cur); - // Don't descend into links. - if (type != CMARK_NODE_LINK && child) { - tree_next = child; - } - else { - cmark_node *ancestor = cur; - while (ancestor != node) { - cmark_node *next = cmark_node_next(ancestor); - if (next) { - tree_next = next; - break; - } - ancestor = cmark_node_parent(ancestor); - } - } - - if (type == NODE_LINK) { + if (cmark_node_get_type(cur) == NODE_LINK) { S_convert_uri(klass, cur); } - - cur = tree_next; } + + cmark_iter_free(iter); } static void http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/73efb7c7/compiler/src/CFCCMan.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCCMan.c b/compiler/src/CFCCMan.c index 55865b1..f6ef3f0 100644 --- a/compiler/src/CFCCMan.c +++ b/compiler/src/CFCCMan.c @@ -421,111 +421,80 @@ S_md_to_man(CFCClass *klass, const char *md, int needs_indent) { static char* S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { char *result = CFCUtil_strdup(""); + int level = needs_indent ? 1 : 0; int has_indent = needs_indent; int has_vspace = true; + cmark_iter *iter = cmark_iter_new(node); + cmark_event_type ev_type; - while (node) { - cmark_node_type type = cmark_node_get_type(node); + while (CMARK_EVENT_DONE != (ev_type = cmark_iter_next(iter))) { + cmark_node *node = cmark_iter_get_node(iter); + cmark_node_type type = cmark_node_get_type(node); switch (type) { - case CMARK_NODE_DOCUMENT: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, children_man, NULL); - FREEMEM(children_man); + case CMARK_NODE_DOCUMENT: break; - } - case CMARK_NODE_PARAGRAPH: { - if (needs_indent && !has_indent) { - result = CFCUtil_cat(result, ".IP\n", NULL); - has_indent = true; - } - else if (!needs_indent && has_indent) { - result = CFCUtil_cat(result, ".P\n", NULL); - has_indent = false; + case CMARK_NODE_PARAGRAPH: + if (ev_type == CMARK_EVENT_ENTER) { + if (level > 0 && !has_indent) { + result = CFCUtil_cat(result, ".IP\n", NULL); + has_indent = true; + } + else if (level == 0 && has_indent) { + result = CFCUtil_cat(result, ".P\n", NULL); + has_indent = false; + } + else if (!has_vspace) { + result = CFCUtil_cat(result, "\n", NULL); + } } - else if (!has_vspace) { + else { result = CFCUtil_cat(result, "\n", NULL); + has_vspace = false; } - - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, children_man, "\n", NULL); - FREEMEM(children_man); - - has_vspace = false; - break; - } - case CMARK_NODE_BLOCK_QUOTE: { - if (needs_indent) { - result = CFCUtil_cat(result, ".RS\n", NULL); - } - - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, true); - result = CFCUtil_cat(result, ".IP\n", children_man, NULL); - FREEMEM(children_man); - - if (needs_indent) { - result = CFCUtil_cat(result, ".RE\n", NULL); - has_indent = false; + case CMARK_NODE_BLOCK_QUOTE: + case CMARK_NODE_LIST: + if (ev_type == CMARK_EVENT_ENTER) { + if (level > 0) { + result = CFCUtil_cat(result, ".RS\n", NULL); + has_indent = false; + } + ++level; } else { - has_indent = true; + --level; + if (level > 0) { + result = CFCUtil_cat(result, ".RE\n", NULL); + has_indent = false; + } } - - break; - } - - case CMARK_NODE_ITEM: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, true); - result = CFCUtil_cat(result, ".IP \\(bu\n", children_man, - NULL); - FREEMEM(children_man); break; - } - case CMARK_NODE_LIST: { - if (needs_indent) { - result = CFCUtil_cat(result, ".RS\n", NULL); + case CMARK_NODE_ITEM: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, ".IP \\(bu\n", NULL); + has_indent = true; + has_vspace = true; } + break; - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, children_man, NULL); - FREEMEM(children_man); - - if (needs_indent) { - result = CFCUtil_cat(result, ".RE\n", NULL); + case CMARK_NODE_HEADER: + // Only works on top level for now. + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, ".SS\n", NULL); has_indent = false; } else { - has_indent = true; + result = CFCUtil_cat(result, "\n", NULL); + has_vspace = true; } - break; - } - - case CMARK_NODE_HEADER: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, ".SS\n", children_man, "\n", NULL); - FREEMEM(children_man); - has_indent = false; - has_vspace = true; - break; - } case CMARK_NODE_CODE_BLOCK: { - if (needs_indent) { + if (level > 0) { result = CFCUtil_cat(result, ".RS\n", NULL); } @@ -535,12 +504,13 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { ".fam\n.fi\n", NULL); FREEMEM(escaped); - if (needs_indent) { + if (level > 0) { result = CFCUtil_cat(result, ".RE\n", NULL); has_indent = false; } else { has_indent = true; + has_vspace = false; } break; @@ -584,15 +554,13 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { } case CMARK_NODE_LINK: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); const char *url = cmark_node_get_url(node); + if (CFCUri_is_clownfish_uri(url)) { - if (children_man[0] != '\0') { - result = CFCUtil_cat(result, children_man, NULL); - } - else { + if (ev_type == CMARK_EVENT_ENTER + && !cmark_node_first_child(node) + ) { + // Empty link text. CFCUri *uri_obj = CFCUri_new(url, klass); char *link_text = CFCC_link_text(uri_obj, klass); if (link_text) { @@ -603,11 +571,15 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { } } else { - result = CFCUtil_cat(result, "\n.UR ", url, "\n", - children_man, "\n.UE\n", - NULL); + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "\n.UR ", url, "\n", + NULL); + } + else { + result = CFCUtil_cat(result, "\n.UE\n", NULL); + } } - FREEMEM(children_man); + break; } @@ -615,34 +587,31 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int needs_indent) { CFCUtil_warn("Images not supported in man pages"); break; - case CMARK_NODE_STRONG: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, "\\fB", children_man, "\\f[]", - NULL); - FREEMEM(children_man); + case CMARK_NODE_STRONG: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "\\fB", NULL); + } + else { + result = CFCUtil_cat(result, "\\f[]", NULL); + } break; - } - case CMARK_NODE_EMPH: { - cmark_node *child = cmark_node_first_child(node); - char *children_man = S_nodes_to_man(klass, child, - needs_indent); - result = CFCUtil_cat(result, "\\fI", children_man, "\\f[]", - NULL); - FREEMEM(children_man); + case CMARK_NODE_EMPH: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "\\fI", NULL); + } + else { + result = CFCUtil_cat(result, "\\f[]", NULL); + } break; - } default: CFCUtil_die("Invalid cmark node type: %d", type); break; } - - node = cmark_node_next(node); } + cmark_iter_free(iter); return result; } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/73efb7c7/compiler/src/CFCPerlPod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlPod.c b/compiler/src/CFCPerlPod.c index 3dcb83a..17e6a43 100644 --- a/compiler/src/CFCPerlPod.c +++ b/compiler/src/CFCPerlPod.c @@ -331,66 +331,56 @@ CFCPerlPod_md_to_pod(CFCPerlPod *self, CFCClass *klass, const char *md) { static char* S_nodes_to_pod(CFCClass *klass, cmark_node *node) { char *result = CFCUtil_strdup(""); + if (node == NULL) { + return result; + } + + cmark_iter *iter = cmark_iter_new(node); + cmark_event_type ev_type; - while (node) { + while (CMARK_EVENT_DONE != (ev_type = cmark_iter_next(iter))) { + cmark_node *node = cmark_iter_get_node(iter); cmark_node_type type = cmark_node_get_type(node); switch (type) { - case CMARK_NODE_DOCUMENT: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, children_pod, NULL); - FREEMEM(children_pod); + case CMARK_NODE_DOCUMENT: break; - } - case CMARK_NODE_PARAGRAPH: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, children_pod, "\n\n", NULL); - FREEMEM(children_pod); + case CMARK_NODE_PARAGRAPH: + if (ev_type == CMARK_EVENT_EXIT) { + result = CFCUtil_cat(result, "\n\n", NULL); + } break; - } - case CMARK_NODE_BLOCK_QUOTE: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, "=over\n\n", children_pod, - "\n=back\n\n", NULL); - FREEMEM(children_pod); + case CMARK_NODE_BLOCK_QUOTE: + case CMARK_NODE_LIST: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "=over\n\n", NULL); + } + else { + result = CFCUtil_cat(result, "=back\n\n", NULL); + } break; - } - case CMARK_NODE_ITEM: { + case CMARK_NODE_ITEM: // TODO: Ordered lists. - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, "=item *\n\n", children_pod, - NULL); - FREEMEM(children_pod); - break; - } - - case CMARK_NODE_LIST: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, "=over\n\n", children_pod, - "=back\n\n", NULL); - FREEMEM(children_pod); + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "=item *\n\n", NULL); + } break; - } - case CMARK_NODE_HEADER: { - cmark_node *child = cmark_node_first_child(node); - int header_level = cmark_node_get_header_level(node); - char *children_pod = S_nodes_to_pod(klass, child); - char *header = CFCUtil_sprintf("=head%d %s\n\n", - header_level + 2, children_pod); - result = CFCUtil_cat(result, header, NULL); - FREEMEM(header); - FREEMEM(children_pod); + case CMARK_NODE_HEADER: + if (ev_type == CMARK_EVENT_ENTER) { + int header_level = cmark_node_get_header_level(node); + char *header = CFCUtil_sprintf("=head%d ", + header_level + 2); + result = CFCUtil_cat(result, header, NULL); + FREEMEM(header); + } + else { + result = CFCUtil_cat(result, "\n\n", NULL); + } break; - } case CMARK_NODE_CODE_BLOCK: { const char *content = cmark_node_get_literal(node); @@ -449,41 +439,44 @@ S_nodes_to_pod(CFCClass *klass, cmark_node *node) { break; } - case CMARK_NODE_LINK: { - char *pod = S_convert_link(klass, node); - result = CFCUtil_cat(result, pod, NULL); - FREEMEM(pod); + case CMARK_NODE_LINK: + if (ev_type == CMARK_EVENT_ENTER) { + char *pod = S_convert_link(klass, node); + result = CFCUtil_cat(result, pod, NULL); + FREEMEM(pod); + cmark_iter_reset(iter, node, CMARK_EVENT_EXIT); + } break; - } case CMARK_NODE_IMAGE: CFCUtil_warn("Images not supported in POD"); break; - case CMARK_NODE_STRONG: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, "B<", children_pod, ">", NULL); - FREEMEM(children_pod); + case CMARK_NODE_STRONG: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "B<", NULL); + } + else { + result = CFCUtil_cat(result, ">", NULL); + } break; - } - case CMARK_NODE_EMPH: { - cmark_node *child = cmark_node_first_child(node); - char *children_pod = S_nodes_to_pod(klass, child); - result = CFCUtil_cat(result, "I<", children_pod, ">", NULL); - FREEMEM(children_pod); + case CMARK_NODE_EMPH: + if (ev_type == CMARK_EVENT_ENTER) { + result = CFCUtil_cat(result, "I<", NULL); + } + else { + result = CFCUtil_cat(result, ">", NULL); + } break; - } default: CFCUtil_die("Invalid cmark node type: %d", type); break; } - - node = cmark_node_next(node); } + cmark_iter_free(iter); return result; }
