nihdoc

WIP markup parser (txt -> html)
git clone git://git.alexkarle.com.com/blag
Log | Files | Refs | README | LICENSE

commit 3816e95226c17819ddaaf01a676522698b5edc52 (patch)
parent 90709a072f94c742c7b85a0e50c5390e7071e364
Author: Alex Karle <alex@alexkarle.com>
Date:   Thu, 23 Dec 2021 21:12:24 -0500

Fix [ in code blocks and further consolidate formats

This should make it easier to add ~strikethrough~ and other formats, if
desired!

Diffstat:
Mblag.c | 41+++++++++++++++++++++++------------------
Mtest/big.html | 1+
Mtest/big.txt | 1+
3 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/blag.c b/blag.c @@ -10,6 +10,12 @@ #include <unistd.h> #include <stdbool.h> +char *FMT_STRS[] = { + ['_'] = "em", + ['*'] = "strong", + ['`'] = "code", +}; + enum Block { NONE, HEADER, @@ -32,9 +38,7 @@ typedef struct State { enum Block in; enum Link in_link; int hlvl; - bool in_code; - bool in_ital; - bool in_bold; + bool fmts[256]; /* indexed by _ * ` */ bool escape; char lnkbuf[2048]; int lnkidx; @@ -113,15 +117,23 @@ void handle_lf(state *s) { } } -int toggle_format(state *s, char *fmt, int enabled, int allow_in_code) { - if ((allow_in_code || !s->in_code) && s->in_link != URL_PARSE && s->in != CODE) { +bool fmt_disabled(state *s) { + /* `` blocks disable all but the next `, likewise CODE makes all disabled */ + if (s->in == CODE) { + return true; + } else { + return s->fmts['`'] && s->c != '`'; + } +} + +void toggle_format(state *s) { + if (!fmt_disabled(s) && s->in_link != URL_PARSE && s->in != CODE) { maybe_startp(s); - printf("<%s%s>", enabled ? "/" : "", fmt); - return !enabled; + printf("<%s%s>", s->fmts[s->c] ? "/" : "", FMT_STRS[s->c]); + s->fmts[s->c] ^= true; } else { putesc(s->c); } - return enabled; } int parse() { @@ -132,9 +144,6 @@ int parse() { .in = NONE, .in_link = NOL, .hlvl = 0, - .in_code = false, - .in_ital = false, - .in_bold = false, .escape = false, .lnkbuf = {0}, .lnkidx = 0, @@ -212,14 +221,10 @@ int parse() { putesc(c); } break; - case '`': - s.in_code = toggle_format(&s, "code", s.in_code, 1); - break; case '*': - s.in_bold = toggle_format(&s, "strong", s.in_bold, 0); - break; + case '`': case '_': - s.in_ital = toggle_format(&s, "em", s.in_ital, 0); + toggle_format(&s); break; case '\t': case '>': @@ -233,7 +238,7 @@ int parse() { } break; case '[': - if (s.in_link == NOL && !s.in_code) { + if (s.in_link == NOL && !fmt_disabled(&s)) { maybe_startp(&s); s.in_link = URL_PARSE; s.lnkidx = 0; diff --git a/test/big.html b/test/big.html @@ -60,6 +60,7 @@ my <a href="gopher://alexkarle.com">gopherhole</a>. <pre><code>$ this is a code block $ *bold* and _italics_ and `code` have no effect! $ git status +$ [ not a link ] ! </code></pre> <p> &lt;html&gt; is escaped! diff --git a/test/big.txt b/test/big.txt @@ -35,6 +35,7 @@ my [gopher://alexkarle.com gopherhole]. $ this is a code block $ *bold* and _italics_ and `code` have no effect! $ git status + $ [ not a link ] ! <html> is escaped!