author | Olivier Brunel
<jjk@jjacky.com> 2023-01-02 11:15:01 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-01-04 15:10:17 UTC |
parent | c36aab68cc9cf3b9b764c78305c808d9a0e1d27f |
main.c | +37 | -4 |
diff --git a/main.c b/main.c index ae787c9..b94596b 100644 --- a/main.c +++ b/main.c @@ -76,6 +76,8 @@ struct ctx { const char *title; const char *author; const char *lang; + size_t oheader; + size_t ofooter; int flags; } doc; struct { @@ -329,7 +331,9 @@ enter_block(MD_BLOCKTYPE type, void *details, void *ctx_) return ERR_PARSER_ENTER_BLOCK; } } - if (!raw_str(ctx, "</head><body><main><header><section><h1>") + 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>")) return ERR_PARSER_ENTER_BLOCK; @@ -538,7 +542,9 @@ leave_block(MD_BLOCKTYPE type, void *details, void *ctx_) || !escape_text(ctx, ctx->doc.author, strlen(ctx->doc.author)) || !raw_str(ctx, "<br>" "<span class=\"generated\">Generated with qmdoc</span>" - "</footer></section></main></body></html>")) + "</footer></section></main>") + || (ctx->doc.ofooter && !raw_str(ctx, ctx->sa.s + ctx->doc.ofooter)) + || !raw_str(ctx, "</body></html>")) return ERR_PARSER_LEAVE_BLOCK; break; @@ -1054,6 +1060,8 @@ help(void) outh(" -a, --author AUTHOR Set AUTHOR as author (in meta in footer)\n" " -C, --no-css Do not use CSS\n" " -d, --destdir DIR Write files into DIR\n" + " -F, --footer FILE Insert FILE as common footer\n" + " -H, --header FILE Insert FILE as common header\n" " -h, --help Show this help screen and exit\n" " -I, --inline-css Use inline CSS instead of external files\n" " -l, --lang LNG Set LNG as language attribute\n" @@ -1076,6 +1084,8 @@ main (int argc, char *argv[]) else PROG = argv[0]; char *destdir = "."; + const char *footer = NULL; + const char *header = NULL; struct ctx ctx = { .options = 0, .sa = STRALLOC_ZERO, @@ -1092,6 +1102,8 @@ main (int argc, char *argv[]) { "author", required_argument, NULL, 'a' }, { "no-css", no_argument, NULL, 'C' }, { "destdir", required_argument, NULL, 'd' }, + { "footer", required_argument, NULL, 'F' }, + { "header", required_argument, NULL, 'H' }, { "help", no_argument, NULL, 'h' }, { "inline-css", no_argument, NULL, 'I' }, { "lang", no_argument, NULL, 'l' }, @@ -1099,7 +1111,7 @@ main (int argc, char *argv[]) { "title", required_argument, NULL, 't' }, { NULL, 0, NULL, 0 }, }; - while ((c = getopt_long(argc, argv, "a:Cd:hIl:ot:", opts, NULL)) != -1) switch (c) { + while ((c = getopt_long(argc, argv, "a:Cd:F:H:hIl:ot:", opts, NULL)) != -1) switch (c) { case 'a': ctx.doc.author = optarg; break; @@ -1109,6 +1121,12 @@ main (int argc, char *argv[]) case 'd': destdir = optarg; break; + case 'F': + footer = optarg; + break; + case 'H': + header = optarg; + break; case 'h': help(); case 'I': @@ -1137,7 +1155,7 @@ main (int argc, char *argv[]) ctx.pages = pages; ctx.nb_pages = sizeof(pages) / sizeof(*pages); - outse("Scanning files..."); + outse("Scanning pages..."); for (int i = optind; i < argc; ++i) { const char *file = argv[i]; size_t len = strlen(file); @@ -1153,6 +1171,21 @@ main (int argc, char *argv[]) load_page_from_file(file, &pages[i - optind], &ctx.sa); } + if (header || footer) { + outse("Loading files..."); + + if (header) { + ctx.doc.oheader = ctx.sa.len; + if (!openreadfileclose(header, &ctx.sa, 0) || !stralloc_0(&ctx.sa)) + strerr_diefu3sys(-ERR_IO, "load data from '", header, "'"); + } + if (footer) { + ctx.doc.ofooter = ctx.sa.len; + if (!openreadfileclose(footer, &ctx.sa, 0) || !stralloc_0(&ctx.sa)) + strerr_diefu3sys(-ERR_IO, "load data from '", footer, "'"); + } + } + if (!(ctx.options & OPT_NO_CSS)) { outs((ctx.options & OPT_INLINE_CSS) ? "Loading" : "Copying"); outse(" CSS files...");