diff options
author | Linnnus <[email protected]> | 2024-02-16 23:18:00 +0100 |
---|---|---|
committer | Linnnus <[email protected]> | 2024-02-16 23:18:00 +0100 |
commit | dd4f820139f81ae5013824f24c5392b567562c41 (patch) | |
tree | cadf052ec09e2b957bb8dbff06de1b91b1628477 | |
parent | 90f4eb831fd6f1e8a293851f1b8f2ed5238f5e58 (diff) |
feat(creole): Add emphasis
-rw-r--r-- | src/creole-test.c | 133 | ||||
-rw-r--r-- | src/creole.c | 24 |
2 files changed, 49 insertions, 108 deletions
diff --git a/src/creole-test.c b/src/creole-test.c index ee29e54..1157721 100644 --- a/src/creole-test.c +++ b/src/creole-test.c @@ -125,6 +125,32 @@ struct { .output = "<p>" "<a href=\"http //example.com/examplepage\">Example Page</a></p>" }, + { + .name = "Emphasis", + .input = "//Emphasis//", + .output = "<p><em>Emphasis</em></p>" + }, + { + .name = "Emphasis spans multiple lines", + .input = "Bold and italics should //be\nable// to cross lines.", + .output = "<p>Bold and italics should <em>be\nable</em> to cross lines.</p>" + }, + { + .name = "Emphasis does not cross paragraph boundaries", + .input = "This text should //not\n\nbe emphased// as it crosses a paragraph boundary.", + .output = "<p>This text should //not</p>" + "<p>be emphased// as it crosses a paragraph boundary.</p>" + }, + { + .name = "URL/emphasis ambiguity", + .input = "This is an //italic// text. This is a url " + "http://www.wikicreole.org. This is what can go wrong //this " + "should be an italic text//.", + .output = "<p>This is an <em>italic</em> text. This is a url " + "<a href=\"http://www.wikicreole.org\">" + "http://www.wikicreole.org</a>. This is what can go wrong " + "<em>this should be an italic text</em>.</p>" + }, #if 0 { .name = "Simple unordered list", @@ -198,113 +224,6 @@ struct { .input = "**Strong**", .output = "<p><strong>Strong</strong></p>" }, - { - .name = "Emphasis", - .input = "//Emphasis//", - .output = "<p><em>Emphasis</em></p>" - }, - { - .name = "Multi-line emphasis", - .input = "Bold and italics should //be\nable// to cross lines.\n\n" - "But, should //not be...\n\n...able// to cross paragraphs.", - .output = "<p>Bold and italics should <em>be\nable</em> to cross lines.\n</p>" - "<p>\nBut, should //not be...\n</p>" - "<p>\n...able// to cross paragraphs.</p>" - }, - { - .name = "URL/emphasis ambiguity", - .input = "This is an //italic// text. This is a url " - "http //www.wikicreole.org. This is what can go wrong //this " - "should be an italic text//.", - .output = "<p>This is an <em>italic</em> text. This is a url " - "<a href=\"http //www.wikicreole.org\">" - "http //www.wikicreole.org</a>. This is what can go wrong " - "<em>this should be an italic text</em>.</p>" - }, - { - .name = "Difficult emphasis #1", - .input = "// http //www.link.org //", - .output = "<p><em> <a href=\"http //www.link.org\">" - "http //www.link.org</a> </em></p>" - }, - { - .name = "Difficult emphasis #2", - .input = "// http //", - .output = "<p><em> http </em></p>" - }, - { - .name = "Difficult emphasis #3", - .input = "// httphpthtpht //", - .output = "<p><em> httphpthtpht </em></p>" - }, - { - .name = "Difficult emphasis #4", - .input = "// http //", - .output = "<p><em> http </em></p>" - }, - { - .name = "Difficult emphasis #5", - .input = "// http //", - .output = "<p>// <a href=\"http //\">http //</a></p>" - }, - { - .name = "Difficult emphasis #6", - .input = "// http ////", - .output = "<p><em> <a href=\"http //\">http //</a></em></p>" - }, - { - .name = "Difficult emphasis #7", - .input = "//httphpthtphtt//", - .output = "<p><em>httphpthtphtt</em></p>" - }, - { - .name = "Difficult emphasis #8", - .input = "//http //link.org//", - .output = "<p><em><a href=\"http //link.org\">" - "http //link.org</a></em></p>" - }, - { - .name = "Difficult emphasis #9", - .input = "// ftp //www.link.org //", - .output = "<p><em> <a href=\"ftp //www.link.org\">" - "ftp //www.link.org</a> </em></p>" - }, - { - .name = "Difficult emphasis #10", - .input = "// ftp //", - .output = "<p><em> ftp </em></p>" - }, - { - .name = "Difficult emphasis #11", - .input = "// fttpfptftpft //", - .output = "<p><em> fttpfptftpft </em></p>" - }, - { - .name = "Difficult emphasis #12", - .input = "// ftp //", - .output = "<p><em> ftp </em></p>" - }, - { - .name = "Difficult emphasis #13", - .input = "// ftp //", - .output = "<p>// <a href=\"ftp //\">ftp //</a></p>" - }, - { - .name = "Difficult emphasis #14", - .input = "// ftp ////", - .output = "<p><em> <a href=\"ftp //\">ftp //</a></em></p>" - }, - { - .name = "Difficult emphasis #15", - .input = "//fttpfptftpftt//", - .output = "<p><em>fttpfptftpftt</em></p>" - }, - { - .name = "Difficult emphasis #16", - .input = "//ftp //link.org//", - .output = "<p><em><a href=\"ftp //link.org\">" - "ftp //link.org</a></em></p>" - } #endif }; diff --git a/src/creole.c b/src/creole.c index 462dc50..9331bcb 100644 --- a/src/creole.c +++ b/src/creole.c @@ -18,6 +18,7 @@ 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); int do_link(const char *begin, const char *end, bool new_block, FILE *out); int do_raw_url(const char *begin, const char *end, bool new_block, FILE *out); +int do_emphasis(const char *begin, const char *end, bool new_block, FILE *out); // Prints string escaped. void hprint(FILE *out, const char *begin, const char *end) { @@ -42,7 +43,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 int (* parser_t)(const char *begin, const char *end, bool new_block, FILE *out); -static parser_t parsers[] = { do_headers, do_paragraph, do_link, do_raw_url, do_replacements }; +static parser_t parsers[] = { do_headers, do_paragraph, do_emphasis, do_link, do_raw_url, do_replacements }; int do_headers(const char *begin, const char *end, bool new_block, FILE *out) { if (!new_block) { // Headers are block-level elements. @@ -245,6 +246,27 @@ end_url: return q - begin; } +int do_emphasis(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] == '~' && stop[-1] == ':'); + if (stop == NULL) { + return 0; + } + + fputs("<em>", out); + process(start, stop, false, out); + fputs("</em>", 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) { |