summaryrefslogtreecommitdiff
path: root/src/creole.c
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 /src/creole.c
parentcd39c2a2fdf57b82fa8584cac3c201b8aafb72b5 (diff)
feat(creole): Support strong/bold
Diffstat (limited to 'src/creole.c')
-rw-r--r--src/creole.c26
1 files changed, 25 insertions, 1 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) {