Ignore code blocks of other host languages

Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7973bf5b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7973bf5b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7973bf5b

Branch: refs/heads/master
Commit: 7973bf5b99e0128520ae32a2c5680bf37912652f
Parents: d11a489
Author: Nick Wellnhofer <[email protected]>
Authored: Sun Jul 26 03:04:25 2015 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Thu Aug 6 18:19:19 2015 +0200

----------------------------------------------------------------------
 compiler/src/CFCCHtml.c       | 60 ++++++++++++++++++++++++++++++++------
 compiler/src/CFCCMan.c        | 60 +++++++++++++++++++++++++++++---------
 compiler/src/CFCDocuComment.c | 15 ++++++++++
 compiler/src/CFCDocuComment.h |  9 ++++++
 compiler/src/CFCPerlPod.c     | 42 +++++++++++++++++++-------
 5 files changed, 152 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7973bf5b/compiler/src/CFCCHtml.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index 3c953fe..aa240b0 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -159,10 +159,13 @@ static char*
 S_md_to_html(const char *md, CFCClass *klass, int dir_level);
 
 static void
-S_convert_uris(cmark_node *node, CFCClass *klass, int dir_level);
+S_transform_doc(cmark_node *node, CFCClass *klass, int dir_level);
+
+static int
+S_transform_code_block(cmark_node *node, int found_matching_code_block);
 
 static void
-S_convert_uri(cmark_node *link, CFCClass *klass, int dir_level);
+S_transform_link(cmark_node *link, CFCClass *klass, int dir_level);
 
 static char*
 S_type_to_html(CFCClass *klass, CFCType *type);
@@ -939,7 +942,7 @@ S_md_to_html(const char *md, CFCClass *klass, int 
dir_level) {
                   | CMARK_OPT_VALIDATE_UTF8
                   | CMARK_OPT_SAFE;
     cmark_node *doc = cmark_parse_document(md, strlen(md), options);
-    S_convert_uris(doc, klass, dir_level);
+    S_transform_doc(doc, klass, dir_level);
     char *html = cmark_render_html(doc, CMARK_OPT_DEFAULT);
     cmark_node_free(doc);
 
@@ -947,25 +950,64 @@ S_md_to_html(const char *md, CFCClass *klass, int 
dir_level) {
 }
 
 static void
-S_convert_uris(cmark_node *node, CFCClass *klass, int dir_level) {
+S_transform_doc(cmark_node *node, CFCClass *klass, int dir_level) {
+    int found_matching_code_block = false;
     cmark_iter *iter = cmark_iter_new(node);
     cmark_event_type ev_type;
 
     while (CMARK_EVENT_DONE != (ev_type = cmark_iter_next(iter))) {
         cmark_node *cur = cmark_iter_get_node(iter);
+        cmark_node_type type = cmark_node_get_type(cur);
+
+        switch (type) {
+            case CMARK_NODE_CODE_BLOCK:
+                found_matching_code_block
+                    = S_transform_code_block(cur, found_matching_code_block);
+                break;
+
+            case CMARK_NODE_LINK:
+                if (ev_type == CMARK_EVENT_EXIT) {
+                    S_transform_link(cur, klass, dir_level);
+                }
+                break;
 
-        if (ev_type == CMARK_EVENT_EXIT
-            && cmark_node_get_type(cur) == NODE_LINK
-        ) {
-            S_convert_uri(cur, klass, dir_level);
+            default:
+                break;
         }
     }
 
     cmark_iter_free(iter);
 }
 
+static int
+S_transform_code_block(cmark_node *code_block, int found_matching_code_block) {
+    int is_host = CFCMarkdown_code_block_is_host(code_block, "c");
+
+    if (is_host) {
+        found_matching_code_block = true;
+    }
+
+    if (CFCMarkdown_code_block_is_last(code_block)) {
+        if (!found_matching_code_block) {
+            cmark_node *warning
+                = cmark_node_new(CMARK_NODE_CODE_BLOCK);
+            cmark_node_set_literal(warning,
+                                   "Code example for C is missing");
+            cmark_node_insert_after(code_block, warning);
+        }
+        else {
+            // Reset.
+            found_matching_code_block = false;
+        }
+    }
+
+    if (!is_host) { cmark_node_free(code_block); }
+
+    return found_matching_code_block;
+}
+
 static void
-S_convert_uri(cmark_node *link, CFCClass *klass, int dir_level) {
+S_transform_link(cmark_node *link, CFCClass *klass, int dir_level) {
     const char *uri_string = cmark_node_get_url(link);
     if (!uri_string || !CFCUri_is_clownfish_uri(uri_string)) {
         return;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7973bf5b/compiler/src/CFCCMan.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCMan.c b/compiler/src/CFCCMan.c
index 79248c8..6089ca3 100644
--- a/compiler/src/CFCCMan.c
+++ b/compiler/src/CFCCMan.c
@@ -427,6 +427,7 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int 
needs_indent) {
     int level      = needs_indent ? 1 : 0;
     int has_indent = needs_indent;
     int has_vspace = true;
+    int found_matching_code_block = false;
     cmark_iter *iter = cmark_iter_new(node);
     cmark_event_type ev_type;
 
@@ -497,23 +498,54 @@ S_nodes_to_man(CFCClass *klass, cmark_node *node, int 
needs_indent) {
                 break;
 
             case CMARK_NODE_CODE_BLOCK: {
-                if (level > 0) {
-                    result = CFCUtil_cat(result, ".RS\n", NULL);
-                }
+                int is_host = CFCMarkdown_code_block_is_host(node, "c");
 
-                const char *content = cmark_node_get_literal(node);
-                char *escaped = S_man_escape(content);
-                result = CFCUtil_cat(result, ".IP\n.nf\n.fam C\n", escaped,
-                                     ".fam\n.fi\n", NULL);
-                FREEMEM(escaped);
+                if (is_host) {
+                    found_matching_code_block = true;
 
-                if (level > 0) {
-                    result = CFCUtil_cat(result, ".RE\n", NULL);
-                    has_indent = false;
+                    if (level > 0) {
+                        result = CFCUtil_cat(result, ".RS\n", NULL);
+                    }
+
+                    const char *content = cmark_node_get_literal(node);
+                    char *escaped = S_man_escape(content);
+                    result = CFCUtil_cat(result, ".IP\n.nf\n.fam C\n", escaped,
+                                         ".fam\n.fi\n", NULL);
+                    FREEMEM(escaped);
+
+                    if (level > 0) {
+                        result = CFCUtil_cat(result, ".RE\n", NULL);
+                        has_indent = false;
+                    }
+                    else {
+                        has_indent = true;
+                        has_vspace = false;
+                    }
                 }
-                else {
-                    has_indent = true;
-                    has_vspace = false;
+
+                if (CFCMarkdown_code_block_is_last(node)) {
+                    if (!found_matching_code_block) {
+                        if (level > 0) {
+                            result = CFCUtil_cat(result, ".RS\n", NULL);
+                        }
+                        result = CFCUtil_cat(result,
+                            ".IP\n.nf\n.fam C\n"
+                            "Code example for Perl is missing\n",
+                            ".fam\n.fi\n",
+                            NULL);
+                        if (level > 0) {
+                            result = CFCUtil_cat(result, ".RE\n", NULL);
+                            has_indent = false;
+                        }
+                        else {
+                            has_indent = true;
+                            has_vspace = false;
+                        }
+                    }
+                    else {
+                        // Reset.
+                        found_matching_code_block = false;
+                    }
                 }
 
                 break;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7973bf5b/compiler/src/CFCDocuComment.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCDocuComment.c b/compiler/src/CFCDocuComment.c
index d88335f..ce59275 100644
--- a/compiler/src/CFCDocuComment.c
+++ b/compiler/src/CFCDocuComment.c
@@ -16,6 +16,7 @@
 
 #include <ctype.h>
 #include <string.h>
+#include <cmark.h>
 
 #define CFC_NEED_BASE_STRUCT_DEF
 #include "CFCBase.h"
@@ -253,3 +254,17 @@ CFCDocuComment_get_retval(CFCDocuComment *self) {
     return self->retval;
 }
 
+int
+CFCMarkdown_code_block_is_host(cmark_node *code_block, const char *lang) {
+    const char *fence_info = cmark_node_get_fence_info(code_block);
+    return !fence_info
+           || fence_info[0] == '\0'
+           || strcmp(fence_info, lang) == 0;
+}
+
+int
+CFCMarkdown_code_block_is_last(cmark_node *code_block) {
+    cmark_node *next = cmark_node_next(code_block);
+    return !next || cmark_node_get_type(next) != CMARK_NODE_CODE_BLOCK;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7973bf5b/compiler/src/CFCDocuComment.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCDocuComment.h b/compiler/src/CFCDocuComment.h
index 910f191..8b44c83 100644
--- a/compiler/src/CFCDocuComment.h
+++ b/compiler/src/CFCDocuComment.h
@@ -26,6 +26,8 @@ extern "C" {
 
 typedef struct CFCDocuComment CFCDocuComment;
 
+struct cmark_node;
+
 /** Parse comment text.
  */
 CFCDocuComment*
@@ -53,6 +55,13 @@ CFCDocuComment_get_param_docs(CFCDocuComment *self);
 const char*
 CFCDocuComment_get_retval(CFCDocuComment *self);
 
+int
+CFCMarkdown_code_block_is_host(struct cmark_node *code_block,
+                               const char *lang);
+
+int
+CFCMarkdown_code_block_is_last(struct cmark_node *code_block);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7973bf5b/compiler/src/CFCPerlPod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlPod.c b/compiler/src/CFCPerlPod.c
index 8fc2eae..fa221e4 100644
--- a/compiler/src/CFCPerlPod.c
+++ b/compiler/src/CFCPerlPod.c
@@ -340,6 +340,7 @@ S_nodes_to_pod(cmark_node *node, CFCClass *klass, int 
header_level) {
         return result;
     }
 
+    int found_matching_code_block = false;
     cmark_iter *iter = cmark_iter_new(node);
     cmark_event_type ev_type;
 
@@ -388,18 +389,37 @@ S_nodes_to_pod(cmark_node *node, CFCClass *klass, int 
header_level) {
                 break;
 
             case CMARK_NODE_CODE_BLOCK: {
-                const char *content = cmark_node_get_literal(node);
-                char *copy = CFCUtil_strdup(content);
-                // Chomp trailing newline.
-                size_t len = strlen(copy);
-                if (len > 0 && copy[len-1] == '\n') {
-                    copy[len-1] = '\0';
+                int is_host = CFCMarkdown_code_block_is_host(node, "perl");
+
+                if (is_host) {
+                    found_matching_code_block = true;
+
+                    const char *content = cmark_node_get_literal(node);
+                    char *copy = CFCUtil_strdup(content);
+                    // Chomp trailing newline.
+                    size_t len = strlen(copy);
+                    if (len > 0 && copy[len-1] == '\n') {
+                        copy[len-1] = '\0';
+                    }
+                    char *indented
+                        = CFCUtil_global_replace(copy, "\n", "\n    ");
+                    result
+                        = CFCUtil_cat(result, "    ", indented, "\n\n", NULL);
+                    FREEMEM(indented);
+                    FREEMEM(copy);
+                }
+
+                if (CFCMarkdown_code_block_is_last(node)) {
+                    if (!found_matching_code_block) {
+                        result = CFCUtil_cat(result,
+                            "    Code example for Perl is missing\n\n");
+                    }
+                    else {
+                        // Reset.
+                        found_matching_code_block = false;
+                    }
                 }
-                char *indented
-                    = CFCUtil_global_replace(copy, "\n", "\n    ");
-                result = CFCUtil_cat(result, "    ", indented, "\n\n", NULL);
-                FREEMEM(indented);
-                FREEMEM(copy);
+
                 break;
             }
 

Reply via email to