ext/xhtml.c in redcarpet-1.10.0 vs ext/xhtml.c in redcarpet-1.10.1

- old
+ new

@@ -27,22 +27,27 @@ struct { int header_count; int current_level; } toc_data; + struct { + int in_squote; + int in_dquote; + } quotes; + unsigned int flags; }; -static inline int +static inline void put_scaped_char(struct buf *ob, char c) { switch (c) { - case '<': BUFPUTSL(ob, "&lt;"); return 1; - case '>': BUFPUTSL(ob, "&gt;"); return 1; - case '&': BUFPUTSL(ob, "&amp;"); return 1; - case '"': BUFPUTSL(ob, "&quot;"); return 1; - default: return 0; + case '<': BUFPUTSL(ob, "&lt;"); break; + case '>': BUFPUTSL(ob, "&gt;"); break; + case '&': BUFPUTSL(ob, "&amp;"); break; + case '"': BUFPUTSL(ob, "&quot;"); break; + default: bufputc(ob, c); break; } } /* lus_attr_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */ static void @@ -188,32 +193,38 @@ BUFPUTSL(ob, "</code>"); return 1; } static int -rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) +rndr_strikethrough(struct buf *ob, struct buf *text, void *opaque) { if (!text || !text->size) return 0; - if (c == '~') { - BUFPUTSL(ob, "<del>"); - bufput(ob, text->data, text->size); - BUFPUTSL(ob, "</del>"); - } else { - BUFPUTSL(ob, "<strong>"); - bufput(ob, text->data, text->size); - BUFPUTSL(ob, "</strong>"); - } + BUFPUTSL(ob, "<del>"); + bufput(ob, text->data, text->size); + BUFPUTSL(ob, "</del>"); + return 1; +} +static int +rndr_double_emphasis(struct buf *ob, struct buf *text, void *opaque) +{ + if (!text || !text->size) + return 0; + + BUFPUTSL(ob, "<strong>"); + bufput(ob, text->data, text->size); + BUFPUTSL(ob, "</strong>"); + return 1; } static int -rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) +rndr_emphasis(struct buf *ob, struct buf *text, void *opaque) { - if (!text || !text->size || c == '~') return 0; + if (!text || !text->size) return 0; BUFPUTSL(ob, "<em>"); if (text) bufput(ob, text->data, text->size); BUFPUTSL(ob, "</em>"); return 1; } @@ -309,10 +320,14 @@ } } else { bufput(ob, &text->data[i], text->size - i); } BUFPUTSL(ob, "</p>\n"); + + /* Close any open quotes at the end of the paragraph */ + options->quotes.in_squote = 0; + options->quotes.in_dquote = 0; } static void rndr_raw_block(struct buf *ob, struct buf *text, void *opaque) { @@ -327,11 +342,11 @@ bufput(ob, text->data + org, sz - org); bufputc(ob, '\n'); } static int -rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) +rndr_triple_emphasis(struct buf *ob, struct buf *text, void *opaque) { if (!text || !text->size) return 0; BUFPUTSL(ob, "<strong><em>"); bufput(ob, text->data, text->size); BUFPUTSL(ob, "</em></strong>"); @@ -544,12 +559,12 @@ } static void rndr_smartypants(struct buf *ob, struct buf *text, void *opaque) { + struct xhtml_renderopt *options = opaque; size_t i; - int open_single = 0, open_double = 0, open_tag = 0; if (!text) return; for (i = 0; i < text->size; ++i) { @@ -570,91 +585,29 @@ if (sub < SUBS_COUNT) continue; switch (c) { - case '<': - open_tag = 1; - break; - - case '>': - open_tag = 0; - break; - -#if 0 - /* - * FIXME: this is bongos. - * - * The markdown spec defines that code blocks can be delimited - * by more than one backtick, e.g. - * - * ``There is a literal backtick (`) here.`` - * <p><code>There is a literal backtick (`) here.</code></p> - * - * Obviously, there's no way to differentiate between the start - * of a code block and the start of a quoted string for smartypants - * - * Look at this piece of Python code: - * - * ``result = ''.join(['this', 'is', 'bongos'])`` - * - * This MD expression is clearly ambiguous since it can be parsed as: - * - * <p>&ldquo;result = &rdquo;.join ...</p> - * - * Or also as: - * - * <p><code>result = ''.join(['this', 'is', 'bongos'])</code></p> - * - * Fuck everything about this. This is temporarily disabled, because at GitHub - * it's probably smarter to prioritize code blocks than pretty cutesy punctuation. - * - * The equivalent closing tag for the (``), ('') has also been disabled, because - * it makes no sense to have closing tags without opening tags. - */ - case '`': - if (open_tag == 0) { - if (i + 1 < text->size && text->data[i + 1] == '`') { - BUFPUTSL(ob, "&ldquo;"); i++; - continue; - } - } - break; -#endif - case '\"': - if (open_tag == 0) { - if (smartypants_quotes(ob, text, i, open_double)) { - open_double = !open_double; - continue; - } + if (smartypants_quotes(ob, text, i, options->quotes.in_dquote)) { + options->quotes.in_dquote = !options->quotes.in_dquote; + continue; } break; case '\'': - if (open_tag == 0) { - -#if 0 /* temporarily disabled, see previous comment */ - if (i + 1 < text->size && text->data[i + 1] == '\'') { - BUFPUTSL(ob, "&rdquo;"); i++; - continue; - } -#endif - - if (smartypants_quotes(ob, text, i, open_single)) { - open_single = !open_single; - continue; - } + if (smartypants_quotes(ob, text, i, options->quotes.in_squote)) { + options->quotes.in_squote = !options->quotes.in_squote; + continue; } break; } /* * Copy raw character */ - if (!put_scaped_char(ob, c)) - bufputc(ob, c); + put_scaped_char(ob, c); } } static void toc_header(struct buf *ob, struct buf *text, int level, void *opaque) @@ -718,10 +671,11 @@ NULL, NULL, NULL, NULL, rndr_triple_emphasis, + rndr_strikethrough, NULL, NULL, NULL, @@ -761,9 +715,10 @@ rndr_image, rndr_linebreak, rndr_link, rndr_raw_html, rndr_triple_emphasis, + rndr_strikethrough, NULL, rndr_normal_text, NULL,