author | Olivier Brunel
<jjk@jjacky.com> 2022-12-24 21:02:50 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2022-12-24 21:18:03 UTC |
parent | 90b25947ba252dcbca5062021093f7b5ecf1ed36 |
main.c | +50 | -18 |
diff --git a/main.c b/main.c index 20e4e1e..8e1fd3d 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,9 @@ struct ctx { } buf; }; +static int highlight_code_text(const char *text, size_t size, void *ctx_); +static int escape_text(FILE *f, const char *text, size_t size); + static int enter_block(MD_BLOCKTYPE type, void *details, void *ctx_) { switch (type) { @@ -207,13 +210,18 @@ static int leave_block(MD_BLOCKTYPE type, void *details, void *ctx_) printf("<pre>"); } - fwrite(ctx->buf.str, 1, ctx->buf.len, stdout); + int flags = ctx->code.flags; + ctx->code.flags = 0; - if (ctx->code.flags & CODE_LINES) + if (ctx->code.flags & CODE_HIGHLIGHT) + highlight_code_text(ctx->buf.str, ctx->buf.len, ctx); + else + fwrite(ctx->buf.str, 1, ctx->buf.len, stdout); + + if (flags & CODE_LINES) printf("</code>"); else printf("</pre>"); - ctx->code.flags = 0; } } break; @@ -247,7 +255,7 @@ static int attribute(MD_ATTRIBUTE *attr, void *ctx_) switch (attr->substr_types[n]) { case MD_TEXT_NORMAL: case MD_TEXT_ENTITY: - printf("%.*s", l, attr->text + attr->substr_offsets[n]); + escape_text(stdout, attr->text, l); break; case MD_TEXT_NULLCHAR: @@ -365,7 +373,7 @@ static int leave_span(MD_SPANTYPE type, void *details, void *ctx_) return 0; } -static int escape_text(const char *text, size_t size) +static int escape_text(FILE *f, const char *text, size_t size) { size_t last = 0; for (size_t n = 0; n < size; ++n) { @@ -382,12 +390,12 @@ static int escape_text(const char *text, size_t size) /* fall through */ case '"': if (!esc) esc = """; - printf("%.*s%s", (int) (n - last), text + last, esc); + fprintf(f, "%.*s%s", (int) (n - last), text + last, esc); last = n + 1; break; } } - printf("%.*s", (int) (size - last), text + last); + fprintf(f, "%.*s", (int) (size - last), text + last); return 0; } @@ -420,7 +428,7 @@ static int text(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *ctx_) { switch (type) { case MD_TEXT_NORMAL: - return escape_text(text, size); + return escape_text(stdout, text, size); case MD_TEXT_NULLCHAR: break; @@ -434,7 +442,7 @@ static int text(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *ctx_) break; case MD_TEXT_ENTITY: - printf("%.*s", size, text); + escape_text(stdout, text, size); break; case MD_TEXT_CODE: @@ -442,7 +450,7 @@ static int text(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *ctx_) struct ctx *ctx = ctx_; if (!(ctx->code.flags & CODE_BUFFERED)) { - printf("%.*s", size, text); + escape_text(stdout, text, size); break; } @@ -454,17 +462,41 @@ static int text(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *ctx_) if (ctx->code.flags & CODE_HIGHLIGHT) return highlight_code_text(text, size, ctx_); else - fprintf(ctx->buf.f, "%.*s", size, text); - break; + return escape_text(ctx->buf.f, text, size); } case MD_TEXT_HTML: - if (size == 4 && !strncmp(text, "<hl>", 4)) - printf("<span class=\"highlighted\">"); - else if (size == 5 && !strncmp(text, "</hl>", 5)) - printf("</span>"); - else - printf("%.*s", size, text); + ; +#define TAG(t,r) { "<" t ">", 2 + strlen(t), r } + struct { + const char *name; + size_t len; + const char *repl; + } tags[] = { + TAG("hl", "<span class=\"highlighted\">"), + TAG("/hl", "</span>"), + TAG("kbd", NULL), + TAG("/kbd", NULL), + TAG("btn", "<span class=\"button\">"), + TAG("/btn", "</span>"), + TAG("mbl", "<span class=\"mbl\"></span>"), + TAG("mbr", "<span class=\"mbr\"></span>"), + TAG("mbw", "<span class=\"mbw\"></span>"), + }; +#undef TAG + + int i, n; + for (i = 0, n = sizeof(tags) / sizeof(*tags); i < n; ++i) { + if (size == tags[i].len && !strncmp(text, tags[i].name, tags[i].len)) { + if (tags[i].repl) + printf("%s", tags[i].repl); + else + printf("%.*s", (int) tags[i].len, tags[i].name); + break; + } + } + if (i == n) + escape_text(stdout, text, size); break; case MD_TEXT_LATEXMATH: