redcarpet 2.0.0b5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/README.markdown +29 -1
- data/ext/redcarpet/autolink.c +5 -6
- data/ext/redcarpet/buffer.c +27 -26
- data/ext/redcarpet/buffer.h +2 -5
- data/ext/redcarpet/houdini.h +3 -2
- data/ext/redcarpet/houdini_html_e.c +1 -1
- data/ext/redcarpet/html_blocks.h +3 -2
- data/ext/redcarpet/html_smartypants.c +4 -2
- data/ext/redcarpet/markdown.c +43 -14
- data/ext/redcarpet/redcarpet.h +2 -2
- data/ext/redcarpet/stack.h +2 -2
- data/lib/redcarpet.rb +18 -0
- data/redcarpet.gemspec +1 -1
- data/test/redcarpet_test.rb +0 -1
- metadata +7 -11
data/README.markdown
CHANGED
@@ -142,7 +142,7 @@ instantiating the renderer:
|
|
142
142
|
:safe_links_only - only generate links for protocols which are considered safe
|
143
143
|
|
144
144
|
:with_toc_data - add HTML anchors to each header in the output HTML,
|
145
|
-
to allow
|
145
|
+
to allow linking to each section.
|
146
146
|
|
147
147
|
:hard_wrap - insert HTML `<br>` tags inside on paragraphs where the origin
|
148
148
|
Markdown document had newlines (by default, Markdown ignores these
|
@@ -283,6 +283,34 @@ SmartyPants works on top of already-rendered HTML, and will ignore replacements
|
|
283
283
|
inside the content of HTML tags and inside specific HTML blocks such as
|
284
284
|
`<code>` or `<pre>`.
|
285
285
|
|
286
|
+
What? You really want to mix Markdown renderers?
|
287
|
+
------------------------------------------------
|
288
|
+
|
289
|
+
What a terrible idea! Markdown is already ill-specified enough; if you create
|
290
|
+
software that is renderer-independent, the results will be completely unreliable!
|
291
|
+
|
292
|
+
Each renderer has its own API and its own set of extensions: you should choose one
|
293
|
+
(it doesn't have to be Redcarpet, though that would be great!), write your
|
294
|
+
software accordingly, and force your users to install it. That's the
|
295
|
+
only way to have reliable and predictable Markdown output on your program.
|
296
|
+
|
297
|
+
Still, if major forces (let's say, tornadoes or other natural disasters) force you
|
298
|
+
to keep a Markdown-compatibility later, Redcarpet also supports this:
|
299
|
+
|
300
|
+
require 'redcarpet/compat'
|
301
|
+
|
302
|
+
Requiring the compatibility library will declare a `Markdown` class with the
|
303
|
+
classical RedCloth API, e.g.
|
304
|
+
|
305
|
+
Markdown.new('this is my text').to_html
|
306
|
+
|
307
|
+
This class renders 100% standards compliant Markdown with 0 extensions. Nada.
|
308
|
+
Don't even try to enable extensions with a compatibility layer, because
|
309
|
+
that's a maintance nightmare and won't work.
|
310
|
+
|
311
|
+
On a related topic: if your Markdown gem has a `lib/markdown.rb` file that
|
312
|
+
monkeypatches the Markdown class, you're a terrible human being. Just saying.
|
313
|
+
|
286
314
|
Boring legal stuff
|
287
315
|
------------------
|
288
316
|
|
data/ext/redcarpet/autolink.c
CHANGED
@@ -24,9 +24,9 @@
|
|
24
24
|
int
|
25
25
|
sd_autolink_issafe(const uint8_t *link, size_t link_len)
|
26
26
|
{
|
27
|
-
static const size_t valid_uris_count =
|
27
|
+
static const size_t valid_uris_count = 5;
|
28
28
|
static const char *valid_uris[] = {
|
29
|
-
"http://", "https://", "ftp://", "mailto
|
29
|
+
"/", "http://", "https://", "ftp://", "mailto:"
|
30
30
|
};
|
31
31
|
|
32
32
|
size_t i;
|
@@ -140,10 +140,9 @@ check_domain(uint8_t *data, size_t size)
|
|
140
140
|
else if (!isalnum(data[i]) && data[i] != '-') break;
|
141
141
|
}
|
142
142
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
return i;
|
143
|
+
/* a valid domain needs to have at least a dot.
|
144
|
+
* that's as far as we get */
|
145
|
+
return np ? i : 0;
|
147
146
|
}
|
148
147
|
|
149
148
|
size_t
|
data/ext/redcarpet/buffer.c
CHANGED
@@ -113,9 +113,35 @@ bufprintf(struct buf *buf, const char *fmt, ...)
|
|
113
113
|
if (!buf || !buf->unit)
|
114
114
|
return;
|
115
115
|
|
116
|
+
int n;
|
117
|
+
|
118
|
+
if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
|
119
|
+
return;
|
120
|
+
|
116
121
|
va_start(ap, fmt);
|
117
|
-
|
122
|
+
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
118
123
|
va_end(ap);
|
124
|
+
|
125
|
+
if (n < 0) {
|
126
|
+
#ifdef _MSC_VER
|
127
|
+
n = _vscprintf(fmt, ap);
|
128
|
+
#else
|
129
|
+
return;
|
130
|
+
#endif
|
131
|
+
}
|
132
|
+
|
133
|
+
if ((size_t)n >= buf->asize - buf->size) {
|
134
|
+
if (bufgrow(buf, buf->size + n + 1) < 0)
|
135
|
+
return;
|
136
|
+
va_start(ap, fmt);
|
137
|
+
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
138
|
+
va_end(ap);
|
139
|
+
}
|
140
|
+
|
141
|
+
if (n < 0)
|
142
|
+
return;
|
143
|
+
|
144
|
+
buf->size += n;
|
119
145
|
}
|
120
146
|
|
121
147
|
/* bufput: appends raw data to a buffer */
|
@@ -198,31 +224,6 @@ bufslurp(struct buf *buf, size_t len)
|
|
198
224
|
void
|
199
225
|
vbufprintf(struct buf *buf, const char *fmt, va_list ap)
|
200
226
|
{
|
201
|
-
int n;
|
202
227
|
|
203
|
-
if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0)
|
204
|
-
return;
|
205
|
-
|
206
|
-
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
207
|
-
|
208
|
-
if (n < 0) {
|
209
|
-
#ifdef _MSC_VER
|
210
|
-
n = _vscprintf(fmt, ap);
|
211
|
-
#else
|
212
|
-
return;
|
213
|
-
#endif
|
214
|
-
}
|
215
|
-
|
216
|
-
if ((size_t)n >= buf->asize - buf->size) {
|
217
|
-
if (bufgrow(buf, buf->size + n + 1) < 0)
|
218
|
-
return;
|
219
|
-
|
220
|
-
n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
|
221
|
-
}
|
222
|
-
|
223
|
-
if (n < 0)
|
224
|
-
return;
|
225
|
-
|
226
|
-
buf->size += n;
|
227
228
|
}
|
228
229
|
|
data/ext/redcarpet/buffer.h
CHANGED
@@ -15,8 +15,8 @@
|
|
15
15
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
16
16
|
*/
|
17
17
|
|
18
|
-
#ifndef
|
19
|
-
#define
|
18
|
+
#ifndef BUFFER_H__
|
19
|
+
#define BUFFER_H__
|
20
20
|
|
21
21
|
#include <stddef.h>
|
22
22
|
#include <stdarg.h>
|
@@ -85,7 +85,4 @@ void bufslurp(struct buf *, size_t);
|
|
85
85
|
/* bufprintf: formatted printing to a buffer */
|
86
86
|
void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
|
87
87
|
|
88
|
-
/* vbufprintf: stdarg variant of formatted printing into a buffer */
|
89
|
-
void vbufprintf(struct buf *, const char * , va_list);
|
90
|
-
|
91
88
|
#endif
|
data/ext/redcarpet/houdini.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
1
|
+
#ifndef HOUDINI_H__
|
2
|
+
#define HOUDINI_H__
|
3
3
|
|
4
4
|
#include "buffer.h"
|
5
5
|
|
@@ -17,6 +17,7 @@
|
|
17
17
|
extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);
|
18
18
|
extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);
|
19
19
|
extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);
|
20
|
+
extern void houdini_escape_xml(struct buf *ob, const uint8_t *src, size_t size);
|
20
21
|
extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);
|
21
22
|
extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);
|
22
23
|
extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);
|
data/ext/redcarpet/html_blocks.h
CHANGED
@@ -147,7 +147,7 @@ find_block_tag (str, len)
|
|
147
147
|
{
|
148
148
|
enum
|
149
149
|
{
|
150
|
-
TOTAL_KEYWORDS =
|
150
|
+
TOTAL_KEYWORDS = 24,
|
151
151
|
MIN_WORD_LENGTH = 1,
|
152
152
|
MAX_WORD_LENGTH = 10,
|
153
153
|
MIN_HASH_VALUE = 1,
|
@@ -179,7 +179,8 @@ find_block_tag (str, len)
|
|
179
179
|
"script",
|
180
180
|
"h5",
|
181
181
|
"noscript",
|
182
|
-
"",
|
182
|
+
"",
|
183
|
+
"style",
|
183
184
|
"iframe",
|
184
185
|
"h4",
|
185
186
|
"ins",
|
@@ -264,8 +264,10 @@ smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
264
264
|
static size_t
|
265
265
|
smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
266
266
|
{
|
267
|
-
static const char *skip_tags[] = {
|
268
|
-
|
267
|
+
static const char *skip_tags[] = {
|
268
|
+
"pre", "code", "var", "samp", "kbd", "math", "script", "style"
|
269
|
+
};
|
270
|
+
static const size_t skip_tags_count = 8;
|
269
271
|
|
270
272
|
size_t tag, i = 0;
|
271
273
|
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -111,6 +111,7 @@ struct sd_markdown {
|
|
111
111
|
struct stack work_bufs[2];
|
112
112
|
unsigned int ext_flags;
|
113
113
|
size_t max_nesting;
|
114
|
+
int in_link_body;
|
114
115
|
};
|
115
116
|
|
116
117
|
/***************************
|
@@ -372,7 +373,6 @@ parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t siz
|
|
372
373
|
if (end >= size) break;
|
373
374
|
i = end;
|
374
375
|
|
375
|
-
/* calling the trigger */
|
376
376
|
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
|
377
377
|
if (!end) /* no action from the callback */
|
378
378
|
end = i + 1;
|
@@ -425,7 +425,6 @@ find_emph_char(uint8_t *data, size_t size, uint8_t c)
|
|
425
425
|
}
|
426
426
|
|
427
427
|
if (i >= size) return tmp_i;
|
428
|
-
i++;
|
429
428
|
}
|
430
429
|
/* skipping a link */
|
431
430
|
else if (data[i] == '[') {
|
@@ -682,7 +681,7 @@ char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of
|
|
682
681
|
static size_t
|
683
682
|
char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
|
684
683
|
{
|
685
|
-
static const char *escape_chars = "\\`*_{}[]()
|
684
|
+
static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~";
|
686
685
|
struct buf work = { 0, 0, 0, 0 };
|
687
686
|
|
688
687
|
if (size > 1) {
|
@@ -758,10 +757,10 @@ char_langle_tag(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
758
757
|
static size_t
|
759
758
|
char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
|
760
759
|
{
|
761
|
-
struct buf *link, *link_url;
|
760
|
+
struct buf *link, *link_url, *link_text;
|
762
761
|
size_t link_len, rewind;
|
763
762
|
|
764
|
-
if (!rndr->cb.link)
|
763
|
+
if (!rndr->cb.link || rndr->in_link_body)
|
765
764
|
return 0;
|
766
765
|
|
767
766
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
@@ -772,7 +771,14 @@ char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_
|
|
772
771
|
bufput(link_url, link->data, link->size);
|
773
772
|
|
774
773
|
ob->size -= rewind;
|
775
|
-
rndr->cb.
|
774
|
+
if (rndr->cb.normal_text) {
|
775
|
+
link_text = rndr_newbuf(rndr, BUFFER_SPAN);
|
776
|
+
rndr->cb.normal_text(link_text, link, rndr->opaque);
|
777
|
+
rndr->cb.link(ob, link_url, NULL, link_text, rndr->opaque);
|
778
|
+
rndr_popbuf(rndr, BUFFER_SPAN);
|
779
|
+
} else {
|
780
|
+
rndr->cb.link(ob, link_url, NULL, link, rndr->opaque);
|
781
|
+
}
|
776
782
|
rndr_popbuf(rndr, BUFFER_SPAN);
|
777
783
|
}
|
778
784
|
|
@@ -786,7 +792,7 @@ char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, siz
|
|
786
792
|
struct buf *link;
|
787
793
|
size_t link_len, rewind;
|
788
794
|
|
789
|
-
if (!rndr->cb.autolink)
|
795
|
+
if (!rndr->cb.autolink || rndr->in_link_body)
|
790
796
|
return 0;
|
791
797
|
|
792
798
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
@@ -806,7 +812,7 @@ char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_
|
|
806
812
|
struct buf *link;
|
807
813
|
size_t link_len, rewind;
|
808
814
|
|
809
|
-
if (!rndr->cb.autolink)
|
815
|
+
if (!rndr->cb.autolink || rndr->in_link_body)
|
810
816
|
return 0;
|
811
817
|
|
812
818
|
link = rndr_newbuf(rndr, BUFFER_SPAN);
|
@@ -832,6 +838,7 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
|
|
832
838
|
struct buf *u_link = 0;
|
833
839
|
size_t org_work_size = rndr->work_bufs[BUFFER_SPAN].size;
|
834
840
|
int text_has_nl = 0, ret = 0;
|
841
|
+
int in_title = 0, qtype = 0;
|
835
842
|
|
836
843
|
/* checking whether the correct renderer exists */
|
837
844
|
if ((is_img && !rndr->cb.image) || (!is_img && !rndr->cb.link))
|
@@ -888,12 +895,15 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
|
|
888
895
|
|
889
896
|
/* looking for title end if present */
|
890
897
|
if (data[i] == '\'' || data[i] == '"') {
|
898
|
+
qtype = data[i];
|
899
|
+
in_title = 1;
|
891
900
|
i++;
|
892
901
|
title_b = i;
|
893
902
|
|
894
903
|
while (i < size) {
|
895
904
|
if (data[i] == '\\') i += 2;
|
896
|
-
else if (data[i] ==
|
905
|
+
else if (data[i] == qtype) {in_title = 0; i++;}
|
906
|
+
else if ((data[i] == ')') && !in_title) break;
|
897
907
|
else i++;
|
898
908
|
}
|
899
909
|
|
@@ -1019,8 +1029,15 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
|
|
1019
1029
|
/* building content: img alt is escaped, link content is parsed */
|
1020
1030
|
if (txt_e > 1) {
|
1021
1031
|
content = rndr_newbuf(rndr, BUFFER_SPAN);
|
1022
|
-
if (is_img)
|
1023
|
-
|
1032
|
+
if (is_img) {
|
1033
|
+
bufput(content, data + 1, txt_e - 1);
|
1034
|
+
} else {
|
1035
|
+
/* disable autolinking when parsing inline the
|
1036
|
+
* content of a link */
|
1037
|
+
rndr->in_link_body = 1;
|
1038
|
+
parse_inline(content, rndr, data + 1, txt_e - 1);
|
1039
|
+
rndr->in_link_body = 0;
|
1040
|
+
}
|
1024
1041
|
}
|
1025
1042
|
|
1026
1043
|
if (link) {
|
@@ -1558,6 +1575,7 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s
|
|
1558
1575
|
struct buf *work = 0, *inter = 0;
|
1559
1576
|
size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
|
1560
1577
|
int in_empty = 0, has_inside_empty = 0;
|
1578
|
+
int has_next_uli, has_next_oli;
|
1561
1579
|
|
1562
1580
|
/* keeping track of the first indentation prefix */
|
1563
1581
|
while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
|
@@ -1604,10 +1622,20 @@ parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t s
|
|
1604
1622
|
|
1605
1623
|
pre = i;
|
1606
1624
|
|
1625
|
+
has_next_uli = prefix_uli(data + beg + i, end - beg - i);
|
1626
|
+
has_next_oli = prefix_oli(data + beg + i, end - beg - i);
|
1627
|
+
|
1628
|
+
/* checking for ul/ol switch */
|
1629
|
+
if (in_empty && (
|
1630
|
+
((*flags & MKD_LIST_ORDERED) && has_next_uli) ||
|
1631
|
+
(!(*flags & MKD_LIST_ORDERED) && has_next_oli)
|
1632
|
+
)){
|
1633
|
+
*flags |= MKD_LI_END;
|
1634
|
+
break; /* the following item must have same list type */
|
1635
|
+
}
|
1636
|
+
|
1607
1637
|
/* checking for a new item */
|
1608
|
-
if ((
|
1609
|
-
!is_hrule(data + beg + i, end - beg - i)) ||
|
1610
|
-
prefix_oli(data + beg + i, end - beg - i)) {
|
1638
|
+
if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) {
|
1611
1639
|
if (in_empty)
|
1612
1640
|
has_inside_empty = 1;
|
1613
1641
|
|
@@ -2325,6 +2353,7 @@ sd_markdown_new(
|
|
2325
2353
|
md->ext_flags = extensions;
|
2326
2354
|
md->opaque = opaque;
|
2327
2355
|
md->max_nesting = max_nesting;
|
2356
|
+
md->in_link_body = 0;
|
2328
2357
|
|
2329
2358
|
return md;
|
2330
2359
|
}
|
data/ext/redcarpet/redcarpet.h
CHANGED
data/ext/redcarpet/stack.h
CHANGED
data/lib/redcarpet.rb
CHANGED
@@ -53,3 +53,21 @@ module Redcarpet
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
# Compatibility class;
|
57
|
+
# Creates a instance of Redcarpet with the RedCloth
|
58
|
+
# API. This instance has no extensions enabled whatsoever,
|
59
|
+
# and no accessors to change this. 100% pure, standard
|
60
|
+
# Markdown.
|
61
|
+
class RedcarpetCompat
|
62
|
+
attr_accessor :text
|
63
|
+
|
64
|
+
def initialize(text, *_dummy)
|
65
|
+
@text = text
|
66
|
+
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_html(*_dummy)
|
70
|
+
@markdown.render(@text)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
data/redcarpet.gemspec
CHANGED
data/test/redcarpet_test.rb
CHANGED
@@ -91,7 +91,6 @@ class HTMLRenderTest < Test::Unit::TestCase
|
|
91
91
|
rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
|
92
92
|
html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
|
93
93
|
end
|
94
|
-
|
95
94
|
end
|
96
95
|
|
97
96
|
class MarkdownTest < Test::Unit::TestCase
|
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 15
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
|
11
|
-
- 5
|
12
|
-
version: 2.0.0b5
|
10
|
+
version: 2.0.0
|
13
11
|
platform: ruby
|
14
12
|
authors:
|
15
13
|
- "Natacha Port\xC3\xA9"
|
@@ -90,14 +88,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
89
|
none: false
|
92
90
|
requirements:
|
93
|
-
- - "
|
91
|
+
- - ">="
|
94
92
|
- !ruby/object:Gem::Version
|
95
|
-
hash:
|
93
|
+
hash: 3
|
96
94
|
segments:
|
97
|
-
-
|
98
|
-
|
99
|
-
- 1
|
100
|
-
version: 1.3.1
|
95
|
+
- 0
|
96
|
+
version: "0"
|
101
97
|
requirements: []
|
102
98
|
|
103
99
|
rubyforge_project:
|