diff options
-rw-r--r-- | main.c | 82 |
1 files 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( "<em>"), S( "<code>"), S("“") }; +Str im_str_cl[IM_NONE] = { S("</em>"), S("</code>"), 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("<em>"), perm); break; - case IM_CODE: str_cat(out, S("<code>"), 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("</em>"), perm); break; - case IM_CODE: str_cat(out, S("</code>"), 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("<!DOCTYPE html>\n" + Str h = S("<!DOCTYPE html>\n"); + + if (opts.language.n) { + str_cat(&h, S("<html lang="), m); + str_cat_uri(&h, opts.language, m); + str_cat(&h, S(">\n"), m); + } + + str_cat(&h, S( "<meta charset=utf-8>\n" - "<meta name=viewport content='width=device-width,initial-scale=1'>\n"); + "<meta name=viewport content='width=device-width,initial-scale=1'>\n" + ), m); if (opts.title.s) { str_cat(&h, S("<title>"), 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; } |