From: Fletcher T. Penney Date: Sat, 4 Mar 2017 17:14:37 +0000 (-0500) Subject: FIXED: Fix algorithm for creating TOC to properly handle 'incorrect' levels X-Git-Tag: 0.4.0-b^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a30bdd663358b86cd5657353873abd9604abff1e;p=multimarkdown FIXED: Fix algorithm for creating TOC to properly handle 'incorrect' levels --- diff --git a/Sources/libMultiMarkdown/html.c b/Sources/libMultiMarkdown/html.c index 6aafb42..9ca38f4 100644 --- a/Sources/libMultiMarkdown/html.c +++ b/Sources/libMultiMarkdown/html.c @@ -293,6 +293,61 @@ void mmd_export_image_html(DString * out, const char * source, token * text, lin } +void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level) { + token * entry, * next; + short entry_level, next_level; + char * temp_char; + + print_const("\n\n"); +} + + +void mmd_export_toc_html(DString * out, const char * source, scratch_pad * scratch) { + token * entry; + size_t counter = 0; + + mmd_export_toc_entry_html(out, source, scratch, &counter, 0); +} + + void mmd_export_token_html(DString * out, const char * source, token * t, size_t offset, scratch_pad * scratch) { if (t == NULL) return; @@ -680,8 +735,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t temp_short = 0; temp_short2 = 0; pad(out, 2, scratch); - print_const("
"); + print_const("
\n"); + mmd_export_toc_html(out, source, scratch); + print_const("
"); + scratch->padded = 0; + break; for (int i = 0; i < scratch->header_stack->size; ++i) { temp_token = stack_peek_index(scratch->header_stack, i); diff --git a/Sources/libMultiMarkdown/latex.c b/Sources/libMultiMarkdown/latex.c index cab0d58..5d6bdac 100644 --- a/Sources/libMultiMarkdown/latex.c +++ b/Sources/libMultiMarkdown/latex.c @@ -370,6 +370,60 @@ void mmd_export_image_latex(DString * out, const char * source, token * text, li } +void mmd_export_toc_entry_latex(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level) { + token * entry, * next; + short entry_level, next_level; + char * temp_char; + + print_const("\\begin{itemize}\n\n"); + + // Iterate over tokens + while (*counter < scratch->header_stack->size) { + // Get token for header + entry = stack_peek_index(scratch->header_stack, *counter); + entry_level = raw_level_for_header(entry); + + if (entry_level >= level) { + // This entry is a direct descendant of the parent + temp_char = label_from_header(source, entry); + print_const("\\item "); + mmd_export_token_tree_latex(out, source, entry->child, scratch); + printf("(\\autoref{%s})\n\n", temp_char); + + if (*counter < scratch->header_stack->size - 1) { + next = stack_peek_index(scratch->header_stack, *counter + 1); + next_level = next->type - BLOCK_H1 + 1; + if (next_level > entry_level) { + // This entry has children + (*counter)++; + mmd_export_toc_entry_latex(out, source, scratch, counter, entry_level + 1); + } + } + + free(temp_char); + } else if (entry_level < level ) { + // If entry < level, exit this level + // Decrement counter first, so that we can test it again later + (*counter)--; + break; + } + + // Increment counter + (*counter)++; + } + + print_const("\\end{itemize}\n\n"); +} + + +void mmd_export_toc_latex(DString * out, const char * source, scratch_pad * scratch) { + token * entry; + size_t counter = 0; + + mmd_export_toc_entry_latex(out, source, scratch, &counter, 0); +} + + void mmd_export_token_latex(DString * out, const char * source, token * t, scratch_pad * scratch) { if (t == NULL) return; @@ -699,72 +753,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat temp_short2 = 0; pad(out, 2, scratch); - for (int i = 0; i < scratch->header_stack->size; ++i) - { - temp_token = stack_peek_index(scratch->header_stack, i); - - if (temp_token->type == temp_short2) { - // Same level -- close list item - //pad(out, 2, scratch); - } - - if (temp_short == 0) { - // First item - pad(out, 2, scratch); - print_const("\\begin{itemize}"); - scratch->padded = 0; - temp_short = temp_token->type; - temp_short2 = temp_short; - } - - // Indent? - if (temp_token->type == temp_short2) { - // Same level -- NTD - } else if (temp_token->type == temp_short2 + 1) { - // Indent - pad(out, 2, scratch); - print_const("\\begin{itemize}"); - scratch->padded = 0; - temp_short2++; - } else if (temp_token->type < temp_short2) { - // Outdent - pad(out, 2, scratch); - while (temp_short2 > temp_token->type) { - if (temp_short2 > temp_short) { - pad(out, 2, scratch); - print_const("\\end{itemize}"); - scratch->padded = 0; - } else - temp_short = temp_short2 - 1; - - temp_short2--; - } - } else { - // Skipped more than one level -- ignore - continue; - } - - temp_char = label_from_header(source, temp_token); - pad(out, 2, scratch); - print_const("\\item "); - mmd_export_token_tree_latex(out, source, temp_token->child, scratch); - printf("(\\autoref{%s})", temp_char); - scratch->padded = 0; - free(temp_char); - } - - while (temp_short2 > (temp_short)) { - pad(out, 2, scratch); - print_const("\\end{itemize}"); - scratch->padded = 0; - temp_short2--; - } - - if (temp_short) { - pad(out, 2, scratch); - print_const("\\end{itemize}"); - scratch->padded = 0; - } + mmd_export_toc_latex(out, source, scratch); scratch->padded = 0; break; diff --git a/Sources/libMultiMarkdown/odf.c b/Sources/libMultiMarkdown/odf.c index 5a349d5..3385a68 100644 --- a/Sources/libMultiMarkdown/odf.c +++ b/Sources/libMultiMarkdown/odf.c @@ -296,6 +296,61 @@ void mmd_export_image_odf(DString * out, const char * source, token * text, link } + +void mmd_export_toc_entry_odf(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level) { + token * entry, * next; + short entry_level, next_level; + char * temp_char; + + print_const("\n\n"); + + // Iterate over tokens + while (*counter < scratch->header_stack->size) { + // Get token for header + entry = stack_peek_index(scratch->header_stack, *counter); + entry_level = raw_level_for_header(entry); + + if (entry_level >= level) { + // This entry is a direct descendant of the parent + temp_char = label_from_header(source, entry); + printf("", temp_char); + mmd_export_token_tree_odf(out, source, entry->child, scratch); + print_const(""); + + if (*counter < scratch->header_stack->size - 1) { + next = stack_peek_index(scratch->header_stack, *counter + 1); + next_level = next->type - BLOCK_H1 + 1; + if (next_level > entry_level) { + // This entry has children + (*counter)++; + mmd_export_toc_entry_odf(out, source, scratch, counter, entry_level + 1); + } + } + + print_const("\n"); + free(temp_char); + } else if (entry_level < level ) { + // If entry < level, exit this level + // Decrement counter first, so that we can test it again later + (*counter)--; + break; + } + + // Increment counter + (*counter)++; + } + + print_const("\n"); +} + +void mmd_export_toc_odf(DString * out, const char * source, scratch_pad * scratch) { + token * entry; + size_t counter = 0; + + mmd_export_toc_entry_odf(out, source, scratch, &counter, 0); +} + + void mmd_export_token_odf(DString * out, const char * source, token * t, scratch_pad * scratch) { if (t == NULL) return; @@ -633,60 +688,7 @@ void mmd_export_token_odf(DString * out, const char * source, token * t, scratch temp_short2 = 0; pad(out, 2, scratch); - for (int i = 0; i < scratch->header_stack->size; ++i) - { - temp_token = stack_peek_index(scratch->header_stack, i); - - if (temp_token->type == temp_short2) { - // Same level -- close list item - print_const("\n"); - } - - if (temp_short == 0) { - // First item - print_const("\n\n"); - temp_short = temp_token->type; - temp_short2 = temp_short; - } - - // Indent? - if (temp_token->type == temp_short2) { - // Same level -- NTD - } else if (temp_token->type == temp_short2 + 1) { - // Indent - print_const("\n\n\n"); - temp_short2++; - } else if (temp_token->type < temp_short2) { - // Outdent - print_const("\n"); - while (temp_short2 > temp_token->type) { - if (temp_short2 > temp_short) - print_const("\n"); - else - temp_short = temp_short2 - 1; - - temp_short2--; - } - } else { - // Skipped more than one level -- ignore - continue; - } - - temp_char = label_from_header(source, temp_token); - - printf("", temp_char); - mmd_export_token_tree_odf(out, source, temp_token->child, scratch); - print_const(""); - free(temp_char); - } - - while (temp_short2 > (temp_short)) { - print_const("\n"); - temp_short2--; - } - - if (temp_short) - print_const("\n\n"); + mmd_export_toc_odf(out, source, scratch); scratch->padded = 1; break; diff --git a/Sources/libMultiMarkdown/writer.c b/Sources/libMultiMarkdown/writer.c index 74ce6e3..1e531e0 100644 --- a/Sources/libMultiMarkdown/writer.c +++ b/Sources/libMultiMarkdown/writer.c @@ -2126,3 +2126,25 @@ char * get_fence_language_specifier(token * fence, const char * source) { return result; } + +short raw_level_for_header(token * header) { + switch (header->type) { + case BLOCK_H1: + case BLOCK_SETEXT_1: + return 1; + case BLOCK_H2: + case BLOCK_SETEXT_2: + return 2; + case BLOCK_H3: + return 3; + case BLOCK_H4: + return 4; + case BLOCK_H5: + return 5; + case BLOCK_H6: + return 6; + } + + return 0; +} + diff --git a/Sources/libMultiMarkdown/writer.h b/Sources/libMultiMarkdown/writer.h index 61d0eb6..84b041f 100644 --- a/Sources/libMultiMarkdown/writer.h +++ b/Sources/libMultiMarkdown/writer.h @@ -236,5 +236,7 @@ char * label_from_string(const char * str); char * clean_string(const char * str, bool lowercase); +short raw_level_for_header(token * header); + #endif diff --git a/tests/MMD6Tests/Table of Contents.fodt b/tests/MMD6Tests/Table of Contents.fodt index 606111b..7c94319 100644 --- a/tests/MMD6Tests/Table of Contents.fodt +++ b/tests/MMD6Tests/Table of Contents.fodt @@ -120,6 +120,18 @@ + + + + + + + + + + + + @@ -253,69 +265,67 @@ -Table of Contents -article + Table of Contents - -Second Level - -First Level - - -Second Level b - - -Third Level - - -Second Level c - - -First Level b - - -Second level d - - -Third level d - -Fourth level d - - - - -First level - - -Second level - + +Second Level +First Level + +Second Level b + +Third Level + + +Second Level c + + +First Level b + +Third Level b +Second level d + +Third level d + +Fourth level d + + + + + + +First level + +Second level + + -Second Level +Second Level -First Level +First Level -Second Level b +Second Level b -Third Level +Third Level -Second Level c +Second Level c -First Level b +First Level b -Third Level b +Third Level b -Second level d +Second level d -Third level d +Third level d -Fourth level d +Fourth level d -First level +First level -Second level +Second level + diff --git a/tests/MMD6Tests/Table of Contents.html b/tests/MMD6Tests/Table of Contents.html index 0aab366..9fc4948 100644 --- a/tests/MMD6Tests/Table of Contents.html +++ b/tests/MMD6Tests/Table of Contents.html @@ -7,35 +7,37 @@ diff --git a/tests/MMD6Tests/Table of Contents.tex b/tests/MMD6Tests/Table of Contents.tex index c75ef61..72886c7 100644 --- a/tests/MMD6Tests/Table of Contents.tex +++ b/tests/MMD6Tests/Table of Contents.tex @@ -26,6 +26,8 @@ \begin{itemize} +\item Third Level b (\autoref{thirdlevelb}) + \item Second level d (\autoref{secondleveld}) \begin{itemize} @@ -52,6 +54,8 @@ \end{itemize} + + \chapter{Second Level } \label{secondlevel} diff --git a/tests/MMD6Tests/Tables.fodt b/tests/MMD6Tests/Tables.fodt index 04c91a0..7e21e66 100644 --- a/tests/MMD6Tests/Tables.fodt +++ b/tests/MMD6Tests/Tables.fodt @@ -291,7 +291,7 @@ - + foo bar @@ -321,7 +321,7 @@ - + foo bar @@ -351,7 +351,7 @@ - + foo bar @@ -374,7 +374,7 @@ - + foo bar @@ -410,7 +410,7 @@ - + foo bar | @@ -441,7 +441,7 @@ - + foo bar