]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Improve performance when exporting
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Sat, 18 Feb 2017 21:16:09 +0000 (16:16 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Sat, 18 Feb 2017 21:16:09 +0000 (16:16 -0500)
src/beamer.c
src/html.c
src/latex.c
src/memoir.c
src/mmd.c
src/transclude.c
src/writer.c

index 4bc61575dfa1b71059fbdd5e878749a14603929b..bb6d8306209194e1206493a7d189ecc94692fad4 100644 (file)
@@ -57,6 +57,7 @@
 #include "beamer.h"
 
 #define print(x) d_string_append(out, x)
+#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
 #define print_char(x) d_string_append_c(out, x)
 #define printf(...) d_string_append_printf(out, __VA_ARGS__)
 #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
@@ -108,12 +109,12 @@ void mmd_outline_add_beamer(DString * out, token * current, scratch_pad * scratc
                                switch (t_level) {
                                        case 3:
                                                pad(out, 1, scratch);
-                                               print("\\end{frame}\n\n");
+                                               print_const("\\end{frame}\n\n");
                                                scratch->padded = 2;
                                                break;
                                        case 4:
                                                pad(out, 1, scratch);
-                                               print("}\n\n");
+                                               print_const("}\n\n");
                                                scratch->padded = 2;
                                                break;
                                }
@@ -132,13 +133,13 @@ void mmd_outline_add_beamer(DString * out, token * current, scratch_pad * scratc
        switch (level) {
                case 3:
                        pad(out, 2, scratch);
-                       print("\\begin{frame}[fragile]\n");
+                       print_const("\\begin{frame}[fragile]\n");
                        scratch->padded = 1;
                        stack_push(s, current);
                        break;
                case 4:
                        pad(out, 2, scratch);
-                       print("\\mode<article>{");
+                       print_const("\\mode<article>{");
                        scratch->padded = 0;
                        stack_push(s, current);
                        break;
@@ -165,24 +166,24 @@ void mmd_export_token_beamer(DString * out, const char * source, token * t, scra
                        if (temp_char) {
                                printf("\\begin{lstlisting}[language=%s]\n", temp_char);
                        } else {
-                               print("\\begin{verbatim}\n");
+                               print_const("\\begin{verbatim}\n");
                        }
 
                        mmd_export_token_tree_latex_raw(out, source, t->child->next, scratch);
 
                        if (temp_char) {
-                               print("\\end{lstlisting}");
+                               print_const("\\end{lstlisting}");
                                free(temp_char);
                        } else {
-                               print("\\end{verbatim}");
+                               print_const("\\end{verbatim}");
                        }
                        scratch->padded = 0;
                        break;
                case BLOCK_CODE_INDENTED:
                        pad(out, 2, scratch);
-                       print("\\begin{verbatim}\n");
+                       print_const("\\begin{verbatim}\n");
                        mmd_export_token_tree_latex_raw(out, source, t->child, scratch);
-                       print("\\end{verbatim}");
+                       print_const("\\end{verbatim}");
                        scratch->padded = 0;
                        break;
                case BLOCK_H1:
@@ -210,23 +211,23 @@ void mmd_export_token_beamer(DString * out, const char * source, token * t, scra
 
                        switch (temp_short + scratch->base_header_level - 1) {
                                case 1:
-                                       print("\\part{");
+                                       print_const("\\part{");
                                        break;
                                case 2:
-                                       print("\\section{");
+                                       print_const("\\section{");
                                        break;
                                case 3:
-                                       print("\\frametitle{");
+                                       print_const("\\frametitle{");
                                        break;
                                default:
-                                       print("\\emph{");
+                                       print_const("\\emph{");
                                        break;
                        }
 
                        mmd_export_token_tree_beamer(out, source, t->child, scratch);
 
                        if (scratch->extensions & EXT_NO_LABELS) {
-                               print("}");
+                               print_const("}");
                        } else {
                                temp_token = manual_label_from_header(t, source);
                                if (temp_token) {
@@ -277,7 +278,7 @@ void mmd_export_citation_list_beamer(DString * out, const char * source, scratch
                token * content;
 
                pad(out, 2, scratch);
-               print("\\part{Bibliography}\n\\begin{frame}[allowframebreaks]\n\\frametitle{Bibliography}\n\\def\\newblock{}\n\\begin{thebibliography}{0}");
+               print_const("\\part{Bibliography}\n\\begin{frame}[allowframebreaks]\n\\frametitle{Bibliography}\n\\def\\newblock{}\n\\begin{thebibliography}{0}");
                scratch->padded = 0;
 
                for (int i = 0; i < scratch->used_citations->size; ++i)
@@ -299,7 +300,7 @@ void mmd_export_citation_list_beamer(DString * out, const char * source, scratch
                }
 
                pad(out, 1, scratch);
-               print("\\end{thebibliography}\n\\end{frame}");
+               print_const("\\end{thebibliography}\n\\end{frame}");
                scratch->padded = 0;
                scratch->citation_being_printed = 0;
        }
@@ -309,14 +310,14 @@ void mmd_export_citation_list_beamer(DString * out, const char * source, scratch
 void mmd_end_complete_beamer(DString * out, const char * source, scratch_pad * scratch) {
        pad(out, 2, scratch);
 
-       print("\\mode<all>\n");
+       print_const("\\mode<all>\n");
        meta * m = extract_meta_from_stack(scratch, "latexfooter");
 
        if (m) {
                printf("\\input{%s}\n\n", m->value);
        }
 
-       print("\\end{document}");
-       print("\\mode*\n");
+       print_const("\\end{document}");
+       print_const("\\mode*\n");
        scratch->padded = 0;
 }
index b7838e778ccc8f5ee2c52ed12f1936b05fbcf1df..527b1a5a8bd35d02381475b04bba96ab87d66010 100644 (file)
@@ -68,6 +68,7 @@
 
 
 #define print(x) d_string_append(out, x)
+#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
 #define print_char(x) d_string_append_c(out, x)
 #define printf(...) d_string_append_printf(out, __VA_ARGS__)
 #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
@@ -79,16 +80,16 @@ long ran_num_next();
 void mmd_print_char_html(DString * out, char c, bool obfuscate) {
        switch (c) {
                case '"':
-                       print("&quot;");
+                       print_const("&quot;");
                        break;
                case '&':
-                       print("&amp;");
+                       print_const("&amp;");
                        break;
                case '<':
-                       print("&lt;");
+                       print_const("&lt;");
                        break;
                case '>':
-                       print("&gt;");
+                       print_const("&gt;");
                        break;
                default:
                        if (obfuscate && ((int) c == (((int) c) & 127))) {
@@ -115,16 +116,16 @@ void mmd_print_string_html(DString * out, const char * str, bool obfuscate) {
 void mmd_print_localized_char_html(DString * out, unsigned short type, scratch_pad * scratch) {
        switch (type) {
                case DASH_N:
-                       print("&#8211;");
+                       print_const("&#8211;");
                        break;
                case DASH_M:
-                       print("&#8212;");
+                       print_const("&#8212;");
                        break;
                case ELLIPSIS:
-                       print("&#8230;");
+                       print_const("&#8230;");
                        break;
                case APOSTROPHE:
-                       print("&#8217;");
+                       print_const("&#8217;");
                        break;
                case QUOTE_LEFT_SINGLE:
                        switch (scratch->quotes_lang) {
@@ -132,64 +133,64 @@ void mmd_print_localized_char_html(DString * out, unsigned short type, scratch_p
                                        print( "&#8217;");
                                        break;
                                case FRENCH:
-                                       print("&#39;");
+                                       print_const("&#39;");
                                        break;
                                case GERMAN:
-                                       print("&#8218;");
+                                       print_const("&#8218;");
                                        break;
                                case GERMANGUILL:
-                                       print("&#8250;");
+                                       print_const("&#8250;");
                                        break;
                                default:
-                                       print("&#8216;");
+                                       print_const("&#8216;");
                                }
                        break;
                case QUOTE_RIGHT_SINGLE:
                        switch (scratch->quotes_lang) {
                                case GERMAN:
-                                       print("&#8216;");
+                                       print_const("&#8216;");
                                        break;
                                case GERMANGUILL:
-                                       print("&#8249;");
+                                       print_const("&#8249;");
                                        break;
                                default:
-                                       print("&#8217;");
+                                       print_const("&#8217;");
                                }
                        break;
                case QUOTE_LEFT_DOUBLE:
                        switch (scratch->quotes_lang) {
                                case DUTCH:
                                case GERMAN:
-                                       print("&#8222;");
+                                       print_const("&#8222;");
                                        break;
                                case GERMANGUILL:
-                                       print("&#187;");
+                                       print_const("&#187;");
                                        break;
                                case FRENCH:
-                                       print("&#171;");
+                                       print_const("&#171;");
                                        break;
                                case SWEDISH:
                                        print( "&#8221;");
                                        break;
                                default:
-                                       print("&#8220;");
+                                       print_const("&#8220;");
                                }
                        break;
                case QUOTE_RIGHT_DOUBLE:
                        switch (scratch->quotes_lang) {
                                case GERMAN:
-                                       print("&#8220;");
+                                       print_const("&#8220;");
                                        break;
                                case GERMANGUILL:
-                                       print("&#171;");
+                                       print_const("&#171;");
                                        break;
                                case FRENCH:
-                                       print("&#187;");
+                                       print_const("&#187;");
                                        break;
                                case SWEDISH:
                                case DUTCH:
                                default:
-                                       print("&#8221;");
+                                       print_const("&#8221;");
                                }
                        break;
        }
@@ -200,28 +201,28 @@ void mmd_export_link_html(DString * out, const char * source, token * text, link
        attr * a = link->attributes;
 
        if (link->url) {
-               print("<a href=\"");
+               print_const("<a href=\"");
                mmd_print_string_html(out, link->url, false);
-               print("\"");
+               print_const("\"");
        } else
-               print("<a href=\"\"");
+               print_const("<a href=\"\"");
 
        if (link->title && link->title[0] != '\0') {
-               print(" title=\"");
+               print_const(" title=\"");
                mmd_print_string_html(out, link->title, false);
-               print("\"");
+               print_const("\"");
        }
 
        while (a) {
-               print(" ");
+               print_const(" ");
                print(a->key);
-               print("=\"");
+               print_const("=\"");
                print(a->value);
-               print("\"");
+               print_const("\"");
                a = a->next;
        }
 
-       print(">");
+       print_const(">");
 
        // If we're printing contents of bracket as text, then ensure we include it all
        if (text && text->child && text->child->len > 1) {
@@ -231,7 +232,7 @@ void mmd_export_link_html(DString * out, const char * source, token * text, link
        
        mmd_export_token_tree_html(out, source, text->child, offset, scratch);
 
-       print("</a>");
+       print_const("</a>");
 }
 
 
@@ -245,19 +246,19 @@ void mmd_export_image_html(DString * out, const char * source, token * text, lin
        if (is_figure) {
                // Remove wrapping <p> markers
                d_string_erase(out, out->currentStringLength - 3, 3);
-               print("<figure>\n");
+               print_const("<figure>\n");
                scratch->close_para = false;
        }
 
        if (link->url)
                printf("<img src=\"%s\"", link->url);
        else
-               print("<img src=\"\"");
+               print_const("<img src=\"\"");
 
        if (text) {
-               print(" alt=\"");
+               print_const(" alt=\"");
                print_token_tree_raw(out, source, text->child);
-               print("\"");
+               print_const("\"");
        }
 
        if (link->label && !(scratch->extensions & EXT_COMPATIBILITY)) {
@@ -271,23 +272,23 @@ void mmd_export_image_html(DString * out, const char * source, token * text, lin
                printf(" title=\"%s\"", link->title);
 
        while (a) {
-               print(" ");
+               print_const(" ");
                print(a->key);
-               print("=\"");
+               print_const("=\"");
                print(a->value);
-               print("\"");
+               print_const("\"");
                a = a->next;
        }
 
-       print(" />");
+       print_const(" />");
 
        if (is_figure) {
                if (text) {
-                       print("\n<figcaption>");
+                       print_const("\n<figcaption>");
                        mmd_export_token_tree_html(out, source, text->child, offset, scratch);
-                       print("</figcaption>");
+                       print_const("</figcaption>");
                }
-               print("\n</figure>");
+               print_const("\n</figure>");
        }
 }
 
@@ -307,13 +308,13 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
        switch (t->type) {
                case AMPERSAND:
                case AMPERSAND_LONG:
-                       print("&amp;");
+                       print_const("&amp;");
                        break;
                case ANGLE_LEFT:
-                       print("&lt;");
+                       print_const("&lt;");
                        break;
                case ANGLE_RIGHT:
-                       print("&gt;");
+                       print_const("&gt;");
                        break;
                case APOSTROPHE:
                        if (!(scratch->extensions & EXT_SMART)) {
@@ -332,30 +333,30 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        print_localized(QUOTE_LEFT_DOUBLE);
                                }
                        else if (t->start < t->mate->start) {
-                               print("<code>");
+                               print_const("<code>");
                        } else {
-                               print("</code>");
+                               print_const("</code>");
                        }
                        break;
                case BLOCK_BLOCKQUOTE:
                        pad(out, 2, scratch);
-                       print("<blockquote>\n");
+                       print_const("<blockquote>\n");
                        scratch->padded = 2;
                        mmd_export_token_tree_html(out, source, t->child, t->start + offset, scratch);
                        pad(out, 1, scratch);
-                       print("</blockquote>");
+                       print_const("</blockquote>");
                        scratch->padded = 0;
                        break;
                case BLOCK_DEFINITION:
                        pad(out, 2, scratch);
-                       print("<dd>");
+                       print_const("<dd>");
 
                        temp_short = scratch->list_is_tight;
                        if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
                                scratch->list_is_tight = true;
 
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                       print("</dd>");
+                       print_const("</dd>");
                        scratch->padded = 0;
 
                        scratch->list_is_tight = temp_short;
@@ -367,7 +368,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        // lemon's LALR(1) parser can't properly handle this (to my understanding).
 
                        if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
-                               print("<dl>\n");
+                               print_const("<dl>\n");
        
                        scratch->padded = 2;
 
@@ -375,13 +376,13 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        pad(out, 1, scratch);
 
                        if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
-                               print("</dl>\n");
+                               print_const("</dl>\n");
 
                        scratch->padded = 1;
                        break;
                case BLOCK_CODE_FENCED:
                        pad(out, 2, scratch);
-                       print("<pre><code");
+                       print_const("<pre><code");
 
                        temp_char = get_fence_language_specifier(t->child->child, source);
                        if (temp_char) {
@@ -389,16 +390,16 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                free(temp_char);
                        }
 
-                       print(">");
+                       print_const(">");
                        mmd_export_token_tree_html_raw(out, source, t->child->next, t->start + offset, scratch);
-                       print("</code></pre>");
+                       print_const("</code></pre>");
                        scratch->padded = 0;
                        break;
                case BLOCK_CODE_INDENTED:
                        pad(out, 2, scratch);
-                       print("<pre><code>");
+                       print_const("<pre><code>");
                        mmd_export_token_tree_html_raw(out, source, t->child, t->start + offset, scratch);
-                       print("</code></pre>");
+                       print_const("</code></pre>");
                        scratch->padded = 0;
                        break;
                case BLOCK_EMPTY:
@@ -424,7 +425,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case BLOCK_HR:
                        pad(out, 2, scratch);
-                       print("<hr />");
+                       print_const("<hr />");
                        scratch->padded = 0;
                        break;
                case BLOCK_HTML:
@@ -444,11 +445,11 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        break;
                        }
                        pad(out, 2, scratch);
-                       print("<ul>");
+                       print_const("<ul>");
                        scratch->padded = 0;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        pad(out, 1, scratch);
-                       print("</ul>");
+                       print_const("</ul>");
                        scratch->padded = 0;
                        scratch->list_is_tight = temp_short;
                        break;
@@ -464,40 +465,40 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        break;
                        }
                        pad(out, 2, scratch);
-                       print("<ol>");
+                       print_const("<ol>");
                        scratch->padded = 0;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        pad(out, 1, scratch);
-                       print("</ol>");
+                       print_const("</ol>");
                        scratch->padded = 0;
                        scratch->list_is_tight = temp_short;
                        break;
                case BLOCK_LIST_ITEM:
                        pad(out, 1, scratch);
-                       print("<li>");
+                       print_const("<li>");
                        scratch->padded = 2;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                       print("</li>");
+                       print_const("</li>");
                        scratch->padded = 0;
                        break;
                case BLOCK_LIST_ITEM_TIGHT:
                        pad(out, 1, scratch);
-                       print("<li>");
+                       print_const("<li>");
 
                        if (!scratch->list_is_tight)
-                               print("<p>");
+                               print_const("<p>");
 
                        scratch->padded = 2;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
 
                        if (scratch->close_para) {
                                if (!scratch->list_is_tight)
-                                       print("</p>");
+                                       print_const("</p>");
                        } else {
                                scratch->close_para = true;
                        }
 
-                       print("</li>");
+                       print_const("</li>");
                        scratch->padded = 0;
                        break;
                case BLOCK_META:
@@ -508,7 +509,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        pad(out, 2, scratch);
        
                        if (!scratch->list_is_tight)
-                               print("<p>");
+                               print_const("<p>");
 
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
 
@@ -530,7 +531,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
 
                        if (scratch->close_para) {
                                if (!scratch->list_is_tight)
-                                       print("</p>");
+                                       print_const("</p>");
                        } else {
                                scratch->close_para = true;
                        }
@@ -576,7 +577,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case BLOCK_TABLE:
                        pad(out, 2, scratch);
-                       print("<table>\n");
+                       print_const("<table>\n");
 
                        // Are we followed by a caption?
                        if (table_has_caption(t)) {
@@ -594,7 +595,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                t->next->child->child->type = TEXT_EMPTY;
                                t->next->child->child->mate->type = TEXT_EMPTY;
                                mmd_export_token_tree_html(out, source, t->next->child->child, offset, scratch);
-                               print("</caption>\n");
+                               print_const("</caption>\n");
                                temp_short = 1;
                        } else {
                                temp_short = 0;
@@ -603,39 +604,39 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        scratch->padded = 2;
                        read_table_column_alignments(source, t, scratch);
 
-                       print("<colgroup>\n");
+                       print_const("<colgroup>\n");
                        for (int i = 0; i < scratch->table_column_count; ++i)
                        {
                                switch (scratch->table_alignment[i]) {
                                        case 'l':
-                                               print("<col style=\"text-align:left;\"/>\n");
+                                               print_const("<col style=\"text-align:left;\"/>\n");
                                                break;
                                        case 'L':
-                                               print("<col style=\"text-align:left;\" class=\"extended\"/>\n");
+                                               print_const("<col style=\"text-align:left;\" class=\"extended\"/>\n");
                                                break;
                                        case 'r':
-                                               print("<col style=\"text-align:right;\"/>\n");
+                                               print_const("<col style=\"text-align:right;\"/>\n");
                                                break;
                                        case 'R':
-                                               print("<col style=\"text-align:right;\" class=\"extended\"/>\n");
+                                               print_const("<col style=\"text-align:right;\" class=\"extended\"/>\n");
                                                break;
                                        case 'c':
-                                               print("<col style=\"text-align:center;\"/>\n");
+                                               print_const("<col style=\"text-align:center;\"/>\n");
                                                break;
                                        case 'C':
-                                               print("<col style=\"text-align:center;\" class=\"extended\"/>\n");
+                                               print_const("<col style=\"text-align:center;\" class=\"extended\"/>\n");
                                                break;
                                        default:
-                                               print("<col />\n");
+                                               print_const("<col />\n");
                                                break;
                                }
                        }
-                       print("</colgroup>\n");
+                       print_const("</colgroup>\n");
                        scratch->padded = 1;
 
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        pad(out, 1, scratch);
-                       print("</table>");
+                       print_const("</table>");
                        scratch->padded = 0;
 
                        scratch->skip_token = temp_short;
@@ -643,33 +644,33 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case BLOCK_TABLE_HEADER:
                        pad(out, 2, scratch);
-                       print("<thead>\n");
+                       print_const("<thead>\n");
                        scratch->in_table_header = 1;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        scratch->in_table_header = 0;
-                       print("</thead>\n");
+                       print_const("</thead>\n");
                        scratch->padded = 1;
                        break;
                case BLOCK_TABLE_SECTION:
                        pad(out, 2, scratch);
-                       print("<tbody>\n");
+                       print_const("<tbody>\n");
                        scratch->padded = 2;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                       print("</tbody>");
+                       print_const("</tbody>");
                        scratch->padded = 0;
                        break;
                case BLOCK_TERM:
                        pad(out, 2, scratch);
-                       print("<dt>");
+                       print_const("<dt>");
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                       print("</dt>\n");
+                       print_const("</dt>\n");
                        scratch->padded = 2;
                        break;
                case BLOCK_TOC:
                        temp_short = 0;
                        temp_short2 = 0;
                        pad(out, 2, scratch);
-                       print("<div class=\"TOC\">");
+                       print_const("<div class=\"TOC\">");
 
                        for (int i = 0; i < scratch->header_stack->size; ++i)
                        {
@@ -677,12 +678,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
 
                                if (temp_token->type == temp_short2) {
                                        // Same level -- close list item
-                                       print("</li>\n");
+                                       print_const("</li>\n");
                                }
 
                                if (temp_short == 0) {
                                        // First item
-                                       print("\n<ul>\n");
+                                       print_const("\n<ul>\n");
                                        temp_short = temp_token->type;
                                        temp_short2 = temp_short;
                                }
@@ -692,14 +693,14 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        // Same level -- NTD
                                } else if (temp_token->type == temp_short2 + 1) {
                                        // Indent
-                                       print("\n\n<ul>\n");
+                                       print_const("\n\n<ul>\n");
                                        temp_short2++;
                                } else if (temp_token->type < temp_short2) {
                                        // Outdent
-                                       print("</li>\n");
+                                       print_const("</li>\n");
                                        while (temp_short2 > temp_token->type) {
                                                if (temp_short2 > temp_short)
-                                                       print("</ul></li>\n");
+                                                       print_const("</ul></li>\n");
                                                else
                                                        temp_short = temp_short2 - 1;
 
@@ -714,80 +715,80 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
 
                                printf("<li><a href=\"#%s\">", temp_char);
                                mmd_export_token_tree_html(out, source, temp_token->child, offset, scratch);
-                               print("</a>");
+                               print_const("</a>");
                                free(temp_char);
                        }
 
                        while (temp_short2 > (temp_short)) {
-                               print("</ul>\n");
+                               print_const("</ul>\n");
                                temp_short2--;
                        }
                        
                        if (temp_short)
-                               print("</li>\n</ul>\n");
+                               print_const("</li>\n</ul>\n");
 
-                       print("</div>");
+                       print_const("</div>");
                        scratch->padded = 0;
                        break;
                case BRACE_DOUBLE_LEFT:
-                       print("{{");
+                       print_const("{{");
                        break;
                case BRACE_DOUBLE_RIGHT:
-                       print("}}");
+                       print_const("}}");
                        break;
                case BRACKET_LEFT:
-                       print("[");                     
+                       print_const("[");                       
                        break;
                case BRACKET_CITATION_LEFT:
-                       print("[#");
+                       print_const("[#");
                        break;
                case BRACKET_FOOTNOTE_LEFT:
-                       print("[^");
+                       print_const("[^");
                        break;
                case BRACKET_IMAGE_LEFT:
-                       print("![");
+                       print_const("![");
                        break;
                case BRACKET_VARIABLE_LEFT:
-                       print("[\%");
+                       print_const("[\%");
                        break;
                case BRACKET_RIGHT:
-                       print("]");
+                       print_const("]");
                        break;
                case COLON:
-                       print(":");
+                       print_const(":");
                        break;
                case CRITIC_ADD_OPEN:
-                       print("{++");
+                       print_const("{++");
                        break;
                case CRITIC_ADD_CLOSE:
-                       print("++}");
+                       print_const("++}");
                        break;
                case CRITIC_COM_OPEN:
-                       print("{&gt;&gt;");
+                       print_const("{&gt;&gt;");
                        break;
                case CRITIC_COM_CLOSE:
-                       print("&lt;&lt;}");
+                       print_const("&lt;&lt;}");
                        break;
                case CRITIC_DEL_OPEN:
-                       print("{--");
+                       print_const("{--");
                        break;
                case CRITIC_DEL_CLOSE:
-                       print("--}");
+                       print_const("--}");
                        break;
                case CRITIC_HI_OPEN:
-                       print("{==");
+                       print_const("{==");
                        break;
                case CRITIC_HI_CLOSE:
-                       print("==}");
+                       print_const("==}");
                        break;
                case CRITIC_SUB_OPEN:
-                       print("{~~");
+                       print_const("{~~");
                        break;
                case CRITIC_SUB_DIV:
-                       print("~&gt;");
+                       print_const("~&gt;");
                        break;
                case CRITIC_SUB_CLOSE:
-                       print("~~}");
+                       print_const("~~}");
                        break;
                case DASH_M:
                        if (!(scratch->extensions & EXT_SMART)) {
@@ -814,18 +815,18 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        }
                        break;
                case EMPH_START:
-                       print("<em>");
+                       print_const("<em>");
                        break;
                case EMPH_STOP:
-                       print("</em>");
+                       print_const("</em>");
                        break;
                case EQUAL:
-                       print("=");
+                       print_const("=");
                        break;
                case ESCAPED_CHARACTER:
                        if (!(scratch->extensions & EXT_COMPATIBILITY) &&
                                (source[t->start + 1] == ' ')) {
-                               print("&nbsp;");
+                               print_const("&nbsp;");
                        } else {
                                mmd_print_char_html(out, source[t->start + 1], false);
                        }
@@ -861,41 +862,41 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case MATH_BRACKET_OPEN:
                        if (t->mate) {
-                               print("<span class=\"math\">\\[");
+                               print_const("<span class=\"math\">\\[");
                        } else
-                               print("\\[");
+                               print_const("\\[");
                        break;
                case MATH_BRACKET_CLOSE:
                        if (t->mate) {
-                               print("\\]</span>");
+                               print_const("\\]</span>");
                        } else
-                               print("\\]");
+                               print_const("\\]");
                        break;
                case MATH_DOLLAR_SINGLE:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? ( print("<span class=\"math\">\\(") ) : ( print("\\)</span>") );
+                               (t->start < t->mate->start) ? ( print_const("<span class=\"math\">\\(") ) : ( print_const("\\)</span>") );
                        } else {
-                               print("$");
+                               print_const("$");
                        }
                        break;
                case MATH_DOLLAR_DOUBLE:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? ( print("<span class=\"math\">\\[") ) : ( print("\\]</span>") );
+                               (t->start < t->mate->start) ? ( print_const("<span class=\"math\">\\[") ) : ( print_const("\\]</span>") );
                        } else {
-                               print("$$");
+                               print_const("$$");
                        }
                        break;
                case MATH_PAREN_OPEN:
                        if (t->mate) {
-                               print("<span class=\"math\">\\(");
+                               print_const("<span class=\"math\">\\(");
                        } else
-                               print("\\(");
+                               print_const("\\(");
                        break;
                case MATH_PAREN_CLOSE:
                        if (t->mate) {
-                               print("\\)</span>");
+                               print_const("\\)</span>");
                        } else
-                               print("\\)");
+                               print_const("\\)");
                        break;
                case NON_INDENT_SPACE:
                        print_char(' ');
@@ -933,9 +934,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        }
                        t->child->type = TEXT_EMPTY;
                        t->child->mate->type = TEXT_EMPTY;
-                       print("<code>");
+                       print_const("<code>");
                        mmd_export_token_tree_html_raw(out, source, t->child, offset, scratch);
-                       print("</code>");
+                       print_const("</code>");
                        break;
                case PAIR_ANGLE:
                        temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
@@ -945,11 +946,11 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        temp_bool = true;
                                else
                                        temp_bool = false;
-                               print("<a href=\"");
+                               print_const("<a href=\"");
                                mmd_print_string_html(out, temp_char, temp_bool);
-                               print("\">");
+                               print_const("\">");
                                mmd_print_string_html(out, temp_char, temp_bool);
-                               print("</a>");
+                               print_const("</a>");
                        } else if (scan_html(&source[t->start])) {
                                print_token(t);
                        } else {
@@ -1107,9 +1108,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                if (scratch->extensions & EXT_CRITIC_ACCEPT) {
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                                } else {
-                                       print("<ins>");
+                                       print_const("<ins>");
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                                       print("</ins>");
+                                       print_const("</ins>");
                                }
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);                             
@@ -1125,9 +1126,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                if (scratch->extensions & EXT_CRITIC_REJECT) {
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                                } else {
-                                       print("<del>");
+                                       print_const("<del>");
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                                       print("</del>");
+                                       print_const("</del>");
                                }
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);                             
@@ -1141,9 +1142,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        if (scratch->extensions & EXT_CRITIC) {
                                t->child->type = TEXT_EMPTY;
                                t->child->mate->type = TEXT_EMPTY;
-                               print("<span class=\"critic comment\">");
+                               print_const("<span class=\"critic comment\">");
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                               print("</span>");
+                               print_const("</span>");
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        }
@@ -1156,18 +1157,18 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        if (scratch->extensions & EXT_CRITIC) {
                                t->child->type = TEXT_EMPTY;
                                t->child->mate->type = TEXT_EMPTY;
-                               print("<mark>");
+                               print_const("<mark>");
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                               print("</mark>");
+                               print_const("</mark>");
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        }
                        break;
                case CRITIC_SUB_DIV_A:
-                       print("~");
+                       print_const("~");
                        break;
                case CRITIC_SUB_DIV_B:
-                       print("&gt;");
+                       print_const("&gt;");
                        break;
                case PAIR_CRITIC_SUB_DEL:
                        if ((scratch->extensions & EXT_CRITIC) &&
@@ -1179,9 +1180,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                } else if (scratch->extensions & EXT_CRITIC_REJECT) {
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                                } else {
-                                       print("<del>");
+                                       print_const("<del>");
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                                       print("</del>");
+                                       print_const("</del>");
                                }
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
@@ -1197,9 +1198,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                } else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                                } else {
-                                       print("<ins>");
+                                       print_const("<ins>");
                                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                                       print("</ins>");
+                                       print_const("</ins>");
                                }
                        } else {
                                mmd_export_token_tree_html(out, source, t->child, offset, scratch);
@@ -1214,10 +1215,10 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        break;
                case PAREN_LEFT:
-                       print("(");
+                       print_const("(");
                        break;
                case PAREN_RIGHT:
-                       print(")");
+                       print_const(")");
                        break;
                case PIPE:
                        print_token(t);
@@ -1227,19 +1228,19 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        break;
                case QUOTE_SINGLE:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("'");
+                               print_const("'");
                        else
                                (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
                        break;
                case QUOTE_DOUBLE:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("&quot;");
+                               print_const("&quot;");
                        else
                                (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
                        break;
                case QUOTE_RIGHT_ALT:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("''");
+                               print_const("''");
                        else
                                print_localized(QUOTE_RIGHT_DOUBLE);
                        break;
@@ -1248,51 +1249,51 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        print_token(t);
                        break;
                case STRONG_START:
-                       print("<strong>");
+                       print_const("<strong>");
                        break;
                case STRONG_STOP:
-                       print("</strong>");
+                       print_const("</strong>");
                        break;
                case SUBSCRIPT:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? (print("<sub>")) : (print("</sub>"));
+                               (t->start < t->mate->start) ? (print_const("<sub>")) : (print_const("</sub>"));
                        } else if (t->len != 1) {
-                               print("<sub>");
+                               print_const("<sub>");
                                mmd_export_token_html(out, source, t->child, offset, scratch);
-                               print("</sub>");
+                               print_const("</sub>");
                        } else {
-                               print("~");
+                               print_const("~");
                        }
                        break;
                case SUPERSCRIPT:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? (print("<sup>")) : (print("</sup>"));
+                               (t->start < t->mate->start) ? (print_const("<sup>")) : (print_const("</sup>"));
                        } else if (t->len != 1) {
-                               print("<sup>");
+                               print_const("<sup>");
                                mmd_export_token_html(out, source, t->child, offset, scratch);
-                               print("</sup>");
+                               print_const("</sup>");
                        } else {
-                               print("^");
+                               print_const("^");
                        }       
                        break;
                case TABLE_CELL:
                        if (scratch->in_table_header) {
-                               print("\t<th");
+                               print_const("\t<th");
                        } else {
-                               print("\t<td");
+                               print_const("\t<td");
                        }
                        switch (scratch->table_alignment[scratch->table_cell_count]) {
                                case 'l':
                                case 'L':
-                                       print(" style=\"text-align:left;\"");
+                                       print_const(" style=\"text-align:left;\"");
                                        break;
                                case 'r':
                                case 'R':
-                                       print(" style=\"text-align:right;\"");
+                                       print_const(" style=\"text-align:right;\"");
                                        break;
                                case 'c':
                                case 'C':
-                                       print(" style=\"text-align:center;\"");
+                                       print_const(" style=\"text-align:center;\"");
                                        break;
                        }
                        if (t->next && t->next->type == TABLE_DIVIDER) {
@@ -1300,12 +1301,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                        printf(" colspan=\"%d\"", t->next->len);
                                }
                        }
-                       print(">");
+                       print_const(">");
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        if (scratch->in_table_header) {
-                               print("</th>\n");
+                               print_const("</th>\n");
                        } else {
-                               print("</td>\n");
+                               print_const("</td>\n");
                        }
                        if (t->next)
                                scratch->table_cell_count += t->next->len;
@@ -1316,14 +1317,14 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                case TABLE_DIVIDER:
                        break;
                case TABLE_ROW:
-                       print("<tr>\n");
+                       print_const("<tr>\n");
                        scratch->table_cell_count = 0;
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
-                       print("</tr>\n");
+                       print_const("</tr>\n");
                        break;
                case TEXT_LINEBREAK:
                        if (t->next) {
-                               print("<br />\n");
+                               print_const("<br />\n");
                                scratch->padded = 1;
                        }
                        break;
@@ -1389,23 +1390,23 @@ void mmd_export_token_html_raw(DString * out, const char * source, token * t, si
                        print_token(t);
                        break;
                case AMPERSAND:
-                       print("&amp;");
+                       print_const("&amp;");
                        break;
                case AMPERSAND_LONG:
-                       print("&amp;amp;");
+                       print_const("&amp;amp;");
                        break;
                case ANGLE_RIGHT:
-                       print("&gt;");
+                       print_const("&gt;");
                        break;
                case ANGLE_LEFT:
-                       print("&lt;");
+                       print_const("&lt;");
                        break;
                case ESCAPED_CHARACTER:
-                       print("\\");
+                       print_const("\\");
                        mmd_print_char_html(out, source[t->start + 1], false);
                        break;
                case QUOTE_DOUBLE:
-                       print("&quot;");
+                       print_const("&quot;");
                        break;
                case CODE_FENCE:
                        if (t->next)
@@ -1423,7 +1424,7 @@ void mmd_export_token_html_raw(DString * out, const char * source, token * t, si
 
 
 void mmd_start_complete_html(DString * out, const char * source, scratch_pad * scratch) {
-       print("<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
+       print_const("<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
 
        // Iterate over metadata keys
        meta * m;
@@ -1432,9 +1433,9 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
                if (strcmp(m->key, "baseheaderlevel") == 0) {
                } else if (strcmp(m->key, "bibtex") == 0) {
                } else if (strcmp(m->key, "css") == 0) {
-                       print("\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
+                       print_const("\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
                        mmd_print_string_html(out, m->value, false);
-                       print("\"/>\n");
+                       print_const("\"/>\n");
                } else if (strcmp(m->key, "htmlfooter") == 0) {
                } else if (strcmp(m->key, "htmlheader") == 0) {
                        print(m->value);
@@ -1452,29 +1453,29 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
                } else if (strcmp(m->key, "mmdheader") == 0) {
                } else if (strcmp(m->key, "quoteslanguage") == 0) {
                } else if (strcmp(m->key, "title") == 0) {
-                       print("\t<title>");
+                       print_const("\t<title>");
                        mmd_print_string_html(out, m->value, false);
-                       print("</title>\n");
+                       print_const("</title>\n");
                } else if (strcmp(m->key, "transcludebase") == 0) {
                } else if (strcmp(m->key, "xhtmlheader") == 0) {
                        print(m->value);
                        print_char('\n');
                } else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
                } else {
-                       print("\t<meta name=\"");
+                       print_const("\t<meta name=\"");
                        mmd_print_string_html(out, m->key, false);
-                       print("\" content=\"");
+                       print_const("\" content=\"");
                        mmd_print_string_html(out, m->value, false);
-                       print("\"/>\n");
+                       print_const("\"/>\n");
                }
        }
 
-       print("</head>\n<body>\n\n");
+       print_const("</head>\n<body>\n\n");
 }
 
 
 void mmd_end_complete_html(DString * out, const char * source, scratch_pad * scratch) {
-       print("\n\n</body>\n</html>\n");
+       print_const("\n\n</body>\n</html>\n");
 }
 
 
@@ -1497,7 +1498,7 @@ void mmd_export_footnote_list_html(DString * out, const char * source, scratch_p
                token * content;
 
                pad(out, 2, scratch);
-               print("<div class=\"footnotes\">\n<hr />\n<ol>");
+               print_const("<div class=\"footnotes\">\n<hr />\n<ol>");
                scratch->padded = 0;
 
                for (int i = 0; i < scratch->used_footnotes->size; ++i)
@@ -1532,7 +1533,7 @@ void mmd_export_footnote_list_html(DString * out, const char * source, scratch_p
                }
 
                pad(out, 2, scratch);
-               print("</ol>\n</div>");
+               print_const("</ol>\n</div>");
                scratch->padded = 0;
                scratch->footnote_being_printed = 0;
        }
@@ -1545,7 +1546,7 @@ void mmd_export_citation_list_html(DString * out, const char * source, scratch_p
                token * content;
 
                pad(out, 2, scratch);
-               print("<div class=\"citations\">\n<hr />\n<ol>");
+               print_const("<div class=\"citations\">\n<hr />\n<ol>");
                scratch->padded = 0;
 
                for (int i = 0; i < scratch->used_citations->size; ++i)
@@ -1580,7 +1581,7 @@ void mmd_export_citation_list_html(DString * out, const char * source, scratch_p
                }
 
                pad(out, 2, scratch);
-               print("</ol>\n</div>");
+               print_const("</ol>\n</div>");
                scratch->padded = 0;
                scratch->citation_being_printed = 0;
        }
index 0b157dc3bed578913609e34fdbecaaecaad22b54..a8c048c331de58e2f7c02e854b0861d75155d39b 100644 (file)
@@ -64,6 +64,7 @@
 #include "scanners.h"
 
 #define print(x) d_string_append(out, x)
+#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
 #define print_char(x) d_string_append_c(out, x)
 #define printf(...) d_string_append_printf(out, __VA_ARGS__)
 #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
 void mmd_print_char_latex(DString * out, char c) {
        switch (c) {
                case '\\':
-                       print("\\textbackslash{}");
+                       print_const("\\textbackslash{}");
                        break;
                case '~':
-                       print("\\ensuremath{\\sim}");
+                       print_const("\\ensuremath{\\sim}");
                        break;
                case '/':
-                       print("\\slash ");
+                       print_const("\\slash ");
                        break;
                case '^':
-                       print("\\^{}");
+                       print_const("\\^{}");
                        break;
                case '<':
                case '>':
@@ -91,7 +92,7 @@ void mmd_print_char_latex(DString * out, char c) {
                        print_char('$');
                        break;
                case '|':
-                       print("\\textbar{}");
+                       print_const("\\textbar{}");
                        break;
                case '#':
                case '{':
@@ -122,81 +123,81 @@ void mmd_print_string_latex(DString * out, const char * str) {
 void mmd_print_localized_char_latex(DString * out, unsigned short type, scratch_pad * scratch) {
        switch (type) {
                case DASH_N:
-                       print("--");
+                       print_const("--");
                        break;
                case DASH_M:
-                       print("---");
+                       print_const("---");
                        break;
                case ELLIPSIS:
-                       print("{\\ldots}");
+                       print_const("{\\ldots}");
                        break;
                case APOSTROPHE:
-                       print("'");
+                       print_const("'");
                        break;
                case QUOTE_LEFT_SINGLE:
                        switch (scratch->quotes_lang) {
                                case SWEDISH:
-                                       print("'");
+                                       print_const("'");
                                        break;
                                case FRENCH:
-                                       print("'");
+                                       print_const("'");
                                        break;
                                case GERMAN:
-                                       print("‚");
+                                       print_const("‚");
                                        break;
                                case GERMANGUILL:
-                                       print("›");
+                                       print_const("›");
                                        break;
                                default:
-                                       print("`");
+                                       print_const("`");
                                }
                        break;
                case QUOTE_RIGHT_SINGLE:
                        switch (scratch->quotes_lang) {
                                case GERMAN:
-                                       print("`");
+                                       print_const("`");
                                        break;
                                case GERMANGUILL:
-                                       print("‹");
+                                       print_const("‹");
                                        break;
                                default:
-                                       print("'");
+                                       print_const("'");
                                }
                        break;
                case QUOTE_LEFT_DOUBLE:
                        switch (scratch->quotes_lang) {
                                case DUTCH:
                                case GERMAN:
-                                       print("„");
+                                       print_const("„");
                                        break;
                                case GERMANGUILL:
-                                       print("»");
+                                       print_const("»");
                                        break;
                                case FRENCH:
-                                       print("«");
+                                       print_const("«");
                                        break;
                                case SWEDISH:
-                                       print("''");
+                                       print_const("''");
                                        break;
                                default:
-                                       print("``");
+                                       print_const("``");
                                }
                        break;
                case QUOTE_RIGHT_DOUBLE:
                        switch (scratch->quotes_lang) {
                                case GERMAN:
-                                       print("``");
+                                       print_const("``");
                                        break;
                                case GERMANGUILL:
-                                       print("«");
+                                       print_const("«");
                                        break;
                                case FRENCH:
-                                       print("»");
+                                       print_const("»");
                                        break;
                                case SWEDISH:
                                case DUTCH:
                                default:
-                                       print("''");
+                                       print_const("''");
                                }
                        break;
        }
@@ -217,9 +218,9 @@ void mmd_export_link_latex(DString * out, const char * source, token * text, lin
                                        printf("\\autoref{%s}", &(link->url)[1]);
                                } else {
                                        mmd_export_token_tree_latex(out, source, text->child, scratch);
-                                       print(" (");
+                                       print_const(" (");
                                        printf("\\autoref{%s}", &(link->url)[1]);
-                                       print(")");
+                                       print_const(")");
                                }
 
                                free(temp_char);
@@ -231,9 +232,9 @@ void mmd_export_link_latex(DString * out, const char * source, token * text, lin
                        printf("\\href{%s}", link->url);                        
                }
        } else
-               print("\\href{}");
+               print_const("\\href{}");
 
-       print("{");
+       print_const("{");
 
        // If we're printing contents of bracket as text, then ensure we include it all
        if (text && text->child && text->child->len > 1) {
@@ -243,12 +244,12 @@ void mmd_export_link_latex(DString * out, const char * source, token * text, lin
        
        mmd_export_token_tree_latex(out, source, text->child, scratch);
 
-       print("}");
+       print_const("}");
 
        // Reprint as footnote for printed copies
        printf("\\footnote{\\href{%s}{", link->url);
        mmd_print_string_latex(out, link->url);
-       print("}}");
+       print_const("}}");
 }
 
 
@@ -281,7 +282,7 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li
                is_figure = false;
 
        if (is_figure) {
-               print("\\begin{figure}[htbp]\n\\centering\n");
+               print_const("\\begin{figure}[htbp]\n\\centering\n");
                scratch->close_para = false;
        }
 
@@ -296,12 +297,12 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li
                a = a->next;
        }
 
-       print("\\includegraphics[");
+       print_const("\\includegraphics[");
 
        if (height || width) {
                if (!height || !width) {
                        // One not specified, preserve aspect
-                       print("keepaspectratio,");
+                       print_const("keepaspectratio,");
                }
 
                if (width) {
@@ -319,7 +320,7 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li
                        free(width);
                } else {
                        // Default width
-                       print("width=\\textwidth,");
+                       print_const("width=\\textwidth,");
                }
 
                if (height) {
@@ -337,25 +338,25 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li
                        free(height);
                } else {
                        // Default height
-                       print("height=0.75\\textheight");
+                       print_const("height=0.75\\textheight");
                }
        } else {
                // no dimensions specified, use sensible defaults
-               print("keepaspectratio,width=\\textwidth,height=0.75\\textheight");
+               print_const("keepaspectratio,width=\\textwidth,height=0.75\\textheight");
        }
 
        if (link->url)
                printf("]{%s}", link->url);
        else
-               print("]{}");
+               print_const("]{}");
 
 
        if (is_figure) {
-               print("\n");
+               print_const("\n");
                if (text) {
-                       print("\\caption{");
+                       print_const("\\caption{");
                        mmd_export_token_tree_latex(out, source, text->child, scratch);
-                       print("}\n");
+                       print_const("}\n");
                }
                if (link->label) {
                        // \todo: Need to decide on approach to id's
@@ -364,7 +365,7 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li
                        free(label);
                }
 
-               print("\\end{figure}");
+               print_const("\\end{figure}");
        }
 }
 
@@ -386,13 +387,13 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
        switch (t->type) {
                case AMPERSAND:
                case AMPERSAND_LONG:
-                       print("\\&");
+                       print_const("\\&");
                        break;
                case ANGLE_LEFT:
-                       print("$<$");
+                       print_const("$<$");
                        break;
                case ANGLE_RIGHT:
-                       print("$>$");
+                       print_const("$>$");
                        break;
                case APOSTROPHE:
                        if (!(scratch->extensions & EXT_SMART)) {
@@ -406,11 +407,11 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        break;
                case BLOCK_BLOCKQUOTE:
                        pad(out, 2, scratch);
-                       print("\\begin{quote}\n");
+                       print_const("\\begin{quote}\n");
                        scratch->padded = 2;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        pad(out, 1, scratch);
-                       print("\\end{quote}");
+                       print_const("\\end{quote}");
                        scratch->padded = 0;
                        break;
                case BLOCK_CODE_FENCED:
@@ -420,24 +421,24 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        if (temp_char) {
                                printf("\\begin{lstlisting}[language=%s]\n", temp_char);
                        } else {
-                               print("\\begin{verbatim}\n");
+                               print_const("\\begin{verbatim}\n");
                        }
 
                        mmd_export_token_tree_latex_raw(out, source, t->child->next, scratch);
 
                        if (temp_char) {
-                               print("\\end{lstlisting}");
+                               print_const("\\end{lstlisting}");
                                free(temp_char);
                        } else {
-                               print("\\end{verbatim}");
+                               print_const("\\end{verbatim}");
                        }
                        scratch->padded = 0;
                        break;
                case BLOCK_CODE_INDENTED:
                        pad(out, 2, scratch);
-                       print("\\begin{verbatim}\n");
+                       print_const("\\begin{verbatim}\n");
                        mmd_export_token_tree_latex_raw(out, source, t->child, scratch);
-                       print("\\end{verbatim}");
+                       print_const("\\end{verbatim}");
                        scratch->padded = 0;
                        break;
                case BLOCK_DEFINITION:
@@ -459,7 +460,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        // lemon's LALR(1) parser can't properly handle this (to my understanding).
 
                        if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
-                               print("\\begin{description}\n");
+                               print_const("\\begin{description}\n");
        
                        scratch->padded = 2;
 
@@ -467,7 +468,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        pad(out, 1, scratch);
 
                        if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
-                               print("\\end{description}\n");
+                               print_const("\\end{description}\n");
 
                        scratch->padded = 1;
                        break;
@@ -495,32 +496,32 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                        switch (temp_short + scratch->base_header_level - 1) {
                                case 1:
-                                       print("\\part{");
+                                       print_const("\\part{");
                                        break;
                                case 2:
-                                       print("\\chapter{");
+                                       print_const("\\chapter{");
                                        break;
                                case 3:
-                                       print("\\section{");
+                                       print_const("\\section{");
                                        break;
                                case 4:
-                                       print("\\subsection{");
+                                       print_const("\\subsection{");
                                        break;
                                case 5:
-                                       print("\\subsubsection{");
+                                       print_const("\\subsubsection{");
                                        break;
                                case 6:
-                                       print("\\paragraph{");
+                                       print_const("\\paragraph{");
                                        break;
                                case 7:
-                                       print("\\subparagraph{");
+                                       print_const("\\subparagraph{");
                                        break;
                        }
 
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
 
                        if (scratch->extensions & EXT_NO_LABELS) {
-                               print("}");
+                               print_const("}");
                        } else {
                                temp_token = manual_label_from_header(t, source);
                                if (temp_token) {
@@ -535,7 +536,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        break;
                case BLOCK_HR:
                        pad(out, 2, scratch);
-                       print("\\begin{center}\\rule{3in}{0.4pt}\\end{center}");
+                       print_const("\\begin{center}\\rule{3in}{0.4pt}\\end{center}");
                        scratch->padded = 0;
                        break;
                case BLOCK_HTML:
@@ -553,11 +554,11 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                        break;
                        }
                        pad(out, 2, scratch);
-                       print("\\begin{itemize}");
+                       print_const("\\begin{itemize}");
                        scratch->padded = 1;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        pad(out, 2, scratch);
-                       print("\\end{itemize}");
+                       print_const("\\end{itemize}");
                        scratch->padded = 0;
                        scratch->list_is_tight = temp_short;
                        break;
@@ -573,24 +574,24 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                        break;
                        }
                        pad(out, 2, scratch);
-                       print("\\begin{enumerate}");
+                       print_const("\\begin{enumerate}");
                        scratch->padded = 1;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        pad(out, 2, scratch);
-                       print("\\end{enumerate}");
+                       print_const("\\end{enumerate}");
                        scratch->padded = 0;
                        scratch->list_is_tight = temp_short;
                        break;
                case BLOCK_LIST_ITEM:
                        pad(out, 2, scratch);
-                       print("\\item ");
+                       print_const("\\item ");
                        scratch->padded = 2;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        scratch->padded = 0;
                        break;
                case BLOCK_LIST_ITEM_TIGHT:
                        pad(out, 2, scratch);
-                       print("\\item ");
+                       print_const("\\item ");
                        scratch->padded = 2;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        scratch->padded = 0;
@@ -605,9 +606,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                case BLOCK_TABLE:
                        pad(out, 2, scratch);
 
-                       print("\\begin{table}[htbp]\n");
+                       print_const("\\begin{table}[htbp]\n");
 
-                       print("\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n");
+                       print_const("\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n");
 
                        // Are we followed by a caption?
                        if (table_has_caption(t)) {
@@ -623,9 +624,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                t->next->child->child->type = TEXT_EMPTY;
                                t->next->child->child->mate->type = TEXT_EMPTY;
 
-                               print("\\caption{");
+                               print_const("\\caption{");
                                mmd_export_token_tree_latex(out, source, t->next->child->child, scratch);
-                               print("}\n");
+                               print_const("}\n");
 
                                printf("\\label{%s}\n", temp_char);
                                free(temp_char);
@@ -639,9 +640,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        pad(out, 1, scratch);
-                       print("\n\\end{tabulary}\n\\end{minipage}");
+                       print_const("\n\\end{tabulary}\n\\end{minipage}");
 
-                       print("\n\\end{table}");
+                       print_const("\n\\end{table}");
 
                        scratch->skip_token = temp_short;
                        scratch->padded = 0;
@@ -649,7 +650,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                case BLOCK_TABLE_HEADER:
                        pad(out, 2, scratch);
 
-                       print("\\begin{tabulary}{\\textwidth}{@{}");
+                       print_const("\\begin{tabulary}{\\textwidth}{@{}");
 
                        for (int i = 0; i < scratch->table_column_count; ++i)
                        {
@@ -668,13 +669,13 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                }
                        }
 
-                       print("@{}} \\toprule\n");
+                       print_const("@{}} \\toprule\n");
 
                        scratch->in_table_header = 1;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        scratch->in_table_header = 0;
 
-                       print("\\midrule\n");
+                       print_const("\\midrule\n");
 
                        scratch->padded = 1;
                        break;
@@ -682,14 +683,14 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        pad(out, 2, scratch);
                        scratch->padded = 2;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                       print("\\bottomrule");
+                       print_const("\\bottomrule");
                        scratch->padded = 0;
                        break;
                case BLOCK_TERM:
                        pad(out, 2, scratch);
-                       print("\\item[");
+                       print_const("\\item[");
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                       print("]");
+                       print_const("]");
                        scratch->padded = 0;
                        break;
                case BLOCK_TOC:
@@ -709,7 +710,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                if (temp_short == 0) {
                                        // First item
                                        pad(out, 2, scratch);
-                                       print("\\begin{itemize}");
+                                       print_const("\\begin{itemize}");
                                        scratch->padded = 0;
                                        temp_short = temp_token->type;
                                        temp_short2 = temp_short;
@@ -721,7 +722,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                } else if (temp_token->type == temp_short2 + 1) {
                                        // Indent
                                        pad(out, 2, scratch);
-                                       print("\\begin{itemize}");
+                                       print_const("\\begin{itemize}");
                                        scratch->padded = 0;
                                        temp_short2++;
                                } else if (temp_token->type < temp_short2) {
@@ -730,7 +731,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                        while (temp_short2 > temp_token->type) {
                                                if (temp_short2 > temp_short) {
                                                        pad(out, 2, scratch);
-                                                       print("\\end{itemize}");
+                                                       print_const("\\end{itemize}");
                                                        scratch->padded = 0;
                                                } else
                                                        temp_short = temp_short2 - 1;
@@ -744,7 +745,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                                temp_char = label_from_header(source, temp_token);
                                pad(out, 2, scratch);
-                               print("\\item ");
+                               print_const("\\item ");
                                mmd_export_token_tree_latex(out, source, temp_token->child, scratch);
                                printf("(\\autoref{%s})", temp_char);
                                scratch->padded = 0;
@@ -753,47 +754,47 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                        while (temp_short2 > (temp_short)) {
                                pad(out, 2, scratch);
-                               print("\\end{itemize}");
+                               print_const("\\end{itemize}");
                                scratch->padded = 0;
                                temp_short2--;
                        }
                        
                        if (temp_short) {
                                pad(out, 2, scratch);
-                               print("\\end{itemize}");
+                               print_const("\\end{itemize}");
                                scratch->padded = 0;
                        }
 
                        scratch->padded = 0;
                        break;
                case BRACE_DOUBLE_LEFT:
-                       print("\\{\\{");
+                       print_const("\\{\\{");
                        break;
                case BRACE_DOUBLE_RIGHT:
-                       print("\\}\\}");
+                       print_const("\\}\\}");
                        break;
                case BRACKET_LEFT:
-                       print("[");                     
+                       print_const("[");                       
                        break;
                case BRACKET_CITATION_LEFT:
-                       print("[#");
+                       print_const("[#");
                        break;
                case BRACKET_FOOTNOTE_LEFT:
-                       print("[^");
+                       print_const("[^");
                        break;
                case BRACKET_IMAGE_LEFT:
-                       print("![");
+                       print_const("![");
                        break;
                case BRACKET_VARIABLE_LEFT:
-                       print("[\%");
+                       print_const("[\%");
                        break;
                case BRACKET_RIGHT:
-                       print("]");
+                       print_const("]");
                        break;
                case CODE_FENCE:
                        break;
                case COLON:
-                       print(":");
+                       print_const(":");
                        break;
                case DASH_M:
                        if (!(scratch->extensions & EXT_SMART)) {
@@ -820,18 +821,18 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        }
                        break;
                case EMPH_START:
-                       print("\\emph{");
+                       print_const("\\emph{");
                        break;
                case EMPH_STOP:
-                       print("}");
+                       print_const("}");
                        break;
                case EQUAL:
-                       print("=");
+                       print_const("=");
                        break;
                case ESCAPED_CHARACTER:
                        if (!(scratch->extensions & EXT_COMPATIBILITY) &&
                                (source[t->start + 1] == ' ')) {
-                               print("~");
+                               print_const("~");
                        } else {
                                mmd_print_char_latex(out, source[t->start + 1]);
                        }
@@ -875,28 +876,28 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                case MARKER_LIST_ENUMERATOR:
                        break;
                case MATH_BRACKET_OPEN:
-                       print("\\[");
+                       print_const("\\[");
                        break;
                case MATH_BRACKET_CLOSE:
-                       print("\\]");
+                       print_const("\\]");
                        break;
                case MATH_DOLLAR_SINGLE:
                        if (t->mate)
-                               print("$");
+                               print_const("$");
                        else
-                               print("\\$");
+                               print_const("\\$");
                        break;
                case MATH_DOLLAR_DOUBLE:
                        if (t->mate)
-                               print("$$");
+                               print_const("$$");
                        else
-                               print("\\$\\$");
+                               print_const("\\$\\$");
                        break;
                case MATH_PAREN_OPEN:
-                       print("\\(");
+                       print_const("\\(");
                        break;
                case MATH_PAREN_CLOSE:
-                       print("\\)");
+                       print_const("\\)");
                        break;
                case NON_INDENT_SPACE:
                        print_char(' ');
@@ -906,15 +907,15 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                        if (temp_char) {
                                if (scan_email(temp_char)) {
-                                       print("\\href{mailto:");
+                                       print_const("\\href{mailto:");
                                        print(temp_char);
                                } else {
-                                       print("\\href{");
+                                       print_const("\\href{");
                                        print(temp_char);
                                }
-                               print("}{");
+                               print_const("}{");
                                mmd_print_string_latex(out, temp_char);
-                               print("}");
+                               print_const("}");
                        } else if (scan_html(&source[t->start])) {
                                // We ignore HTML blocks
                                if (scan_html_comment(&source[t->start])) {
@@ -960,9 +961,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        }
                        t->child->type = TEXT_EMPTY;
                        t->child->mate->type = TEXT_EMPTY;
-                       print("\\texttt{");
+                       print_const("\\texttt{");
                        mmd_export_token_tree_latex_tt(out, source, t->child, scratch);
-                       print("}");
+                       print_const("}");
                        break;
                case PAIR_BRACES:
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
@@ -1053,9 +1054,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                        if (temp_char[0] == '\0') {
                                                // No locator
                         if (temp_char2[strlen(temp_char2) - 1] == ';') {
-                            print("\\citet");
+                            print_const("\\citet");
                         } else {
-                            print("~\\citep");
+                            print_const("~\\citep");
                         }
                                        } else {
                                                // Locator present
@@ -1138,9 +1139,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                if (scratch->extensions & EXT_CRITIC_ACCEPT) {
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                                } else {
-                                       print("\\underline{");
+                                       print_const("\\underline{");
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                                       print("}");
+                                       print_const("}");
                                }
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);                            
@@ -1156,9 +1157,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                if (scratch->extensions & EXT_CRITIC_REJECT) {
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                                } else {
-                                       print("\\sout{");
+                                       print_const("\\sout{");
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                                       print("}");
+                                       print_const("}");
                                }
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);                            
@@ -1172,9 +1173,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        if (scratch->extensions & EXT_CRITIC) {
                                t->child->type = TEXT_EMPTY;
                                t->child->mate->type = TEXT_EMPTY;
-                               print("\\cmnote{");
+                               print_const("\\cmnote{");
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
-                               print("}");
+                               print_const("}");
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
                        }
@@ -1188,18 +1189,18 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                t->child->type = TEXT_EMPTY;
                                t->child->mate->type = TEXT_EMPTY;
                                // 'hl' requires 'soul' package
-                               print("\\hl{");
+                               print_const("\\hl{");
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
-                               print("}");
+                               print_const("}");
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
                        }
                        break;
                case CRITIC_SUB_DIV_A:
-                       print("~");
+                       print_const("~");
                        break;
                case CRITIC_SUB_DIV_B:
-                       print("&gt;");
+                       print_const("&gt;");
                        break;
                case PAIR_CRITIC_SUB_DEL:
                        if ((scratch->extensions & EXT_CRITIC) &&
@@ -1211,9 +1212,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                } else if (scratch->extensions & EXT_CRITIC_REJECT) {
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                                } else {
-                                       print("\\sout{");
+                                       print_const("\\sout{");
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                                       print("}");
+                                       print_const("}");
                                }
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
@@ -1229,9 +1230,9 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                } else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                                } else {
-                                       print("\\underline{");
+                                       print_const("\\underline{");
                                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                                       print("}");
+                                       print_const("}");
                                }
                        } else {
                                mmd_export_token_tree_latex(out, source, t->child, scratch);
@@ -1255,15 +1256,15 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
                        break;
                case PAREN_LEFT:
-                       print("(");
+                       print_const("(");
                        break;
                case PAREN_RIGHT:
-                       print(")");
+                       print_const(")");
                        break;
                case PIPE:
                        for (int i = 0; i < t->len; ++i)
                        {
-                               print("\\textbar{}");
+                               print_const("\\textbar{}");
                        }
                        break;
                case PLUS:
@@ -1271,54 +1272,54 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        break;
                case QUOTE_SINGLE:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("'");
+                               print_const("'");
                        else
                                (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
                        break;
                case QUOTE_DOUBLE:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("&quot;");
+                               print_const("&quot;");
                        else
                                (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
                        break;
                case QUOTE_RIGHT_ALT:
                        if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
-                               print("''");
+                               print_const("''");
                        else
                                print_localized(QUOTE_RIGHT_DOUBLE);
                        break;
                case SLASH:
-                       print("\\slash ");
+                       print_const("\\slash ");
                        break;
                case STAR:
                        print_token(t);
                        break;
                case STRONG_START:
-                       print("\\textbf{");
+                       print_const("\\textbf{");
                        break;
                case STRONG_STOP:
-                       print("}");
+                       print_const("}");
                        break;
                case SUBSCRIPT:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? (print("\\textsubscript{")) : (print("}"));
+                               (t->start < t->mate->start) ? (print_const("\\textsubscript{")) : (print_const("}"));
                        } else if (t->len != 1) {
-                               print("\\textsubscript{");
+                               print_const("\\textsubscript{");
                                mmd_export_token_latex(out, source, t->child, scratch);
-                               print("}");
+                               print_const("}");
                        } else {
-                               print("\\ensuremath{\\sim}");
+                               print_const("\\ensuremath{\\sim}");
                        }
                        break;
                case SUPERSCRIPT:
                        if (t->mate) {
-                               (t->start < t->mate->start) ? (print("\\textsuperscript{")) : (print("}"));
+                               (t->start < t->mate->start) ? (print_const("\\textsuperscript{")) : (print_const("}"));
                        } else if (t->len != 1) {
-                               print("\\textsuperscript{");
+                               print_const("\\textsuperscript{");
                                mmd_export_token_latex(out, source, t->child, scratch);
-                               print("}");
+                               print_const("}");
                        } else {
-                               print("\\^{}");
+                               print_const("\\^{}");
                        }       
                        break;
                case TABLE_CELL:
@@ -1328,14 +1329,14 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                        switch (scratch->table_alignment[scratch->table_cell_count]) {
                                                case 'l':
                                                case 'L':
-                                                       print("l}{");
+                                                       print_const("l}{");
                                                        break;
                                                case 'r':
                                                case 'R':
-                                                       print("r}{");
+                                                       print_const("r}{");
                                                        break;
                                                default:
-                                                       print("c}{");
+                                                       print_const("c}{");
                                                        break;
                                        }
                                }
@@ -1345,14 +1346,14 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
 
                        if (t->next && t->next->type == TABLE_DIVIDER) {
                                if (t->next->len > 1)
-                                       print("}");
+                                       print_const("}");
                        }
 
                        if (t->next && t->next->type == TABLE_DIVIDER) {
                                t = t->next;
 
                                if (t->next && t->next->type == TABLE_CELL) {
-                                       print("&");
+                                       print_const("&");
                                        scratch->table_cell_count += t->next->len;
                                }
                        } else
@@ -1364,19 +1365,19 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                case TABLE_ROW:
                        scratch->table_cell_count = 0;
                        mmd_export_token_tree_latex(out, source, t->child, scratch);
-                       print("\\\\\n");
+                       print_const("\\\\\n");
                        break;
                case TEXT_BACKSLASH:
-                       print("\\textbackslash{}");
+                       print_const("\\textbackslash{}");
                        break;
                case TEXT_EMPTY:
                        break;
                case TEXT_HASH:
-                       print("\\#");
+                       print_const("\\#");
                        break;
                case TEXT_LINEBREAK:
                        if (t->next) {
-                               print("\n");
+                               print_const("\n");
                                scratch->padded = 1;
                        }
                        break;
@@ -1385,18 +1386,18 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                                print_char('\n');
                        break;
                case TEXT_PERCENT:
-                       print("\\%");
+                       print_const("\\%");
                        break;
                case TEXT_BRACE_LEFT:
                case TEXT_BRACE_RIGHT:
-                       print("\\");
+                       print_const("\\");
                case TEXT_NUMBER_POSS_LIST:
                case TEXT_PERIOD:
                case TEXT_PLAIN:
                        print_token(t);
                        break;
                case UL:
-                       print("\\_");
+                       print_const("\\_");
                        break;
                default:
                        fprintf(stderr, "Unknown token type: %d\n", t->type);
@@ -1435,7 +1436,7 @@ void mmd_export_token_latex_raw(DString * out, const char * source, token * t, s
 
        switch (t->type) {
                case ESCAPED_CHARACTER:
-                       print("\\");
+                       print_const("\\");
                        print_char(source[t->start + 1]);
 //                     mmd_print_char_latex(out, source[t->start + 1]);
                        break;
@@ -1474,26 +1475,26 @@ void mmd_export_token_latex_tt(DString * out, const char * source, token * t, sc
        switch (t->type) {
                case AMPERSAND:
                case AMPERSAND_LONG:
-                       print("\\&");
+                       print_const("\\&");
                        break;
                case ANGLE_LEFT:
-                       print("$<$");
+                       print_const("$<$");
                        break;
                case ANGLE_RIGHT:
-                       print("$>$");
+                       print_const("$>$");
                        break;
                case DASH_N:
                        if (t->len == 1) {
-                               print("-");
+                               print_const("-");
                        } else {
-                               print("-{}-");
+                               print_const("-{}-");
                        }
                        break;
                case DASH_M:
-                       print("-{}-{}-");
+                       print_const("-{}-{}-");
                        break;
                case ESCAPED_CHARACTER:
-                       print("\\textbackslash{}");
+                       print_const("\\textbackslash{}");
                        mmd_print_char_latex(out, source[t->start + 1]);
                        break;
                case CODE_FENCE:
@@ -1502,25 +1503,25 @@ void mmd_export_token_latex_tt(DString * out, const char * source, token * t, sc
                case TEXT_EMPTY:
                        break;
         case SLASH:
-            print("\\slash ");
+            print_const("\\slash ");
             break;
         case TEXT_BACKSLASH:
-               print("\\textbackslash{}");
+               print_const("\\textbackslash{}");
                break;
                case BRACE_DOUBLE_LEFT:
-                       print("\\{\\{");
+                       print_const("\\{\\{");
                        break;
                case BRACE_DOUBLE_RIGHT:
-                       print("\\}\\}");
+                       print_const("\\}\\}");
                        break;
         case TEXT_BRACE_LEFT:
-                       print("\\{");
+                       print_const("\\{");
                        break;
         case TEXT_BRACE_RIGHT:
-                       print("\\}");
+                       print_const("\\}");
                        break;
         case UL:
-               print("\\_");
+               print_const("\\_");
                break;
                default:
                        if (t->child)
@@ -1583,35 +1584,35 @@ void mmd_start_complete_latex(DString * out, const char * source, scratch_pad *
                } else if (strcmp(m->key, "quoteslanguage") == 0) {
                } else if ((strcmp(m->key, "title") == 0) ||
                        (strcmp(m->key, "latextitle") == 0)) {
-                       print("\\def\\mytitle{");
+                       print_const("\\def\\mytitle{");
                        mmd_print_string_latex(out, m->value);
-                       print("}\n");
+                       print_const("}\n");
                } else if ((strcmp(m->key, "author") == 0) ||
                        (strcmp(m->key, "latexauthor") == 0)) {
-                       print("\\def\\myauthor{");
+                       print_const("\\def\\myauthor{");
                        mmd_print_string_latex(out, m->value);
-                       print("}\n");
+                       print_const("}\n");
                } else if (strcmp(m->key, "date") == 0) {
-                       print("\\def\\mydate{");
+                       print_const("\\def\\mydate{");
                        mmd_print_string_latex(out, m->value);
-                       print("}\n");
+                       print_const("}\n");
                } else if (strcmp(m->key, "copyright") == 0) {
-                       print("\\def\\mycopyright{");
+                       print_const("\\def\\mycopyright{");
                        mmd_print_string_latex(out, m->value);
-                       print("}\n");
+                       print_const("}\n");
                } else if (strcmp(m->key, "bibtex") == 0) {
-                       print("\\def\\bibliocommand{\\bibliography{");
+                       print_const("\\def\\bibliocommand{\\bibliography{");
                        mmd_print_string_latex(out, m->value);
-                       print("}}\n");
+                       print_const("}}\n");
                } else if (strcmp(m->key, "transcludebase") == 0) {
                } else if (strcmp(m->key, "xhtmlheader") == 0) {
                } else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
                } else {
-                       print("\\def\\");
+                       print_const("\\def\\");
                        mmd_print_string_latex(out, m->key);
-                       print("{");
+                       print_const("{");
                        mmd_print_string_latex(out, m->value);
-                       print("}\n");
+                       print_const("}\n");
                }
        }
 
@@ -1645,7 +1646,7 @@ void mmd_end_complete_latex(DString * out, const char * source, scratch_pad * sc
                }
        }
 
-       print("\\end{document}");
+       print_const("\\end{document}");
        scratch->padded = 0;
 }
 
@@ -1656,7 +1657,7 @@ void mmd_export_citation_list_latex(DString * out, const char * source, scratch_
                token * content;
 
                pad(out, 2, scratch);
-               print("\\begin{thebibliography}{0}");
+               print_const("\\begin{thebibliography}{0}");
                scratch->padded = 0;
 
                for (int i = 0; i < scratch->used_citations->size; ++i)
@@ -1678,7 +1679,7 @@ void mmd_export_citation_list_latex(DString * out, const char * source, scratch_
                }
 
                pad(out, 1, scratch);
-               print("\\end{thebibliography}");
+               print_const("\\end{thebibliography}");
                scratch->padded = 0;
                scratch->citation_being_printed = 0;
        }
index 2416619dc5123fb31b60a427d8224283c406b78c..4b59892261417817a11b7aad1699f4ff85de55ea 100644 (file)
@@ -57,6 +57,7 @@
 #include "memoir.h"
 
 #define print(x) d_string_append(out, x)
+#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
 #define print_char(x) d_string_append_c(out, x)
 #define printf(...) d_string_append_printf(out, __VA_ARGS__)
 #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
@@ -80,24 +81,24 @@ void mmd_export_token_memoir(DString * out, const char * source, token * t, scra
                        if (temp_char) {
                                printf("\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{lstlisting}[language=%s]\n", temp_char);
                        } else {
-                               print("\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{verbatim}\n");
+                               print_const("\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{verbatim}\n");
                        }
 
                        mmd_export_token_tree_latex_raw(out, source, t->child->next, scratch);
 
                        if (temp_char) {
-                               print("\\end{lstlisting}\n\\end{adjustwidth}");
+                               print_const("\\end{lstlisting}\n\\end{adjustwidth}");
                                free(temp_char);
                        } else {
-                               print("\\end{verbatim}\n\\end{adjustwidth}");
+                               print_const("\\end{verbatim}\n\\end{adjustwidth}");
                        }
                        scratch->padded = 0;
                        break;
                case BLOCK_CODE_INDENTED:
                        pad(out, 2, scratch);
-                       print("\\begin{adjustwidth}{2.5em}{2.5em}\\begin{verbatim}\n");
+                       print_const("\\begin{adjustwidth}{2.5em}{2.5em}\\begin{verbatim}\n");
                        mmd_export_token_tree_latex_raw(out, source, t->child, scratch);
-                       print("\\end{verbatim}\n\\end{adjustwidth}");
+                       print_const("\\end{verbatim}\n\\end{adjustwidth}");
                        scratch->padded = 0;
                        break;
                default:
index e08948bf4a652ba97994fa4188020be9bb5f3e0b..542b68d4d2156e89459a53ebaad3ba8048f051a7 100644 (file)
--- a/src/mmd.c
+++ b/src/mmd.c
@@ -1714,10 +1714,6 @@ void strip_line_tokens_from_block(mmd_engine * e, token * block) {
 
 /// Parse part of the string into a token tree
 token * mmd_engine_parse_substring(mmd_engine * e, size_t byte_start, size_t byte_len) {
-#ifdef kUseObjectPool
-       // Ensure token pool is available and ready
-       token_pool_init();
-#endif
 
        // Reset definition stack
        e->definition_stack->size = 0;
@@ -1773,11 +1769,6 @@ bool mmd_has_metadata(mmd_engine * e, size_t * end) {
        if (e->root)
                token_tree_free(e->root);
 
-#ifdef kUseObjectPool
-       // Ensure token pool is available and ready
-       token_pool_init();
-#endif
-
        // Tokenize the string (up until first empty line)
        token * doc = mmd_tokenize_string(e, &e->dstr->str[0], e->dstr->currentStringLength, true);
 
index c7b01664ac4fa04bbc99aa5ef915056d4a262efc..3ba24a19c6f0b43e4f0db053295e04d4c79fadc1 100644 (file)
 
 /// strndup not available on all platforms
 static char * my_strndup(const char * source, size_t n) {
-       size_t len = strlen(source);
+       size_t len = 0;
        char * result;
+       const char * test = source;
 
-       if (n < len)
-               len = n;
+       // strlen is too slow is strlen(source) >> n
+       for (len = 0; len < n; ++len)
+       {
+               if (test == '\0')
+                       break;
+
+               test++;
+       }
 
        result = malloc(len + 1);
 
index 8fcf680a02484c4a50861cca1b068f310917626b..13f1021808a9615072515ce0ba6c54cdeeb5266d 100644 (file)
@@ -83,11 +83,18 @@ void store_metadata(scratch_pad * scratch, meta * m);
 
 /// strndup not available on all platforms
 static char * my_strndup(const char * source, size_t n) {
-       size_t len = strlen(source);
+       size_t len = 0;
        char * result;
+       const char * test = source;
 
-       if (n < len)
-               len = n;
+       // strlen is too slow is strlen(source) >> n
+       for (len = 0; len < n; ++len)
+       {
+               if (test == '\0')
+                       break;
+
+               test++;
+       }
 
        result = malloc(len + 1);