Welcome to little lamb

Code » qmdoc » commit a9994fc

Fix escaping and other stuff

author Olivier Brunel
2022-12-24 21:02:50 UTC
committer Olivier Brunel
2022-12-24 21:18:03 UTC
parent 90b25947ba252dcbca5062021093f7b5ecf1ed36

Fix escaping and other stuff

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 = "&quot;";
-                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: