diff options
author | Linnnus <[email protected]> | 2024-02-04 18:45:16 +0100 |
---|---|---|
committer | Linnnus <[email protected]> | 2024-02-04 20:26:23 +0100 |
commit | aa2edcdf68676c3839593309af97b335cb8388b8 (patch) | |
tree | 46aaa67c4fb671751691af1d18bf3c520dda4f6f | |
parent | 04ef019e858e6175c7b9e61bd00bab3d383890d7 (diff) |
feat(creole): escape special HTML characters
-rw-r--r-- | src/creole-test.c | 10 | ||||
-rw-r--r-- | src/creole.c | 32 |
2 files changed, 36 insertions, 6 deletions
diff --git a/src/creole-test.c b/src/creole-test.c index 835ee42..3020c51 100644 --- a/src/creole-test.c +++ b/src/creole-test.c @@ -11,6 +11,11 @@ struct { const char *name, *input, *output; } tests[] = { { + .name = "Basic paragraph markup", + .input = "Basic paragraph test with <, >, & and \"", + .output = "<p>Basic paragraph test with <, >, & and "</p>" + }, + { .name = "Two paragraphs next to each other.", .input = "Hello,\n\nworld!", .output = "<p>Hello,</p><p>world!</p>" @@ -52,11 +57,6 @@ struct { }, #if 0 { - .name = "Basic paragraph markup", - .input = "Basic paragraph test with <, >, & and \"", - .output = "<p>Basic paragraph test with <, >, & and "</p>" - }, - { .name = "Simple unordered list", .input = "* list item\n*list item 2", .output = "<ul><li> list item</li>\n<li>list item 2</li></ul>" diff --git a/src/creole.c b/src/creole.c index b3d1a87..7472a3b 100644 --- a/src/creole.c +++ b/src/creole.c @@ -6,6 +6,7 @@ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #define LENGTH(x) (sizeof(x)/sizeof((x)[0])) @@ -14,6 +15,7 @@ void process(const char *begin, const char *end, bool new_block, FILE *out); int do_headers(const char *begin, const char *end, bool new_block, FILE *out); int do_paragraph(const char *begin, const char *end, bool new_block, FILE *out); +int do_replacements(const char *begin, const char *end, bool new_block, FILE *out); // A parser takes a (sub)string and returns the number of characters consumed, if any. // @@ -21,7 +23,7 @@ int do_paragraph(const char *begin, const char *end, bool new_block, FILE *out); // The sign of the return value determines whether a new block should begin, after the consumed text. typedef int (* parser_t)(const char *begin, const char *end, bool new_block, FILE *out); -static parser_t parsers[] = { do_headers, do_paragraph }; +static parser_t parsers[] = { do_headers, do_paragraph, do_replacements }; int do_headers(const char *begin, const char *end, bool new_block, FILE *out) { if (!new_block) { // Headers are block-level elements. @@ -87,6 +89,34 @@ found_double_newline: return -(stop - begin); } +static struct { + const char *from, *to; +} replacements[] = { + // Escaped special characters + // TODO (e.g. "\\{" should become "{" so users can escape and void it being parsed as markup + // Characters that have special meaning in HTML + {"<", "<"}, + {">", ">"}, + {"\"", """}, + {"&", "&"}, +}; + +int do_replacements(const char *begin, const char *end, bool new_block, FILE *out) +{ + for (unsigned i = 0; i < LENGTH(replacements); ++i) { + size_t length = strlen(replacements[i].from); + if (end - begin < length) { + continue; + } + if (strncmp(replacements[i].from, begin, length) == 0) { + fputs(replacements[i].to, out); + return length; + } + } + + return 0; +} + void process(const char *begin, const char *end, bool new_block, FILE *out) { const char *p = begin; while (p < end) { |