]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Add support for manual labels on ATX Headers
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Fri, 10 Feb 2017 03:37:05 +0000 (22:37 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Fri, 10 Feb 2017 03:37:05 +0000 (22:37 -0500)
src/html.c
src/libMultiMarkdown.h
src/writer.c
src/writer.h
tests/MMD6Tests/Advanced Headers.html [new file with mode: 0644]
tests/MMD6Tests/Advanced Headers.htmlc [new file with mode: 0644]
tests/MMD6Tests/Advanced Headers.text [new file with mode: 0644]

index 29001e193efee32fc910a57e11737d923c87e5da..11769a6c7ccb739cfa1249abbe88b34e29d05244 100644 (file)
@@ -415,7 +415,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        if (scratch->extensions & EXT_NO_LABELS) {
                                printf("<h%1d>", temp_short + scratch->base_header_level - 1);
                        } else {
-                               temp_char = label_from_token(source, t);
+                               temp_token = manual_label_from_header(t, source);
+                               if (temp_token) {
+                                       temp_char = label_from_token(source, temp_token);
+                               } else {
+                                       temp_char = label_from_token(source, t);
+                               }
                                printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
                                free(temp_char);
                        }
@@ -1267,6 +1272,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case CODE_FENCE:
                case TEXT_EMPTY:
+               case MANUAL_LABEL:
                        break;
                case TEXT_NL:
                        if (t->next)
index 17d58ea696a5c3cb50e94067afa26d5a57bf91a6..c1bcf3d146e09d89c5f501b8137cd1ada61c6205 100644 (file)
@@ -270,6 +270,8 @@ enum token_types {
        TEXT_NUMBER_POSS_LIST,
        TEXT_PERIOD,
        TEXT_PLAIN,
+
+       MANUAL_LABEL,
 };
 
 
index 432ccf6e067df86f3d78cacf0461e2f54b2c71cd..7f8e53f96400fb3149265c48ee022469457b9f70 100644 (file)
@@ -1110,10 +1110,69 @@ void process_definition_stack(mmd_engine * e) {
        }
 }
 
+token * manual_label_from_header(token * h, const char * source) {
+       token * walker = h->child->tail;
+       token * label = NULL;
+       short count = 0;
+
+       while (walker) {
+               switch (walker->type) {
+                       case MANUAL_LABEL:
+                               // Already identified
+                               label = walker;
+                               walker = NULL;
+                               break;
+                       case INDENT_TAB:
+                       case INDENT_SPACE:
+                       case NON_INDENT_SPACE:
+                       case TEXT_NL:
+                       case TEXT_LINEBREAK:
+                       case TEXT_EMPTY:
+                               walker = walker->prev;
+                               break;
+                       case TEXT_PLAIN:
+                               if (walker->len == 1) {
+                                       if (source[walker->start] == ' ') {
+                                               walker = walker->prev;
+                                               break;
+                                       }
+                               }
+                               walker = NULL;
+                               break;
+                       case PAIR_BRACKET:
+                               label = walker;
+                               while(walker->type == PAIR_BRACKET) {
+                                       walker = walker->prev;
+                                       count++;
+                               }
+                               if (count % 2 == 0) {
+                                       // Even count
+                                       label = NULL;
+                               } else {
+                                       // Odd count
+                                       label->type = MANUAL_LABEL;
+                               }
+                       default:
+                               walker = NULL;
+               }
+       }
+
+       return label;
+}
+
 
 void process_header_to_links(mmd_engine * e, token * h) {
        char * label = label_from_token(e->dstr->str, h);
 
+       // See if we have a manual label
+       token * manual = manual_label_from_header(h, e->dstr->str);
+
+       if (manual) {
+               free(label);
+               label = label_from_token(e->dstr->str, manual);
+               h = manual;
+       }
+
        DString * url = d_string_new("#");
 
        d_string_append(url, label);
index faf8d7c4d4df69c3c6218b643dc3d21ae2139f8e..fa3f5b49f10c83ba6550e7ca0ff752757c31699c 100644 (file)
@@ -207,5 +207,7 @@ bool table_has_caption(token * table);
 
 char * get_fence_language_specifier(token * fence, const char * source);
 
+token * manual_label_from_header(token * h, const char * source);
+
 #endif
 
diff --git a/tests/MMD6Tests/Advanced Headers.html b/tests/MMD6Tests/Advanced Headers.html
new file mode 100644 (file)
index 0000000..b3bb99a
--- /dev/null
@@ -0,0 +1,11 @@
+<h1 id="bar">foo  </h1>
+
+<h1 id="bar">foo</h1>
+
+<h1 id="foobarbat">foo <a href="#bat">bar</a></h1>
+
+<h1 id="bat">foo <a href="#bar">bar</a> </h1>
+
+<h1 id="baz">foo <a href="#bat">bar</a></h1>
+
+<p>5</p>
diff --git a/tests/MMD6Tests/Advanced Headers.htmlc b/tests/MMD6Tests/Advanced Headers.htmlc
new file mode 100644 (file)
index 0000000..0a8e69e
--- /dev/null
@@ -0,0 +1,11 @@
+<h1>foo [bar] </h1>
+
+<h1>foo[bar]</h1>
+
+<h1>foo [bar][bat]</h1>
+
+<h1>foo [bar] [bat]</h1>
+
+<h1>foo [bar][bat][baz]</h1>
+
+<p>5</p>
diff --git a/tests/MMD6Tests/Advanced Headers.text b/tests/MMD6Tests/Advanced Headers.text
new file mode 100644 (file)
index 0000000..949dab6
--- /dev/null
@@ -0,0 +1,11 @@
+# foo [bar] #
+
+# foo[bar]
+
+# foo [bar][bat]
+
+# foo [bar] [bat]
+
+# foo [bar][bat][baz]
+
+5