summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-02-17 01:02:24 +0100
committerLinnnus <[email protected]>2024-02-17 01:03:22 +0100
commit0f60b5f74919b8841bf9d8a9658d031e4fc503d1 (patch)
tree9e9db30e949c61297e9eb0ca58921038aa6938a3
parentcd39c2a2fdf57b82fa8584cac3c201b8aafb72b5 (diff)
feat(creole): Support strong/bold
-rw-r--r--src/creole.c26
-rw-r--r--src/creole_test_main.c20
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
};