diff options
author | Linnnus <[email protected]> | 2024-02-17 01:02:24 +0100 |
---|---|---|
committer | Linnnus <[email protected]> | 2024-02-17 01:03:22 +0100 |
commit | 0f60b5f74919b8841bf9d8a9658d031e4fc503d1 (patch) | |
tree | 9e9db30e949c61297e9eb0ca58921038aa6938a3 | |
parent | cd39c2a2fdf57b82fa8584cac3c201b8aafb72b5 (diff) |
feat(creole): Support strong/bold
-rw-r--r-- | src/creole.c | 26 | ||||
-rw-r--r-- | src/creole_test_main.c | 20 |
2 files changed, 40 insertions, 6 deletions
diff --git a/src/creole.c b/src/creole.c index 8bdeb19..5804ebd 100644 --- a/src/creole.c +++ b/src/creole.c @@ -19,6 +19,7 @@ long do_replacements(const char *begin, const char *end, bool new_block, FILE *o long do_link(const char *begin, const char *end, bool new_block, FILE *out); long do_raw_url(const char *begin, const char *end, bool new_block, FILE *out); long do_emphasis(const char *begin, const char *end, bool new_block, FILE *out); +long do_bold(const char *begin, const char *end, bool new_block, FILE *out); // Prints string escaped. void hprint(FILE *out, const char *begin, const char *end) { @@ -43,7 +44,7 @@ void hprint(FILE *out, const char *begin, const char *end) { // The sign of the return value determines whether a new block should begin, after the consumed text. typedef long (* parser_t)(const char *begin, const char *end, bool new_block, FILE *out); -static parser_t parsers[] = { do_headers, do_paragraph, do_emphasis, do_link, do_raw_url, do_replacements }; +static parser_t parsers[] = { do_headers, do_paragraph, do_emphasis, do_bold, do_link, do_raw_url, do_replacements }; long do_headers(const char *begin, const char *end, bool new_block, FILE *out) { if (!new_block) { // Headers are block-level elements. @@ -267,6 +268,29 @@ long do_emphasis(const char *begin, const char *end, bool new_block, FILE *out) return stop - start + 4; /* //...// */ } +// FIXME: This is //almost// just a copy/paste of do_emphasis. Not very DRY... +// The one difficult part is that : should only be treated as an escape character for //. +long do_bold(const char *begin, const char *end, bool new_block, FILE *out) { + if (begin + 2 >= end || begin[0] != '*' || begin[1] != '*') { + return 0; + } + const char *start = begin + 2; /* // */ + + const char *stop = start; + do { + stop = strnstr(stop + 1, "**", end - (stop + 1)); + } while (stop != NULL && stop[-1] == '~'); + if (stop == NULL) { + return 0; + } + + fputs("<strong>", out); + process(start, stop, false, out); + fputs("</strong>", out); + + return stop - start + 4; /* **...** */ +} + void process(const char *begin, const char *end, bool new_block, FILE *out) { const char *p = begin; while (p < end) { diff --git a/src/creole_test_main.c b/src/creole_test_main.c index 1157721..334ba43 100644 --- a/src/creole_test_main.c +++ b/src/creole_test_main.c @@ -151,6 +151,21 @@ struct { "http://www.wikicreole.org</a>. This is what can go wrong " "<em>this should be an italic text</em>.</p>" }, + { + .name = "Bold", + .input = "**Strong**", + .output = "<p><strong>Strong</strong></p>" + }, + { + .name = "Nested bold/italic", + .input = "//**Strong and emphasized**//", + .output = "<p><em><strong>Strong and emphasized</strong></em></p>" + }, + { + .name = "Alternating bold/italic doesn't work", + .input = "//**Strong and emphasized//**", + .output = "<p><em>**Strong and emphasized</em>**</p>" + }, #if 0 { .name = "Simple unordered list", @@ -219,11 +234,6 @@ struct { .input = "Inline {{{tt}}} example {{{here}}}!", .output = "<p>Inline <tt>tt</tt> example <tt>here</tt>!</p>" }, - { - .name = "Strong", - .input = "**Strong**", - .output = "<p><strong>Strong</strong></p>" - }, #endif }; |