summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-02-04 14:29:34 +0100
committerLinnnus <[email protected]>2024-02-04 20:26:23 +0100
commit21faa99f847a4f88c6b3647158515564a7d1528f (patch)
tree2c65fb3e9626aa3e29c95111bc430944b299384c
parent48750fe720c2f4917803535ec56bc52f937764fd (diff)
feat(creole): Add basic paragraphs
In the future, we may need to keep track of state, if encountering block-level elements ends paragraphs.
-rw-r--r--src/creole-test.c77
-rw-r--r--src/creole.c26
2 files changed, 65 insertions, 38 deletions
diff --git a/src/creole-test.c b/src/creole-test.c
index 23702a1..1e25a0f 100644
--- a/src/creole-test.c
+++ b/src/creole-test.c
@@ -10,6 +10,46 @@
struct {
const char *name, *input, *output;
} tests[] = {
+ {
+ .name = "Two paragraphs next to each other.",
+ .input = "Hello,\n\nworld!",
+ .output = "<p>Hello,</p><p>world!</p>"
+ },
+ {
+ .name = "h1",
+ .input = "= Header =",
+ .output = "<h1>Header</h1>"
+ },
+ {
+ .name = "h2",
+ .input = "== Header =",
+ .output = "<h2>Header</h2>"
+ },
+ {
+ .name = "h3",
+ .input = "=== Header =",
+ .output = "<h3>Header</h3>"
+ },
+ {
+ .name = "h4",
+ .input = "==== Header =",
+ .output = "<h4>Header</h4>"
+ },
+ {
+ .name = "h5",
+ .input = "===== Header",
+ .output = "<h5>Header</h5>"
+ },
+ {
+ .name = "h6",
+ .input = "====== Header =",
+ .output = "<h6>Header</h6>"
+ },
+ {
+ .name = ">h6",
+ .input = "======= Header =",
+ .output = "<p>======= Header =</p>"
+ },
#if 0
{
.name = "Basic paragraph markup",
@@ -66,43 +106,6 @@ struct {
.input = "{{{\nPreformatted block\n}}}\n{{{Block 2}}}",
.output = "<pre>Preformatted block\n</pre><pre>Block 2</pre>"
},
-#endif
- {
- .name = "h1",
- .input = "= Header =",
- .output = "<h1>Header</h1>"
- },
- {
- .name = "h2",
- .input = "== Header =",
- .output = "<h2>Header</h2>"
- },
- {
- .name = "h3",
- .input = "=== Header =",
- .output = "<h3>Header</h3>"
- },
- {
- .name = "h4",
- .input = "==== Header =",
- .output = "<h4>Header</h4>"
- },
- {
- .name = "h5",
- .input = "===== Header",
- .output = "<h5>Header</h5>"
- },
- {
- .name = "h6",
- .input = "====== Header =",
- .output = "<h6>Header</h6>"
- },
- {
- .name = ">h6",
- .input = "======= Header =",
- .output = "<p>======= Header =</p>"
- },
-#if 0
{
.name = "Tables",
.input = "| A | B |\n| //C// | **D** \\\\ E |",
diff --git a/src/creole.c b/src/creole.c
index 7eb6ad5..b3d1a87 100644
--- a/src/creole.c
+++ b/src/creole.c
@@ -13,6 +13,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);
// A parser takes a (sub)string and returns the number of characters consumed, if any.
//
@@ -20,7 +21,7 @@ int do_headers(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 };
+static parser_t parsers[] = { do_headers, do_paragraph };
int do_headers(const char *begin, const char *end, bool new_block, FILE *out) {
if (!new_block) { // Headers are block-level elements.
@@ -63,6 +64,29 @@ int do_headers(const char *begin, const char *end, bool new_block, FILE *out) {
return -(eol - begin);
}
+int do_paragraph(const char *begin, const char *end, bool new_block, FILE *out) {
+ if (!new_block) { // Paragraphs are block-level elements.
+ return 0;
+ }
+
+ const char *stop = begin + 1;
+ while (stop + 1 < end) {
+ if (stop[0] == '\n' && stop[1] == '\n') {
+ goto found_double_newline;
+ } else {
+ stop += 1;
+ }
+ }
+ stop = end;
+found_double_newline:
+
+ fputs("<p>", out);
+ process(begin, stop, false, out);
+ fputs("</p>", out);
+
+ return -(stop - begin);
+}
+
void process(const char *begin, const char *end, bool new_block, FILE *out) {
const char *p = begin;
while (p < end) {