diff --git a/ext/markdown.c b/ext/markdown.c
index ce2b855b..a95c75b6 100755
--- a/ext/markdown.c
+++ b/ext/markdown.c
@@ -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;
}
@@ -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;
}
@@ -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) {
@@ -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;
}
@@ -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;
@@ -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;
@@ -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;
@@ -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 */
diff --git a/ext/markdown.h b/ext/markdown.h
index d48c8ff1..24d6f0f8 100755
--- a/ext/markdown.h
+++ b/ext/markdown.h
@@ -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);
diff --git a/ext/xhtml.c b/ext/xhtml.c
index d9d9831a..5c1b507a 100755
--- a/ext/xhtml.c
+++ b/ext/xhtml.c
@@ -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, "<"); return 1;
- case '>': BUFPUTSL(ob, ">"); return 1;
- case '&': BUFPUTSL(ob, "&"); return 1;
- case '"': BUFPUTSL(ob, """); return 1;
- default: return 0;
+ case '<': BUFPUTSL(ob, "<"); break;
+ case '>': BUFPUTSL(ob, ">"); break;
+ case '&': BUFPUTSL(ob, "&"); break;
+ case '"': BUFPUTSL(ob, """); break;
+ default: bufputc(ob, c); break;
}
}
@@ -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, "");
- bufput(ob, text->data, text->size);
- BUFPUTSL(ob, "");
- } else {
- BUFPUTSL(ob, "");
- bufput(ob, text->data, text->size);
- BUFPUTSL(ob, "");
- }
+ BUFPUTSL(ob, "");
+ bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "");
+ return 1;
+}
+
+static int
+rndr_double_emphasis(struct buf *ob, struct buf *text, void *opaque)
+{
+ if (!text || !text->size)
+ return 0;
+
+ BUFPUTSL(ob, "");
+ bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "");
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, "");
if (text) bufput(ob, text->data, text->size);
BUFPUTSL(ob, "");
@@ -311,6 +322,10 @@ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
bufput(ob, &text->data[i], text->size - i);
}
BUFPUTSL(ob, "
There is a literal backtick (`) here.
“result = ”.join ...
- * - * Or also as: - * - *result = ''.join(['this', 'is', 'bongos'])