You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2015/01/18 19:44:47 UTC

[11/12] lucy-clownfish git commit: Switch to CommonMark iterators

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 <we...@aevum.de>
Authored: Sat Jan 10 22:43:20 2015 +0100
Committer: Nick Wellnhofer <we...@aevum.de>
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;
 }