diff --git a/html/html.c b/html/html.c index 44b69a2..5f0e767 100755 --- a/html/html.c +++ b/html/html.c @@ -162,6 +162,15 @@ rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque) BUFPUTSL(ob, "\n"); } +static void +rndr_markedtext(struct buf *ob, const struct buf *text, void *opaque) +{ + BUFPUTSL(ob, ""); + if (text) escape_html(ob, text->data, text->size); + BUFPUTSL(ob, ""); + return 1; +} + static void rndr_blockspoiler(struct buf *ob, const struct buf *text, void *opaque) { @@ -734,6 +743,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio NULL, rndr_codespan, + rndr_markedtext, rndr_spoilerspan, rndr_double_emphasis, rndr_emphasis, @@ -777,6 +787,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, rndr_autolink, rndr_codespan, + rndr_markedtext, rndr_spoilerspan, rndr_double_emphasis, rndr_emphasis, diff --git a/html_block_names.txt b/html_block_names.txt index e4d6f16..4d53165 100644 --- a/html_block_names.txt +++ b/html_block_names.txt @@ -24,3 +24,4 @@ fieldset noscript blockquote span +mark diff --git a/src/markdown.c b/src/markdown.c index fa85a71..59a8b91 100644 --- a/src/markdown.c +++ b/src/markdown.c @@ -629,6 +629,39 @@ parse_spoilerspan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_ return 0; } +static size_t +parse_markedtext(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) +{ + int (*render_method)(struct buf *ob, const struct buf *text, void *opaque); + size_t len; + size_t i = 0; + struct buf *work = 0; + int r; + + render_method = rndr->cb.markedtext; + + if (!render_method) return 0; + + while (i < size) { + len = find_emph_char(data + i, size - i, '='); + if (!len) return 0; + i += len; + + if (i + 1 < size && data[i] == '=' && data[i + 1] == '=') { + work = rndr_newbuf(rndr, BUFFER_SPAN); + parse_inline(work, rndr, data, i - 1); + r = render_method(ob, work, rndr->opaque); + rndr_popbuf(rndr, BUFFER_SPAN); + + if (!r) return 0; + + return i + 1; + } + i++; + } + return 0; +} + /* char_emphasis • single and double emphasis parsing */ static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t max_rewind, size_t max_lookbehind, size_t size) @@ -644,6 +677,13 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t ma } + if (size > 3 && c == '=' && data[1] == '=') { + if(_isspace(data[2]) || (ret = parse_markedtext(ob, rndr, data + 2, size - 2)) == 0) + return 0; + + return ret + 2; + } + if (size > 2 && data[1] != c) { /* whitespace cannot follow an opening emphasis; * strikethrough only takes two characters '~~' */ @@ -1480,6 +1520,28 @@ prefix_blockspoiler(uint8_t *data, size_t size) return 0; } +static size_t +prefix_markedtext(uint8_t *data, size_t size) +{ + size_t i = 0; + if (i < size && data[i] == ' ') i++; + if (i < size && data[i] == ' ') i++; + if (i < size && data[i] == ' ') i++; + + if (i + 1 < size && data[i] == '=' && data[i + 1] == '=') { + size_t markedtext = find_emph_char(data + i + 1, size - i - 1, '='); + if (i + markedtext < size && markedtext > 0 && data[i + markedtext] == '=') + return 0; + + if (i + 2 < size && data[i + 2] == ' ') + return i + 3; + + return i + 2; + } + + return 0; +} + /* prefix_code • returns prefix length for block code*/ static size_t prefix_code(uint8_t *data, size_t size) diff --git a/src/markdown.h b/src/markdown.h index c70a2bb..8b36be7 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -83,6 +83,7 @@ struct sd_callbacks { int (*autolink)(struct buf *ob, const struct buf *link, enum mkd_autolink type, void *opaque); int (*codespan)(struct buf *ob, const struct buf *text, void *opaque); int (*spoilerspan)(struct buf *ob, const struct buf *text, void *opaque); + int (*markedtext)(struct buf *ob, const struct buf *text, void *opaque); int (*double_emphasis)(struct buf *ob, const struct buf *text, void *opaque); int (*emphasis)(struct buf *ob, const struct buf *text, void *opaque); int (*image)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque);