author | Olivier Brunel
<jjk@jjacky.com> 2023-01-02 13:02:46 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-01-04 15:10:17 UTC |
parent | f51fec07240b8c44dbec188b66f28068916605b9 |
main.c | +66 | -48 |
diff --git a/main.c b/main.c index ef3e7ea..5555294 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ enum { OPT_NO_CSS = (1 << 0), OPT_INLINE_CSS = (1 << 1), OPT_OVERWRITE = (1 << 2), + OPT_NO_TOC = (1 << 3), }; enum { @@ -330,39 +331,45 @@ enter_block(MD_BLOCKTYPE type, void *details, void *ctx_) } if (!raw_str(ctx, "</head><body>") || (ctx->doc.oheader && !raw_str(ctx, ctx->sa.s + ctx->doc.oheader)) - || !raw_str(ctx, "<main><header><section><h1>") - || !escape_text(ctx, ctx->doc.title, strlen(ctx->doc.title)) - || !raw_str(ctx, "</h1></section><nav><ul>")) + || !raw_str(ctx, "<main>")) return ERR_PARSER_ENTER_BLOCK; - for (int i = 0; i < ctx->nb_pages; ++i) { - if (!raw_str(ctx, "<li><a href=\"") + if (!(ctx->options & OPT_NO_TOC)) { + if (!raw_str(ctx, "<header><section><h1>") + || !escape_text(ctx, ctx->doc.title, strlen(ctx->doc.title)) + || !raw_str(ctx, "</h1></section><nav><ul>")) + return ERR_PARSER_ENTER_BLOCK; + for (int i = 0; i < ctx->nb_pages; ++i) { + if (!raw_str(ctx, "<li><a href=\"") || !escape_text(ctx, str_file(i), strlen(str_file(i))) || !raw_str(ctx, "\">") || !escape_text(ctx, str_title(i), strlen(str_title(i))) || !raw_str(ctx, "</a>")) - return ERR_PARSER_ENTER_BLOCK; + return ERR_PARSER_ENTER_BLOCK; - /* remember positions for TOC */ - if (i == ctx->cur_page) { - /* where to include it */ - ctx->otoc = ctx->sa_out.len; + /* remember positions for TOC */ + if (i == ctx->cur_page) { + /* where to include it */ + ctx->otoc = ctx->sa_out.len; - /* open it */ - ctx->doc.flags |= DOC_BUFFERING; - if (!raw_str(ctx, "<ul>")) { + /* open it */ + ctx->doc.flags |= DOC_BUFFERING; + if (!raw_str(ctx, "<ul>")) { + ctx->doc.flags &= ~DOC_BUFFERING; + return ERR_PARSER_TOC; + } + ctx->toc_lvl = 1; ctx->doc.flags &= ~DOC_BUFFERING; - return ERR_PARSER_TOC; } - ctx->toc_lvl = 1; - ctx->doc.flags &= ~DOC_BUFFERING; } + if (!raw_str(ctx, "</ul></nav></header>")) + return ERR_PARSER_ENTER_BLOCK; } + + if (!raw_str(ctx, "<section>")) + return ERR_PARSER_ENTER_BLOCK; #undef str_title #undef str_file - - if (!raw_str(ctx, "</ul></nav></header><section>")) - return ERR_PARSER_ENTER_BLOCK; } break; @@ -426,16 +433,18 @@ enter_block(MD_BLOCKTYPE type, void *details, void *ctx_) return ERR_PARSER_ENTER_BLOCK; ctx->doc.flags |= DOC_HAS_TITLE | DOC_BUFFERING; - /* TOC */ - for ( ; ctx->toc_lvl < d->level; ++ctx->toc_lvl) { - if (!raw_str(ctx, "<ul>")) - return ERR_PARSER_TOC; - } - for ( ; ctx->toc_lvl > d->level; --ctx->toc_lvl) { - if (!raw_str(ctx, "</ul>")) - return ERR_PARSER_TOC; + if (!(ctx->options & OPT_NO_TOC)) { + /* TOC */ + for ( ; ctx->toc_lvl < d->level; ++ctx->toc_lvl) { + if (!raw_str(ctx, "<ul>")) + return ERR_PARSER_TOC; + } + for ( ; ctx->toc_lvl > d->level; --ctx->toc_lvl) { + if (!raw_str(ctx, "</ul>")) + return ERR_PARSER_TOC; + } + ctx->buf.salen = ctx->buf.sa.len; } - ctx->buf.salen = ctx->buf.sa.len; } break; @@ -603,17 +612,19 @@ leave_block(MD_BLOCKTYPE type, void *details, void *ctx_) || !raw_str(ctx, ">")) return ERR_PARSER_LEAVE_BLOCK; - /* TOC */ - char toc[l]; - memcpy(toc, s, l); - ctx->doc.flags |= DOC_BUFFERING; - if (!raw_str(ctx, "<li><a href=\"#") - || !anchor(ctx, toc, l) - || !raw_str(ctx, "\">") - || !strip_tags(ctx, toc, l, 1) - || !raw_str(ctx, "</a>")) - return ERR_PARSER_TOC; - ctx->doc.flags &= ~DOC_BUFFERING; + if (!(ctx->options & OPT_NO_TOC)) { + /* TOC */ + char toc[l]; + memcpy(toc, s, l); + ctx->doc.flags |= DOC_BUFFERING; + if (!raw_str(ctx, "<li><a href=\"#") + || !anchor(ctx, toc, l) + || !raw_str(ctx, "\">") + || !strip_tags(ctx, toc, l, 1) + || !raw_str(ctx, "</a>")) + return ERR_PARSER_TOC; + ctx->doc.flags &= ~DOC_BUFFERING; + } } break; @@ -941,16 +952,18 @@ convert_page(struct ctx *ctx, int fddest) buf); } - /* close TOC */ - ctx->doc.flags |= DOC_BUFFERING; - for ( ; ctx->toc_lvl > 0; --ctx->toc_lvl) { - if (!raw_str(ctx, "</ul>")) { - char buf[UINT32_FMT]; - buf[uint32_fmt(buf, (uint32) ERR_PARSER_TOC)] = '\0'; - ret_strerr_warnwu2x(ERR_PARSER, "parser internal error ", buf); + if (!(ctx->options & OPT_NO_TOC)) { + /* close TOC */ + ctx->doc.flags |= DOC_BUFFERING; + for ( ; ctx->toc_lvl > 0; --ctx->toc_lvl) { + if (!raw_str(ctx, "</ul>")) { + char buf[UINT32_FMT]; + buf[uint32_fmt(buf, (uint32) ERR_PARSER_TOC)] = '\0'; + ret_strerr_warnwu2x(ERR_PARSER, "parser internal error ", buf); + } } + ctx->doc.flags &= ~DOC_BUFFERING; } - ctx->doc.flags &= ~DOC_BUFFERING; /* write output : */ if ( /* up to TOC position */ @@ -1064,6 +1077,7 @@ help(void) " -I, --inline-css Use inline CSS instead of external files\n" " -l, --lang LNG Set LNG as language attribute\n" " -o, --overwrite Overwrite destination files if already exist\n" + " -T, --no-toc Don't write a TOC on each page\n" " -t, --title TITLE Set TITLE as general (across all pages) title\n" ); } @@ -1107,10 +1121,11 @@ main (int argc, char *argv[]) { "inline-css", no_argument, NULL, 'I' }, { "lang", no_argument, NULL, 'l' }, { "overwrite", no_argument, NULL, 'o' }, + { "no-toc", no_argument, NULL, 'T' }, { "title", required_argument, NULL, 't' }, { NULL, 0, NULL, 0 }, }; - while ((c = getopt_long(argc, argv, "a:Cc:d:F:H:hIl:ot:", opts, NULL)) != -1) switch (c) { + while ((c = getopt_long(argc, argv, "a:Cc:d:F:H:hIl:oTt:", opts, NULL)) != -1) switch (c) { case 'a': ctx.doc.author = optarg; break; @@ -1140,6 +1155,9 @@ main (int argc, char *argv[]) case 'o': ctx.options |= OPT_OVERWRITE; break; + case 'T': + ctx.options |= OPT_NO_TOC; + break; case 't': ctx.doc.title = optarg; break;