From: Fletcher T. Penney Date: Tue, 9 Oct 2018 04:44:59 +0000 (-0400) Subject: ADDED: Add support for random header labels when not manually specified (Addresses... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1e870f4b4b44cdb2c06614383ae25d4a6f80fc7b;p=multimarkdown ADDED: Add support for random header labels when not manually specified (Addresses #157) --- diff --git a/Sources/libMultiMarkdown/epub.c b/Sources/libMultiMarkdown/epub.c index 4539220..441c8bc 100644 --- a/Sources/libMultiMarkdown/epub.c +++ b/Sources/libMultiMarkdown/epub.c @@ -251,7 +251,8 @@ void epub_export_nav_entry(DString * out, const char * source, scratch_pad * scr if (entry_level >= level) { // This entry is a direct descendant of the parent - temp_char = label_from_header(source, entry); + scratch->label_counter = *counter; + temp_char = label_from_header(source, entry, scratch); printf("
  • ", temp_char); mmd_export_token_tree_html(out, source, entry->child, scratch); print_const(""); @@ -287,8 +288,9 @@ void epub_export_nav_entry(DString * out, const char * source, scratch_pad * scr void epub_export_nav(DString * out, mmd_engine * e, scratch_pad * scratch) { size_t counter = 0; - epub_export_nav_entry(out, e->dstr->str, scratch, &counter, 0); + + scratch->label_counter = 0; } @@ -472,6 +474,7 @@ void epub_write_wrapper(const char * filepath, DString * body, mmd_engine * e, c DString * epub_create(DString * body, mmd_engine * e, const char * directory) { DString * result = d_string_new(""); scratch_pad * scratch = scratch_pad_new(e, FORMAT_EPUB); + scratch->random_seed_base_labels = e->random_seed_base_labels; mz_bool status; char * data; diff --git a/Sources/libMultiMarkdown/html.c b/Sources/libMultiMarkdown/html.c index de33c01..410b928 100644 --- a/Sources/libMultiMarkdown/html.c +++ b/Sources/libMultiMarkdown/html.c @@ -470,7 +470,8 @@ void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad * if (entry_level >= level) { // This entry is a direct descendant of the parent - temp_char = label_from_header(source, entry); + scratch->label_counter = *counter; + temp_char = label_from_header(source, entry, scratch); printf("
  • ", temp_char); mmd_export_token_tree_html(out, source, entry->child, scratch); print_const(""); @@ -507,6 +508,8 @@ void mmd_export_toc_html(DString * out, const char * source, scratch_pad * scrat size_t counter = 0; mmd_export_toc_entry_html(out, source, scratch, &counter, 0); + + scratch->label_counter = 0; } @@ -685,7 +688,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc if (scratch->extensions & EXT_NO_LABELS) { printf("", temp_short + scratch->base_header_level - 1); } else { - temp_char = label_from_header(source, t); + temp_char = label_from_header(source, t, scratch); printf("", temp_short + scratch->base_header_level - 1, temp_char); free(temp_char); } @@ -853,14 +856,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc if (scratch->extensions & EXT_NO_LABELS) { printf("", temp_short + scratch->base_header_level - 1); } else { - temp_token = manual_label_from_header(t, source); - - if (temp_token) { - temp_char = label_from_token(source, temp_token); - } else { - temp_char = label_from_token(source, t); - } - + temp_char = label_from_header(source, t, scratch); printf("", temp_short + scratch->base_header_level - 1, temp_char); free(temp_char); } @@ -877,14 +873,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc if (scratch->extensions & EXT_NO_LABELS) { printf("", temp_short + scratch->base_header_level - 1); } else { - temp_token = manual_label_from_header(t, source); - - if (temp_token) { - temp_char = label_from_token(source, temp_token); - } else { - temp_char = label_from_token(source, t); - } - + temp_char = label_from_header(source, t, scratch); printf("", temp_short + scratch->base_header_level - 1, temp_char); free(temp_char); } diff --git a/Sources/libMultiMarkdown/include/libMultiMarkdown.h b/Sources/libMultiMarkdown/include/libMultiMarkdown.h index 800e9d9..4a1cc61 100644 --- a/Sources/libMultiMarkdown/include/libMultiMarkdown.h +++ b/Sources/libMultiMarkdown/include/libMultiMarkdown.h @@ -582,6 +582,7 @@ enum parser_extensions { EXT_TRANSCLUDE = 1 << 13, //!< Perform transclusion(s) EXT_PARSE_OPML = 1 << 14, //!< Convert from OPML before processing source text EXT_PARSE_ITMZ = 1 << 15, //!< Convert from ITMZ (iThoughts) before processing source text + EXT_RANDOM_LABELS = 1 << 16, //!< Use random numbers for header labels (unless manually defined) EXT_FAKE = 1 << 31, //!< 31 is highest number allowed }; diff --git a/Sources/libMultiMarkdown/latex.c b/Sources/libMultiMarkdown/latex.c index a3ef057..a7b91fd 100644 --- a/Sources/libMultiMarkdown/latex.c +++ b/Sources/libMultiMarkdown/latex.c @@ -447,7 +447,8 @@ void mmd_export_toc_entry_latex(DString * out, const char * source, scratch_pad if (entry_level >= level) { // This entry is a direct descendant of the parent - temp_char = label_from_header(source, entry); + scratch->label_counter = *counter; + temp_char = label_from_header(source, entry, scratch); print_const("\\item "); mmd_export_token_tree_latex(out, source, entry->child, scratch); printf("(\\autoref{%s})\n\n", temp_char); @@ -483,6 +484,8 @@ void mmd_export_toc_latex(DString * out, const char * source, scratch_pad * scra size_t counter = 0; mmd_export_toc_entry_latex(out, source, scratch, &counter, 0); + + scratch->label_counter = 0; } @@ -696,14 +699,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat if (scratch->extensions & EXT_NO_LABELS) { print_const("}"); } else { - temp_token = manual_label_from_header(t, source); - - if (temp_token) { - temp_char = label_from_token(source, temp_token); - } else { - temp_char = label_from_token(source, t); - } - + temp_char = label_from_header(source, t, scratch); printf("}\n\\label{%s}", temp_char); free(temp_char); } diff --git a/Sources/libMultiMarkdown/mmd.h b/Sources/libMultiMarkdown/mmd.h index de74275..2f3622a 100644 --- a/Sources/libMultiMarkdown/mmd.h +++ b/Sources/libMultiMarkdown/mmd.h @@ -94,6 +94,8 @@ struct mmd_engine { short quotes_lang; struct asset * asset_hash; + + int random_seed_base_labels; }; diff --git a/Sources/libMultiMarkdown/opendocument-content.c b/Sources/libMultiMarkdown/opendocument-content.c index 69d0be2..539dc7e 100644 --- a/Sources/libMultiMarkdown/opendocument-content.c +++ b/Sources/libMultiMarkdown/opendocument-content.c @@ -643,7 +643,8 @@ void mmd_export_toc_entry_opendocument(DString * out, const char * source, scrat if (entry_level >= level) { // This entry is a direct descendant of the parent - temp_char = label_from_header(source, entry); + scratch->label_counter = *counter; + temp_char = label_from_header(source, entry, scratch); printf("", temp_char); mmd_export_token_tree_opendocument(out, source, entry->child, scratch); print_const(" 1\n"); @@ -688,6 +689,8 @@ void mmd_export_toc_opendocument(DString * out, const char * source, scratch_pad mmd_export_toc_entry_opendocument(out, source, scratch, &counter, 0); print_const("\n\n\n"); + + scratch->label_counter = 0; } @@ -889,7 +892,7 @@ void mmd_export_token_opendocument(DString * out, const char * source, token * t if (scratch->extensions & EXT_NO_LABELS) { mmd_export_token_tree_opendocument(out, source, t->child, scratch); } else { - temp_char = label_from_header(source, t); + temp_char = label_from_header(source, t, scratch); printf("", temp_char); mmd_export_token_tree_opendocument(out, source, t->child, scratch); //printf("", temp_char); diff --git a/Sources/libMultiMarkdown/writer.c b/Sources/libMultiMarkdown/writer.c index d8145f1..ffd3d03 100644 --- a/Sources/libMultiMarkdown/writer.c +++ b/Sources/libMultiMarkdown/writer.c @@ -169,6 +169,14 @@ scratch_pad * scratch_pad_new(mmd_engine * e, short format) { p->random_seed_base = 0; } + if (e->extensions & EXT_RANDOM_LABELS) { + p->random_seed_base_labels = rand() % 32000; + } else { + p->random_seed_base_labels = 0; + } + + p->label_counter = 0; + // Store links in a hash for rapid retrieval when exporting p->link_hash = NULL; link * l; @@ -452,14 +460,25 @@ char * label_from_token(const char * source, token * t) { } -char * label_from_header(const char * source, token * t) { +char * label_from_header(const char * source, token * t, scratch_pad * scratch) { char * result; + short temp_short; + token * temp_token = manual_label_from_header(t, source); if (temp_token) { result = label_from_token(source, temp_token); } else { - result = label_from_token(source, t); + if (scratch->extensions & EXT_RANDOM_LABELS) { + srand(scratch->random_seed_base_labels + scratch->label_counter); + temp_short = rand() % 32000 + 1; + result = malloc(sizeof(char) * 6); + sprintf(result, "%d", temp_short); + + scratch->label_counter++; + } else { + result = label_from_token(source, t); + } } return result; @@ -1968,6 +1987,9 @@ void mmd_engine_export_token_tree(DString * out, mmd_engine * e, short format) { // Preserve asset_hash for possible use in export e->asset_hash = scratch->asset_hash; + // Preserve random label seed + e->random_seed_base_labels = scratch->random_seed_base_labels; + scratch_pad_free(scratch); } diff --git a/Sources/libMultiMarkdown/writer.h b/Sources/libMultiMarkdown/writer.h index 6922a9d..7749564 100644 --- a/Sources/libMultiMarkdown/writer.h +++ b/Sources/libMultiMarkdown/writer.h @@ -90,6 +90,9 @@ typedef struct { int random_seed_base; + int random_seed_base_labels; + int label_counter; + stack * used_citations; stack * inline_citations_to_free; struct fn_holder * citation_hash; @@ -219,7 +222,7 @@ void link_free(link * l); void footnote_free(footnote * f); char * label_from_token(const char * source, token * t); -char * label_from_header(const char * source, token * t); +char * label_from_header(const char * source, token * t, scratch_pad * scratch); void parse_brackets(const char * source, scratch_pad * scratch, token * bracket, link ** link, short * skip_token, bool * free_link); diff --git a/Sources/multimarkdown/main.c b/Sources/multimarkdown/main.c index 5640d8d..5cdb764 100644 --- a/Sources/multimarkdown/main.c +++ b/Sources/multimarkdown/main.c @@ -75,7 +75,7 @@ // argtable structs struct arg_lit *a_help, *a_version, *a_compatibility, *a_nolabels, *a_batch, - *a_accept, *a_reject, *a_full, *a_snippet, *a_random, *a_meta, + *a_accept, *a_reject, *a_full, *a_snippet, *a_random, *a_unique, *a_meta, *a_notransclude, *a_nosmart, *a_opml, *a_itmz; struct arg_str *a_format, *a_lang, *a_extract; struct arg_file *a_file, *a_o; @@ -147,6 +147,7 @@ int main(int argc, char** argv) { a_snippet = arg_lit0("s", "snippet", "force a snippet"), a_compatibility = arg_lit0("c", "compatibility", "Markdown compatibility mode"), a_random = arg_lit0(NULL, "random", "use random numbers for footnote anchors"), + a_unique = arg_lit0(NULL, "unique", "use random numbers for header labels unless manually specified"), a_nosmart = arg_lit0(NULL, "nosmart", "Disable smart typography"), a_nolabels = arg_lit0(NULL, "nolabels", "Disable id attributes for headers"), a_notransclude = arg_lit0(NULL, "notransclude", "Disable file transclusion"), @@ -275,6 +276,11 @@ int main(int argc, char** argv) { extensions |= EXT_RANDOM_FOOT; } + if (a_unique->count > 0) { + // Use random header labels + extensions |= EXT_RANDOM_LABELS; + } + if (a_format->count > 0) { if (strcmp(a_format->sval[0], "html") == 0) { format = FORMAT_HTML;