summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c82
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("&mdash;"), 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:", &param,
+ while ((r = arg_get(&a, "?sliqc:h:t:L:", &param,
"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;
}