From b5971e5a553606dbce6423961d29a6a4ad62d87b Mon Sep 17 00:00:00 2001 From: wrmr Date: Fri, 4 Apr 2025 21:21:26 -0500 Subject: add --smartq, --lang --- main.c | 82 +++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index 0cddf91..caaee7c 100644 --- a/main.c +++ b/main.c @@ -13,10 +13,12 @@ #include "args.h" typedef struct { + Str language; int standalone; int from_stdin; Str stylesheet; int inlinep; + int smartquot; int csslink; Str hvarv[1024]; Str title; @@ -268,11 +270,15 @@ BlockList blk_gather(Str src, Arena *perm) { #define Otl(a, f, b) for (Line *l = blk->lines; l; l = l->next) Ot(a, f, b) typedef enum { - IM_NONE, IM_ITAL, - IM_CODE + IM_CODE, + IM_DQUOT, + IM_NONE } InlineMarkup; +Str im_str_op[IM_NONE] = { S( ""), S( ""), S("“") }; +Str im_str_cl[IM_NONE] = { S(""), S(""), S("”") }; + typedef struct { int stkc; InlineMarkup *stkv; @@ -287,19 +293,11 @@ InlineMarkup im_last(InlineState *ms) { } void im_cat_op(Str *out, InlineMarkup mu, Arena *perm) { - switch (mu) { - case IM_ITAL: str_cat(out, S(""), perm); break; - case IM_CODE: str_cat(out, S(""), perm); break; - default: break; - } + str_cat(out, im_str_op[mu], perm); } void im_cat_cl(Str *out, InlineMarkup mu, Arena *perm) { - switch (mu) { - case IM_ITAL: str_cat(out, S(""), perm); break; - case IM_CODE: str_cat(out, S(""), perm); break; - default: break; - } + str_cat(out, im_str_cl[mu], perm); } InlineMarkup im_pop(InlineState *ms) { @@ -325,6 +323,14 @@ void im_cl(InlineState *ms, Str *out, Arena *perm) { im_cat_cl(out, im_pop(ms), perm); } +void im_tog(InlineState *ms, Str *out, InlineMarkup mu, Arena *scratch, Arena *perm) { + if (im_last(ms) == mu) { + im_cl(ms, out, perm); + } else { + im_op(ms, out, mu, scratch, perm); + } +} + void markup_inline(InlineState *ms, Str *out, Str src, Arena *scratch, Arena *perm) { if (!opts.inlinep) { str_cat_html(out, src, perm); @@ -339,15 +345,10 @@ void markup_inline(InlineState *ms, Str *out, Str src, Arena *scratch, Arena *pe str_catc_html(out, src.s[i], perm); } } else { - if (c == '`') { - im_op(ms, out, IM_CODE, scratch, perm); - } else if (c == '*') { - if (im_last(ms) == IM_ITAL) { - im_cl(ms, out, perm); - } else { - im_op(ms, out, IM_ITAL, scratch, perm); - } - } else if (str_starts(str_skip(src, i), S("---"))) { + if (c == '`') im_op(ms, out, IM_CODE, scratch, perm); + else if (c == '*') im_tog(ms, out, IM_ITAL, scratch, perm); + else if (c == '"' && opts.smartquot) im_tog(ms, out, IM_DQUOT, scratch, perm); + else if (str_starts(str_skip(src, i), S("---"))) { str_cat(out, S("—"), perm); i += 2; } else { @@ -483,7 +484,7 @@ int hvar_calc(Str param, Str *name, Str *val, Str filename) { void usage(const char *cmd) { fprintf(stderr, "usage: %s -?\n" - " %s [-s] [-i] [[-l] -c FILE] [-t TITLE] [-h NAME:ARG1[,ARG2,ARG3...]] [FILES...]\n" + " %s [-silq] [-L LANG] [-c FILE] [-t TITLE] [-h NAME:ARG1[,ARG2,ARG3...]] [FILES...]\n" "\n" " -? --help show this help text\n" " -s --standalone prefix with html metadata\n" @@ -493,14 +494,25 @@ void usage(const char *cmd) { " -l --link when combined with --css, link to an external stylehseet\n" " instead of reading from a file locally\n" " -i --inline enable inline formatting (*italics*, `code`, ---dashes)\n" - " -t --title set the document title (does nothing without --standalone)\n", + " -q --smartq enable smart quotes\n" + " -t --title set the document title (does nothing without --standalone)\n" + " -L --lang set the document's language\n", cmd, cmd); } Str html_head(Arena *m, Arena *l) { - Str h = S("\n" + Str h = S("\n"); + + if (opts.language.n) { + str_cat(&h, S("\n"), m); + } + + str_cat(&h, S( "\n" - "\n"); + "\n" + ), m); if (opts.title.s) { str_cat(&h, S(""), m); @@ -549,6 +561,14 @@ Str html_head(Arena *m, Arena *l) { str_cat(&h, S("</style>"), m); } } + + return h; +} + +Str html_tail(Arena *m, Arena *l) { + (void)l; + Str h = S(""); + if (opts.language.n) str_cat(&h, S("</html>"), m); return h; } @@ -566,13 +586,15 @@ int main(int argc, const char **argv) { Str param = { 0 }; opts.from_stdin = 1; - while ((r = arg_get(&a, "?slic:h:t:", ¶m, + while ((r = arg_get(&a, "?sliqc:h:t:L:", ¶m, "help", '?', "standalone", 's', + "smartq", 'q', "inline", 'i', ":title", 't', ":css", 'c', "link", 'l', + "lang", 'L', ":hvar", 'h')) >= ARG_OK) { Arena reset = scratch; FILE *f; @@ -586,12 +608,18 @@ int main(int argc, const char **argv) { case 'i': opts.inlinep = 1; break; + case 'q': + opts.smartquot = 1; + break; case 'c': opts.stylesheet = param; break; case 'l': opts.csslink = 1; break; + case 'L': + opts.language = param; + break; case 't': opts.title = param; break; @@ -663,5 +691,7 @@ int main(int argc, const char **argv) { doc = doc->next; } + str_put(html_tail(&perm, &scratch)); + return 0; } -- cgit 1.4.1-2-gfad0