Skip to content

Commit

Permalink
Backport Upskirt changes
Browse files Browse the repository at this point in the history
- Improve quoting/striking through inner spans
- Make `put_scaped_char` more sane
- Make autolinking case-insensitive
  • Loading branch information
vmg committed Apr 22, 2011
1 parent 612b142 commit e328f33
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 104 deletions.
25 changes: 17 additions & 8 deletions ext/markdown.c
Expand Up @@ -137,7 +137,7 @@ is_safe_link(const char *link, size_t link_len)
for (i = 0; i < valid_uris_count; ++i) {
size_t len = strlen(valid_uris[i]);

if (link_len > len && memcmp(link, valid_uris[i], len) == 0)
if (link_len > len && strncasecmp(link, valid_uris[i], len) == 0)
return 1;
}

Expand Down Expand Up @@ -397,7 +397,7 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c

work = rndr_newbuf(rndr);
parse_inline(work, rndr, data, i);
r = rndr->make.emphasis(ob, work, c, rndr->make.opaque);
r = rndr->make.emphasis(ob, work, rndr->make.opaque);
rndr_popbuf(rndr);
return r ? i + 1 : 0;
}
Expand All @@ -410,11 +410,14 @@ parse_emph1(struct buf *ob, struct render *rndr, char *data, size_t size, char c
static size_t
parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c)
{
int (*render_method)(struct buf *ob, struct buf *text, void *opaque);
size_t i = 0, len;
struct buf *work = 0;
int r;

if (!rndr->make.double_emphasis)
render_method = (c == '~') ? rndr->make.strikethrough : rndr->make.double_emphasis;

if (!render_method)
return 0;

while (i < size) {
Expand All @@ -425,7 +428,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !isspace(data[i - 1])) {
work = rndr_newbuf(rndr);
parse_inline(work, rndr, data, i);
r = rndr->make.double_emphasis(ob, work, c, rndr->make.opaque);
r = render_method(ob, work, rndr->make.opaque);
rndr_popbuf(rndr);
return r ? i + 2 : 0;
}
Expand Down Expand Up @@ -456,7 +459,7 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
struct buf *work = rndr_newbuf(rndr);

parse_inline(work, rndr, data, i);
r = rndr->make.triple_emphasis(ob, work, c, rndr->make.opaque);
r = rndr->make.triple_emphasis(ob, work, rndr->make.opaque);
rndr_popbuf(rndr);
return r ? i + 3 : 0;

Expand Down Expand Up @@ -484,8 +487,9 @@ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, si
size_t ret;

if (size > 2 && data[1] != c) {
/* whitespace cannot follow an opening emphasis */
if (isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
/* whitespace cannot follow an opening emphasis;
* strikethrough only takes two characters '~~' */
if (c == '~' || isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
return 0;

return ret + 1;
Expand All @@ -499,7 +503,7 @@ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, si
}

if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
if (isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
if (c == '~' || isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
return 0;

return ret + 3;
Expand Down Expand Up @@ -1970,8 +1974,13 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,

if (extensions & MKDEXT_AUTOLINK) {
rndr.active_char['h'] = char_autolink; // http, https
rndr.active_char['H'] = char_autolink;

rndr.active_char['f'] = char_autolink; // ftp
rndr.active_char['F'] = char_autolink;

rndr.active_char['m'] = char_autolink; // mailto
rndr.active_char['M'] = char_autolink;
}

/* Extension data */
Expand Down
7 changes: 4 additions & 3 deletions ext/markdown.h
Expand Up @@ -61,13 +61,14 @@ struct mkd_renderer {
/* span level callbacks - NULL or return 0 prints the span verbatim */
int (*autolink)(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque);
int (*codespan)(struct buf *ob, struct buf *text, void *opaque);
int (*double_emphasis)(struct buf *ob, struct buf *text, char c, void *opaque);
int (*emphasis)(struct buf *ob, struct buf *text, char c,void *opaque);
int (*double_emphasis)(struct buf *ob, struct buf *text, void *opaque);
int (*emphasis)(struct buf *ob, struct buf *text, void *opaque);
int (*image)(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque);
int (*linebreak)(struct buf *ob, void *opaque);
int (*link)(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque);
int (*raw_html_tag)(struct buf *ob, struct buf *tag, void *opaque);
int (*triple_emphasis)(struct buf *ob, struct buf *text, char c, void *opaque);
int (*triple_emphasis)(struct buf *ob, struct buf *text, void *opaque);
int (*strikethrough)(struct buf *ob, struct buf *text, void *opaque);

/* low level callbacks - NULL copies input directly into the output */
void (*entity)(struct buf *ob, struct buf *entity, void *opaque);
Expand Down
133 changes: 44 additions & 89 deletions ext/xhtml.c
Expand Up @@ -29,18 +29,23 @@ struct xhtml_renderopt {
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;
}
}

Expand Down Expand Up @@ -190,28 +195,34 @@ rndr_codespan(struct buf *ob, struct buf *text, void *opaque)
}

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>");
Expand Down Expand Up @@ -311,6 +322,10 @@ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
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
Expand All @@ -329,7 +344,7 @@ rndr_raw_block(struct buf *ob, struct buf *text, void *opaque)
}

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>");
Expand Down Expand Up @@ -546,8 +561,8 @@ rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)
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;
Expand All @@ -572,87 +587,25 @@ rndr_smartypants(struct buf *ob, struct buf *text, void *opaque)
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);
}
}

Expand Down Expand Up @@ -720,6 +673,7 @@ ups_toc_renderer(struct mkd_renderer *renderer)
NULL,
NULL,
rndr_triple_emphasis,
rndr_strikethrough,

NULL,
NULL,
Expand Down Expand Up @@ -763,6 +717,7 @@ ups_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
rndr_link,
rndr_raw_html,
rndr_triple_emphasis,
rndr_strikethrough,

NULL,
rndr_normal_text,
Expand Down
2 changes: 1 addition & 1 deletion lib/redcarpet.rb
Expand Up @@ -26,7 +26,7 @@
# end
#
class Redcarpet
VERSION = '1.10.0'
VERSION = '1.10.1'

# Original Markdown formatted text.
attr_reader :text
Expand Down
4 changes: 2 additions & 2 deletions redcarpet.gemspec
@@ -1,9 +1,9 @@
Gem::Specification.new do |s|
s.name = 'redcarpet'
s.version = '1.10.0'
s.version = '1.10.1'
s.summary = "Ruby bindings for libupskirt"
s.description = 'A fast and safe Markdown to (X)HTML parser'
s.date = '2011-04-21'
s.date = '2011-04-22'
s.email = 'vicent@github.com'
s.homepage = 'http://github.com/tanoku/redcarpet'
s.has_rdoc = true
Expand Down
2 changes: 1 addition & 1 deletion upskirt
Submodule upskirt updated from 311830 to f3fcab

0 comments on commit e328f33

Please sign in to comment.