From dd4f820139f81ae5013824f24c5392b567562c41 Mon Sep 17 00:00:00 2001 From: Linnnus Date: Fri, 16 Feb 2024 23:18:00 +0100 Subject: feat(creole): Add emphasis --- src/creole-test.c | 133 +++++++++++------------------------------------------- src/creole.c | 24 +++++++++- 2 files changed, 49 insertions(+), 108 deletions(-) (limited to 'src') 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 = "

" "Example Page

" }, + { + .name = "Emphasis", + .input = "//Emphasis//", + .output = "

Emphasis

" + }, + { + .name = "Emphasis spans multiple lines", + .input = "Bold and italics should //be\nable// to cross lines.", + .output = "

Bold and italics should be\nable to cross lines.

" + }, + { + .name = "Emphasis does not cross paragraph boundaries", + .input = "This text should //not\n\nbe emphased// as it crosses a paragraph boundary.", + .output = "

This text should //not

" + "

be emphased// as it crosses a paragraph boundary.

" + }, + { + .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 = "

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.

" + }, #if 0 { .name = "Simple unordered list", @@ -198,113 +224,6 @@ struct { .input = "**Strong**", .output = "

Strong

" }, - { - .name = "Emphasis", - .input = "//Emphasis//", - .output = "

Emphasis

" - }, - { - .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 = "

Bold and italics should be\nable to cross lines.\n

" - "

\nBut, should //not be...\n

" - "

\n...able// to cross paragraphs.

" - }, - { - .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 = "

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.

" - }, - { - .name = "Difficult emphasis #1", - .input = "// http //www.link.org //", - .output = "

" - "http //www.link.org

" - }, - { - .name = "Difficult emphasis #2", - .input = "// http //", - .output = "

http

" - }, - { - .name = "Difficult emphasis #3", - .input = "// httphpthtpht //", - .output = "

httphpthtpht

" - }, - { - .name = "Difficult emphasis #4", - .input = "// http //", - .output = "

http

" - }, - { - .name = "Difficult emphasis #5", - .input = "// http //", - .output = "

// http //

" - }, - { - .name = "Difficult emphasis #6", - .input = "// http ////", - .output = "

http //

" - }, - { - .name = "Difficult emphasis #7", - .input = "//httphpthtphtt//", - .output = "

httphpthtphtt

" - }, - { - .name = "Difficult emphasis #8", - .input = "//http //link.org//", - .output = "

" - "http //link.org

" - }, - { - .name = "Difficult emphasis #9", - .input = "// ftp //www.link.org //", - .output = "

" - "ftp //www.link.org

" - }, - { - .name = "Difficult emphasis #10", - .input = "// ftp //", - .output = "

ftp

" - }, - { - .name = "Difficult emphasis #11", - .input = "// fttpfptftpft //", - .output = "

fttpfptftpft

" - }, - { - .name = "Difficult emphasis #12", - .input = "// ftp //", - .output = "

ftp

" - }, - { - .name = "Difficult emphasis #13", - .input = "// ftp //", - .output = "

// ftp //

" - }, - { - .name = "Difficult emphasis #14", - .input = "// ftp ////", - .output = "

ftp //

" - }, - { - .name = "Difficult emphasis #15", - .input = "//fttpfptftpftt//", - .output = "

fttpfptftpftt

" - }, - { - .name = "Difficult emphasis #16", - .input = "//ftp //link.org//", - .output = "

" - "ftp //link.org

" - } #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("", out); + process(start, stop, false, out); + fputs("", 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) { -- cgit v1.2.3