summaryrefslogtreecommitdiff
path: root/src/creole.c
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-02-04 18:45:16 +0100
committerLinnnus <[email protected]>2024-02-04 20:26:23 +0100
commitaa2edcdf68676c3839593309af97b335cb8388b8 (patch)
tree46aaa67c4fb671751691af1d18bf3c520dda4f6f /src/creole.c
parent04ef019e858e6175c7b9e61bd00bab3d383890d7 (diff)
feat(creole): escape special HTML characters
Diffstat (limited to 'src/creole.c')
-rw-r--r--src/creole.c32
1 files changed, 31 insertions, 1 deletions
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
+ {"<", "&lt;"},
+ {">", "&gt;"},
+ {"\"", "&quot;"},
+ {"&", "&amp;"},
+};
+
+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) {