redcarpet 2.3.0 → 3.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 +24 -18
- data/Rakefile +42 -3
- data/ext/redcarpet/autolink.c +1 -1
- data/ext/redcarpet/autolink.h +0 -2
- data/ext/redcarpet/houdini_html_e.c +5 -1
- data/ext/redcarpet/html.c +15 -0
- data/ext/redcarpet/markdown.c +19 -8
- data/ext/redcarpet/markdown.h +2 -2
- data/ext/redcarpet/rc_markdown.c +9 -6
- data/ext/redcarpet/rc_render.c +10 -6
- data/ext/redcarpet/redcarpet.h +1 -8
- data/lib/redcarpet.rb +1 -1
- data/redcarpet.gemspec +8 -8
- data/test/html_render_test.rb +47 -0
- data/test/markdown_test.rb +13 -20
- metadata +24 -23
data/README.markdown
CHANGED
@@ -11,7 +11,7 @@ case since version 2 -- it now has its own API, but retains the old name. Yes,
|
|
11
11
|
that does mean that Redcarpet 2 is not backwards-compatible with the 1.X
|
12
12
|
versions.
|
13
13
|
|
14
|
-
Redcarpet is
|
14
|
+
Redcarpet is based on the [Sundown](https://www.github.com/vmg/sundown)
|
15
15
|
library. You might want to find out more about Sundown to see what makes this
|
16
16
|
Ruby library so awesome.
|
17
17
|
|
@@ -29,10 +29,11 @@ You can totally install it as a Gem
|
|
29
29
|
|
30
30
|
Redcarpet is readily available as a Ruby gem. It will build some native
|
31
31
|
extensions, but the parser is standalone and requires no installed libraries.
|
32
|
+
Redcarpet requires at least Ruby 1.9.2 on your system.
|
32
33
|
|
33
34
|
$ [sudo] gem install redcarpet
|
34
35
|
|
35
|
-
The Redcarpet source
|
36
|
+
The Redcarpet source is available at GitHub:
|
36
37
|
|
37
38
|
$ git clone git://github.com/vmg/redcarpet.git
|
38
39
|
|
@@ -63,12 +64,12 @@ parser will identify. The following extensions are accepted:
|
|
63
64
|
* `:no_intra_emphasis`: do not parse emphasis inside of words.
|
64
65
|
Strings such as `foo_bar_baz` will not generate `<em>` tags.
|
65
66
|
|
66
|
-
* `:tables`: parse tables, PHP-Markdown style
|
67
|
+
* `:tables`: parse tables, PHP-Markdown style.
|
67
68
|
|
68
69
|
* `:fenced_code_blocks`: parse fenced code blocks, PHP-Markdown
|
69
70
|
style. Blocks delimited with 3 or more `~` or backtickswill be considered
|
70
71
|
as code, without the need to be indented. An optional language name may
|
71
|
-
be added at the end of the opening fence for the code block
|
72
|
+
be added at the end of the opening fence for the code block.
|
72
73
|
|
73
74
|
* `:autolink`: parse links even when they are not enclosed in `<>`
|
74
75
|
characters. Autolinks for the http, https and ftp protocols will be
|
@@ -83,9 +84,9 @@ with `fenced_code_blocks: true`.
|
|
83
84
|
|
84
85
|
* `:strikethrough`: parse strikethrough, PHP-Markdown style
|
85
86
|
Two `~` characters mark the start of a strikethrough,
|
86
|
-
e.g. `this is ~~good~~ bad
|
87
|
+
e.g. `this is ~~good~~ bad`.
|
87
88
|
|
88
|
-
* `:lax_spacing
|
89
|
+
* `:lax_spacing`: HTML blocks do not require to be surrounded by an
|
89
90
|
empty line as in the Markdown standard.
|
90
91
|
|
91
92
|
* `:space_after_headers`: A space is always required between the hash
|
@@ -97,6 +98,9 @@ would not be a valid header.
|
|
97
98
|
* `:underline`: parse underscored emphasis as underlines.
|
98
99
|
`This is _underlined_ but this is still *italic*`.
|
99
100
|
|
101
|
+
* `:highlight`: parse highlights.
|
102
|
+
`This is ==highlighted==`. It looks like this: `<mark>highlighted</mark>`
|
103
|
+
|
100
104
|
Example:
|
101
105
|
|
102
106
|
~~~~~ ruby
|
@@ -124,25 +128,25 @@ performance — several degrees of magnitude faster than other Ruby Markdown
|
|
124
128
|
solutions.
|
125
129
|
|
126
130
|
All the rendering flags that previously applied only to HTML output have
|
127
|
-
now been moved to the `Render::HTML` class, and may be enabled when
|
131
|
+
now been moved to the `Redcarpet::Render::HTML` class, and may be enabled when
|
128
132
|
instantiating the renderer:
|
129
133
|
|
130
134
|
~~~~~ ruby
|
131
|
-
Render::HTML.new(render_options = {})
|
135
|
+
Redcarpet::Render::HTML.new(render_options = {})
|
132
136
|
~~~~~
|
133
137
|
|
134
138
|
Initializes an HTML renderer. The following flags are available:
|
135
139
|
|
136
|
-
* `:filter_html`: do not allow any user-inputted HTML in the output
|
140
|
+
* `:filter_html`: do not allow any user-inputted HTML in the output.
|
137
141
|
|
138
|
-
* `:no_images`: do not generate any `<img>` tags
|
142
|
+
* `:no_images`: do not generate any `<img>` tags.
|
139
143
|
|
140
|
-
* `:no_links`: do not generate any `<a>` tags
|
144
|
+
* `:no_links`: do not generate any `<a>` tags.
|
141
145
|
|
142
|
-
* `:no_styles`: do not generate any `<style>` tags
|
146
|
+
* `:no_styles`: do not generate any `<style>` tags.
|
143
147
|
|
144
148
|
* `:safe_links_only`: only generate links for protocols which are considered
|
145
|
-
safe
|
149
|
+
safe.
|
146
150
|
|
147
151
|
* `:with_toc_data`: add HTML anchors to each header in the output HTML,
|
148
152
|
to allow linking to each section.
|
@@ -153,9 +157,9 @@ Markdown document had newlines (by default, Markdown ignores these newlines).
|
|
153
157
|
* `:xhtml`: output XHTML-conformant tags. This option is always enabled in the
|
154
158
|
`Render::XHTML` renderer.
|
155
159
|
|
156
|
-
* `:prettify`: add prettyprint classes to `<code>` tags for google-code-prettify
|
160
|
+
* `:prettify`: add prettyprint classes to `<code>` tags for google-code-prettify.
|
157
161
|
|
158
|
-
* `:link_attributes`: hash of extra attributes to add to links
|
162
|
+
* `:link_attributes`: hash of extra attributes to add to links.
|
159
163
|
|
160
164
|
Example:
|
161
165
|
|
@@ -190,18 +194,19 @@ end
|
|
190
194
|
markdown = Redcarpet::Markdown.new(HTMLwithPygments, :fenced_code_blocks => true)
|
191
195
|
~~~~~
|
192
196
|
|
193
|
-
But new renderers can also be created from scratch (see `lib/render_man.rb` for
|
197
|
+
But new renderers can also be created from scratch (see `lib/redcarpet/render_man.rb` for
|
194
198
|
an example implementation of a Manpage renderer)
|
195
199
|
|
196
200
|
~~~~~~ ruby
|
197
201
|
class ManPage < Redcarpet::Render::Base
|
198
|
-
|
202
|
+
# you get the drill -- keep going from here
|
199
203
|
end
|
200
204
|
~~~~~
|
201
205
|
|
202
206
|
The following instance methods may be implemented by the renderer:
|
203
207
|
|
204
208
|
### Block-level calls
|
209
|
+
|
205
210
|
If the return value of the method is `nil`, the block will be skipped.
|
206
211
|
If the method for a document element is not implemented, the block will
|
207
212
|
be skipped.
|
@@ -246,6 +251,7 @@ be copied verbatim:
|
|
246
251
|
* strikethrough(text)
|
247
252
|
* superscript(text)
|
248
253
|
* underline(text)
|
254
|
+
* highlight(text)
|
249
255
|
|
250
256
|
### Low level rendering
|
251
257
|
|
@@ -288,7 +294,7 @@ The SmartyPants parser can be found in `Redcarpet::Render::SmartyPants`. It has
|
|
288
294
|
been implemented as a module, so it can be used standalone or as a mixin.
|
289
295
|
|
290
296
|
When mixed with a Renderer class, it will override the `postprocess` method
|
291
|
-
to perform SmartyPants replacements once the rendering is complete
|
297
|
+
to perform SmartyPants replacements once the rendering is complete.
|
292
298
|
|
293
299
|
~~~~ ruby
|
294
300
|
# Mixin
|
data/Rakefile
CHANGED
@@ -12,7 +12,46 @@ Rake::ExtensionTask.new('redcarpet')
|
|
12
12
|
require 'bundler/gem_tasks'
|
13
13
|
|
14
14
|
# Testing
|
15
|
-
|
15
|
+
require 'rake/testtask'
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
Rake::TestTask.new('test:unit') do |t|
|
18
|
+
t.libs << 'lib'
|
19
|
+
t.libs << 'test'
|
20
|
+
t.pattern = 'test/*_test.rb'
|
21
|
+
t.verbose = true
|
22
|
+
t.warning = false
|
23
|
+
end
|
24
|
+
|
25
|
+
task 'test:unit' => :compile
|
26
|
+
|
27
|
+
desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
|
28
|
+
task 'test:conformance' => :compile do |t|
|
29
|
+
script = "#{pwd}/bin/redcarpet"
|
30
|
+
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
|
31
|
+
lib_dir = "#{pwd}/lib"
|
32
|
+
|
33
|
+
chdir("test/MarkdownTest_#{test_version}") do
|
34
|
+
sh "RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'Run version 1.0 conformance suite'
|
39
|
+
task 'test:conformance:1.0' => :compile do |t|
|
40
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0'
|
41
|
+
Rake::Task['test:conformance'].invoke
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Run 1.0.3 conformance suite'
|
45
|
+
task 'test:conformance:1.0.3' => :compile do |t|
|
46
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0.3'
|
47
|
+
Rake::Task['test:conformance'].invoke
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Run unit and conformance tests'
|
51
|
+
task :test => %w[test:unit test:conformance]
|
52
|
+
|
53
|
+
desc 'Run benchmarks'
|
54
|
+
task :benchmark => :compile do |t|
|
55
|
+
$:.unshift 'lib'
|
56
|
+
load 'test/benchmark.rb'
|
57
|
+
end
|
data/ext/redcarpet/autolink.c
CHANGED
@@ -141,7 +141,7 @@ check_domain(uint8_t *data, size_t size, int allow_short)
|
|
141
141
|
return 0;
|
142
142
|
|
143
143
|
for (i = 1; i < size - 1; ++i) {
|
144
|
-
if (data[i]
|
144
|
+
if (strchr(".:", data[i]) != NULL) np++;
|
145
145
|
else if (!isalnum(data[i]) && data[i] != '-') break;
|
146
146
|
}
|
147
147
|
|
data/ext/redcarpet/autolink.h
CHANGED
@@ -69,7 +69,11 @@ houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure
|
|
69
69
|
if (src[i] == '/' && !secure) {
|
70
70
|
bufputc(ob, '/');
|
71
71
|
} else {
|
72
|
-
|
72
|
+
/* The left and right tags (< and >) aren't escaped in comments */
|
73
|
+
if ((src[i] == '<' && src[i + 1] == '!') || (src[i] == '>' && src[i - 1] == '-'))
|
74
|
+
bufputc(ob, src[i]);
|
75
|
+
else
|
76
|
+
bufputs(ob, HTML_ESCAPES[esc]);
|
73
77
|
}
|
74
78
|
|
75
79
|
i++;
|
data/ext/redcarpet/html.c
CHANGED
@@ -231,6 +231,19 @@ rndr_underline(struct buf *ob, const struct buf *text, void *opaque)
|
|
231
231
|
return 1;
|
232
232
|
}
|
233
233
|
|
234
|
+
static int
|
235
|
+
rndr_highlight(struct buf *ob, const struct buf *text, void *opaque)
|
236
|
+
{
|
237
|
+
if (!text || !text->size)
|
238
|
+
return 0;
|
239
|
+
|
240
|
+
BUFPUTSL(ob, "<mark>");
|
241
|
+
bufput(ob, text->data, text->size);
|
242
|
+
BUFPUTSL(ob, "</mark>");
|
243
|
+
|
244
|
+
return 1;
|
245
|
+
}
|
246
|
+
|
234
247
|
static int
|
235
248
|
rndr_linebreak(struct buf *ob, void *opaque)
|
236
249
|
{
|
@@ -587,6 +600,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
|
|
587
600
|
rndr_double_emphasis,
|
588
601
|
rndr_emphasis,
|
589
602
|
rndr_underline,
|
603
|
+
rndr_highlight,
|
590
604
|
NULL,
|
591
605
|
NULL,
|
592
606
|
toc_link,
|
@@ -629,6 +643,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
|
|
629
643
|
rndr_double_emphasis,
|
630
644
|
rndr_emphasis,
|
631
645
|
rndr_underline,
|
646
|
+
rndr_highlight,
|
632
647
|
rndr_image,
|
633
648
|
rndr_linebreak,
|
634
649
|
rndr_link,
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -65,6 +65,7 @@ typedef size_t
|
|
65
65
|
|
66
66
|
static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
67
67
|
static size_t char_underline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
68
|
+
static size_t char_highlight(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
68
69
|
static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
69
70
|
static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
70
71
|
static size_t char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
@@ -395,7 +396,7 @@ find_emph_char(uint8_t *data, size_t size, uint8_t c)
|
|
395
396
|
size_t i = 1;
|
396
397
|
|
397
398
|
while (i < size) {
|
398
|
-
while (i < size && data[i] != c && data[i] != '
|
399
|
+
while (i < size && data[i] != c && data[i] != '[')
|
399
400
|
i++;
|
400
401
|
|
401
402
|
if (i == size)
|
@@ -539,6 +540,8 @@ parse_emph2(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
539
540
|
|
540
541
|
if (c == '~')
|
541
542
|
r = rndr->cb.strikethrough(ob, work, rndr->opaque);
|
543
|
+
else if (c == '=')
|
544
|
+
r = rndr->cb.highlight(ob, work, rndr->opaque);
|
542
545
|
else
|
543
546
|
r = rndr->cb.double_emphasis(ob, work, rndr->opaque);
|
544
547
|
|
@@ -600,14 +603,14 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of
|
|
600
603
|
size_t ret;
|
601
604
|
|
602
605
|
if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {
|
603
|
-
if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>')
|
606
|
+
if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>' && data[-1] != '(')
|
604
607
|
return 0;
|
605
608
|
}
|
606
609
|
|
607
610
|
if (size > 2 && data[1] != c) {
|
608
611
|
/* whitespace cannot follow an opening emphasis;
|
609
612
|
* strikethrough only takes two characters '~~' */
|
610
|
-
if (c == '~' || _isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
|
613
|
+
if (c == '~' || c == '=' || _isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)
|
611
614
|
return 0;
|
612
615
|
|
613
616
|
return ret + 1;
|
@@ -621,7 +624,7 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of
|
|
621
624
|
}
|
622
625
|
|
623
626
|
if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
|
624
|
-
if (c == '~' || _isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
|
627
|
+
if (c == '~' || c == '=' || _isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)
|
625
628
|
return 0;
|
626
629
|
|
627
630
|
return ret + 3;
|
@@ -898,10 +901,18 @@ char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset
|
|
898
901
|
link_b = i;
|
899
902
|
|
900
903
|
/* looking for link end: ' " ) */
|
904
|
+
/* Count the number of open parenthesis */
|
905
|
+
size_t nb_p = 0;
|
906
|
+
|
901
907
|
while (i < size) {
|
902
908
|
if (data[i] == '\\') i += 2;
|
903
|
-
else if (data[i] == '
|
904
|
-
|
909
|
+
else if (data[i] == '(' && i != 0) {
|
910
|
+
nb_p++; i++;
|
911
|
+
}
|
912
|
+
else if (data[i] == ')') {
|
913
|
+
if (nb_p == 0) break;
|
914
|
+
else nb_p--; i++;
|
915
|
+
} else if (i >= 1 && _isspace(data[i-1]) && (data[i] == '\'' || data[i] == '"')) break;
|
905
916
|
else i++;
|
906
917
|
}
|
907
918
|
|
@@ -2423,6 +2434,8 @@ sd_markdown_new(
|
|
2423
2434
|
md->active_char['_'] = MD_CHAR_EMPHASIS;
|
2424
2435
|
if (extensions & MKDEXT_STRIKETHROUGH)
|
2425
2436
|
md->active_char['~'] = MD_CHAR_EMPHASIS;
|
2437
|
+
if (extensions & MKDEXT_HIGHLIGHT)
|
2438
|
+
md->active_char['='] = MD_CHAR_EMPHASIS;
|
2426
2439
|
}
|
2427
2440
|
|
2428
2441
|
if (md->cb.codespan)
|
@@ -2555,5 +2568,3 @@ sd_version(int *ver_major, int *ver_minor, int *ver_revision)
|
|
2555
2568
|
*ver_minor = SUNDOWN_VER_MINOR;
|
2556
2569
|
*ver_revision = SUNDOWN_VER_REVISION;
|
2557
2570
|
}
|
2558
|
-
|
2559
|
-
/* vim: set filetype=c: */
|
data/ext/redcarpet/markdown.h
CHANGED
@@ -61,6 +61,7 @@ enum mkd_extensions {
|
|
61
61
|
MKDEXT_SUPERSCRIPT = (1 << 7),
|
62
62
|
MKDEXT_LAX_SPACING = (1 << 8),
|
63
63
|
MKDEXT_DISABLE_INDENTED_CODE = (1 << 9),
|
64
|
+
MKDEXT_HIGHLIGHT = (1 << 10)
|
64
65
|
};
|
65
66
|
|
66
67
|
/* sd_callbacks - functions for rendering parsed data */
|
@@ -85,6 +86,7 @@ struct sd_callbacks {
|
|
85
86
|
int (*double_emphasis)(struct buf *ob, const struct buf *text, void *opaque);
|
86
87
|
int (*emphasis)(struct buf *ob, const struct buf *text, void *opaque);
|
87
88
|
int (*underline)(struct buf *ob, const struct buf *text, void *opaque);
|
89
|
+
int (*highlight)(struct buf *ob, const struct buf *text, void *opaque);
|
88
90
|
int (*image)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque);
|
89
91
|
int (*linebreak)(struct buf *ob, void *opaque);
|
90
92
|
int (*link)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque);
|
@@ -137,5 +139,3 @@ sd_version(int *major, int *minor, int *revision);
|
|
137
139
|
#endif
|
138
140
|
|
139
141
|
#endif
|
140
|
-
|
141
|
-
/* vim: set filetype=c: */
|
data/ext/redcarpet/rc_markdown.c
CHANGED
@@ -50,6 +50,9 @@ static void rb_redcarpet_md_flags(VALUE hash, unsigned int *enabled_extensions_p
|
|
50
50
|
if (rb_hash_lookup(hash, CSTR2SYM("underline")) == Qtrue)
|
51
51
|
extensions |= MKDEXT_UNDERLINE;
|
52
52
|
|
53
|
+
if (rb_hash_lookup(hash, CSTR2SYM("highlight")) == Qtrue)
|
54
|
+
extensions |= MKDEXT_HIGHLIGHT;
|
55
|
+
|
53
56
|
if (rb_hash_lookup(hash, CSTR2SYM("lax_spacing")) == Qtrue)
|
54
57
|
extensions |= MKDEXT_LAX_SPACING;
|
55
58
|
|
@@ -110,8 +113,8 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
110
113
|
|
111
114
|
if (rb_respond_to(rb_rndr, rb_intern("preprocess")))
|
112
115
|
text = rb_funcall(rb_rndr, rb_intern("preprocess"), 1, text);
|
113
|
-
|
114
|
-
|
116
|
+
if (NIL_P(text))
|
117
|
+
return Qnil;
|
115
118
|
|
116
119
|
#ifdef HAVE_RUBY_ENCODING_H
|
117
120
|
{
|
@@ -132,7 +135,7 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
132
135
|
markdown);
|
133
136
|
|
134
137
|
/* build the Ruby string */
|
135
|
-
text =
|
138
|
+
text = rb_enc_str_new((const char*)output_buf->data, output_buf->size, rb_enc_get(text));
|
136
139
|
|
137
140
|
bufrelease(output_buf);
|
138
141
|
|
@@ -145,11 +148,11 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
145
148
|
__attribute__((visibility("default")))
|
146
149
|
void Init_redcarpet()
|
147
150
|
{
|
148
|
-
|
151
|
+
rb_mRedcarpet = rb_define_module("Redcarpet");
|
149
152
|
|
150
153
|
rb_cMarkdown = rb_define_class_under(rb_mRedcarpet, "Markdown", rb_cObject);
|
151
|
-
|
152
|
-
|
154
|
+
rb_define_singleton_method(rb_cMarkdown, "new", rb_redcarpet_md__new, -1);
|
155
|
+
rb_define_method(rb_cMarkdown, "render", rb_redcarpet_md_render, 1);
|
153
156
|
|
154
157
|
Init_redcarpet_rndr();
|
155
158
|
}
|
data/ext/redcarpet/rc_render.c
CHANGED
@@ -40,11 +40,7 @@ VALUE rb_cRenderHTML;
|
|
40
40
|
VALUE rb_cRenderHTML_TOC;
|
41
41
|
VALUE rb_mSmartyPants;
|
42
42
|
|
43
|
-
#
|
44
|
-
#define buf2str(t) ((t) ? redcarpet_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
|
45
|
-
#else
|
46
|
-
#define buf2str(t) ((t) ? redcarpet_str_new((const char*)(t)->data, (t)->size, NULL) : Qnil)
|
47
|
-
#endif
|
43
|
+
#define buf2str(t) ((t) ? rb_enc_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
|
48
44
|
|
49
45
|
static void
|
50
46
|
rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
|
@@ -171,6 +167,12 @@ rndr_underline(struct buf *ob, const struct buf *text, void *opaque)
|
|
171
167
|
SPAN_CALLBACK("underline", 1, buf2str(text));
|
172
168
|
}
|
173
169
|
|
170
|
+
static int
|
171
|
+
rndr_highlight(struct buf *ob, const struct buf *text, void *opaque)
|
172
|
+
{
|
173
|
+
SPAN_CALLBACK("highlight", 1, buf2str(text));
|
174
|
+
}
|
175
|
+
|
174
176
|
static int
|
175
177
|
rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque)
|
176
178
|
{
|
@@ -279,6 +281,7 @@ static struct sd_callbacks rb_redcarpet_callbacks = {
|
|
279
281
|
rndr_double_emphasis,
|
280
282
|
rndr_emphasis,
|
281
283
|
rndr_underline,
|
284
|
+
rndr_highlight,
|
282
285
|
rndr_image,
|
283
286
|
rndr_linebreak,
|
284
287
|
rndr_link,
|
@@ -312,6 +315,7 @@ static const char *rb_redcarpet_method_names[] = {
|
|
312
315
|
"double_emphasis",
|
313
316
|
"emphasis",
|
314
317
|
"underline",
|
318
|
+
"highlight",
|
315
319
|
"image",
|
316
320
|
"linebreak",
|
317
321
|
"link",
|
@@ -456,7 +460,7 @@ static VALUE rb_redcarpet_smartypants_render(VALUE self, VALUE text)
|
|
456
460
|
output_buf = bufnew(128);
|
457
461
|
|
458
462
|
sdhtml_smartypants(output_buf, (const uint8_t*)RSTRING_PTR(text), RSTRING_LEN(text));
|
459
|
-
result =
|
463
|
+
result = rb_enc_str_new((const char*)output_buf->data, output_buf->size, rb_enc_get(text));
|
460
464
|
|
461
465
|
bufrelease(output_buf);
|
462
466
|
return result;
|
data/ext/redcarpet/redcarpet.h
CHANGED
@@ -5,12 +5,7 @@
|
|
5
5
|
#include "ruby.h"
|
6
6
|
#include <stdio.h>
|
7
7
|
|
8
|
-
#
|
9
|
-
# include <ruby/encoding.h>
|
10
|
-
# define redcarpet_str_new(data, size, enc) rb_enc_str_new(data, size, enc)
|
11
|
-
#else
|
12
|
-
# define redcarpet_str_new(data, size, enc) rb_str_new(data, size)
|
13
|
-
#endif
|
8
|
+
#include <ruby/encoding.h>
|
14
9
|
|
15
10
|
#include "markdown.h"
|
16
11
|
#include "html.h"
|
@@ -24,9 +19,7 @@ struct redcarpet_renderopt {
|
|
24
19
|
VALUE link_attributes;
|
25
20
|
VALUE self;
|
26
21
|
VALUE base_class;
|
27
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
28
22
|
rb_encoding *active_enc;
|
29
|
-
#endif
|
30
23
|
};
|
31
24
|
|
32
25
|
struct rb_redcarpet_rndr {
|
data/lib/redcarpet.rb
CHANGED
data/redcarpet.gemspec
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'redcarpet'
|
4
|
-
s.version = '
|
4
|
+
s.version = '3.0.0'
|
5
5
|
s.summary = "Markdown that smells nice"
|
6
6
|
s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
|
7
|
-
s.date = '2013-
|
7
|
+
s.date = '2013-07-09'
|
8
8
|
s.email = 'vicent@github.com'
|
9
9
|
s.homepage = 'http://github.com/vmg/redcarpet'
|
10
10
|
s.authors = ["Natacha Porté", "Vicent Martí"]
|
11
|
+
s.license = 'MIT'
|
11
12
|
# = MANIFEST =
|
12
13
|
s.files = %w[
|
13
14
|
COPYING
|
@@ -39,7 +40,6 @@ Gem::Specification.new do |s|
|
|
39
40
|
lib/redcarpet/render_man.rb
|
40
41
|
lib/redcarpet/render_strip.rb
|
41
42
|
redcarpet.gemspec
|
42
|
-
sundown
|
43
43
|
test/test_helper.rb
|
44
44
|
test/custom_render_test.rb
|
45
45
|
test/html_render_test.rb
|
@@ -57,9 +57,9 @@ Gem::Specification.new do |s|
|
|
57
57
|
s.executables = ["redcarpet"]
|
58
58
|
s.require_paths = ["lib"]
|
59
59
|
|
60
|
-
s.add_development_dependency "nokogiri"
|
61
|
-
s.add_development_dependency "rake-compiler"
|
62
|
-
s.add_development_dependency "test-unit"
|
63
|
-
s.add_development_dependency "bluecloth"
|
64
|
-
s.add_development_dependency "kramdown"
|
60
|
+
s.add_development_dependency "nokogiri", "~> 1.6.0"
|
61
|
+
s.add_development_dependency "rake-compiler", "~> 0.8.3"
|
62
|
+
s.add_development_dependency "test-unit", "~> 2.5.4"
|
63
|
+
s.add_development_dependency "bluecloth", "~> 2.2.0"
|
64
|
+
s.add_development_dependency "kramdown", "~> 1.0.2"
|
65
65
|
end
|
data/test/html_render_test.rb
CHANGED
@@ -89,4 +89,51 @@ EOE
|
|
89
89
|
rd = render_with(@rndr[:escape_html], %([This'link"is](http://example.net/)))
|
90
90
|
assert_equal "<p><a href=\"http://example.net/\">This'link"is</a></p>\n", rd
|
91
91
|
end
|
92
|
+
|
93
|
+
def test_that_code_emphasis_work
|
94
|
+
markdown = <<-MD
|
95
|
+
This should be **`a bold codespan`**
|
96
|
+
However, this should be *`an emphasised codespan`*
|
97
|
+
|
98
|
+
* **`ABC`** or **`DEF`**
|
99
|
+
* Foo bar
|
100
|
+
MD
|
101
|
+
|
102
|
+
html = <<HTML
|
103
|
+
<p>This should be <strong><code>a bold codespan</code></strong>
|
104
|
+
However, this should be <em><code>an emphasised codespan</code></em></p>
|
105
|
+
|
106
|
+
<ul>
|
107
|
+
<li><strong><code>ABC</code></strong> or <strong><code>DEF</code></strong></li>
|
108
|
+
<li>Foo bar</li>
|
109
|
+
</ul>
|
110
|
+
HTML
|
111
|
+
|
112
|
+
output = render_with(Redcarpet::Render::HTML.new, markdown)
|
113
|
+
assert_equal html, output
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_that_parenthesis_are_handled_into_links
|
117
|
+
markdown = "Hey have a look at the [bash man page](man:bash(1))!"
|
118
|
+
html = "<p>Hey have a look at the <a href=\"man:bash(1)\">bash man page</a>!</p>\n"
|
119
|
+
output = render_with(Redcarpet::Render::HTML.new, markdown)
|
120
|
+
|
121
|
+
assert_equal html, output
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_autolinking_works_as_expected
|
125
|
+
markdown = "Example of uri ftp://user:pass@example.com/. Email foo@bar.com and link http://bar.com"
|
126
|
+
renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true)
|
127
|
+
output = renderer.render(markdown)
|
128
|
+
|
129
|
+
assert output.include? '<a href="ftp://user:pass@example.com/">ftp://user:pass@example.com/</a>'
|
130
|
+
assert output.include? 'mailto:foo@bar.com'
|
131
|
+
assert output.include? '<a href="http://bar.com">'
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_that_comments_arent_escaped
|
135
|
+
input = "<!-- This is a nice comment! -->"
|
136
|
+
output = render_with(@rndr[:escape_html], input)
|
137
|
+
assert output.include? input
|
138
|
+
end
|
92
139
|
end
|
data/test/markdown_test.rb
CHANGED
@@ -88,26 +88,6 @@ class MarkdownTest < Test::Unit::TestCase
|
|
88
88
|
html_equal "<p><a href=\"http://github.com/rtomayko/rdiscount\">http://github.com/rtomayko/rdiscount</a></p>\n", rd
|
89
89
|
end
|
90
90
|
|
91
|
-
if "".respond_to?(:encoding)
|
92
|
-
def test_should_return_string_in_same_encoding_as_input
|
93
|
-
input = "Yogācāra"
|
94
|
-
output = @markdown.render(input)
|
95
|
-
assert_equal input.encoding.name, output.encoding.name
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_should_return_string_in_same_encoding_not_in_utf8
|
99
|
-
input = "testing".encode('US-ASCII')
|
100
|
-
output = @markdown.render(input)
|
101
|
-
assert_equal input.encoding.name, output.encoding.name
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_should_accept_non_utf8_or_ascii
|
105
|
-
input = "testing \xAB\xCD".force_encoding('ASCII-8BIT')
|
106
|
-
output = @markdown.render(input)
|
107
|
-
assert_equal 'ASCII-8BIT', output.encoding.name
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
91
|
def test_that_tags_can_have_dashes_and_underscores
|
112
92
|
rd = @markdown.render("foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b>")
|
113
93
|
html_equal "<p>foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b></p>\n", rd
|
@@ -190,6 +170,15 @@ EOS
|
|
190
170
|
assert output.include? '<em>some</em>'
|
191
171
|
end
|
192
172
|
|
173
|
+
def test_highlight_flag_works
|
174
|
+
text = "this is ==highlighted=="
|
175
|
+
|
176
|
+
refute render_with({}, text).include? '<mark>highlighted</mark>'
|
177
|
+
|
178
|
+
output = render_with({:highlight => true}, text)
|
179
|
+
assert output.include? '<mark>highlighted</mark>'
|
180
|
+
end
|
181
|
+
|
193
182
|
def test_that_fenced_flag_works
|
194
183
|
text = <<fenced
|
195
184
|
This is a simple test
|
@@ -256,5 +245,9 @@ text
|
|
256
245
|
assert render_with({:no_intra_emphasis => true}, "this fails: hello_world_") !~ /<em>/
|
257
246
|
assert render_with({:no_intra_emphasis => true}, "this also fails: hello_world_#bye") !~ /<em>/
|
258
247
|
assert render_with({:no_intra_emphasis => true}, "this works: hello_my_world") !~ /<em>/
|
248
|
+
|
249
|
+
markdown = "This is (**bold**) and this_is_not_italic!"
|
250
|
+
html = "<p>This is (<strong>bold</strong>) and this_is_not_italic!</p>\n"
|
251
|
+
assert_equal html, render_with({:no_intra_emphasis => true}, markdown)
|
259
252
|
end
|
260
253
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,88 +10,88 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
|
-
- -
|
20
|
+
- - ~>
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 1.6.0
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
30
|
+
version: 1.6.0
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: rake-compiler
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
34
34
|
none: false
|
35
35
|
requirements:
|
36
|
-
- -
|
36
|
+
- - ~>
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
38
|
+
version: 0.8.3
|
39
39
|
type: :development
|
40
40
|
prerelease: false
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 0.8.3
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: test-unit
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.5.4
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
none: false
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
62
|
+
version: 2.5.4
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: bluecloth
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
66
66
|
none: false
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - ~>
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: 2.2.0
|
71
71
|
type: :development
|
72
72
|
prerelease: false
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
|
-
- -
|
76
|
+
- - ~>
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
78
|
+
version: 2.2.0
|
79
79
|
- !ruby/object:Gem::Dependency
|
80
80
|
name: kramdown
|
81
81
|
requirement: !ruby/object:Gem::Requirement
|
82
82
|
none: false
|
83
83
|
requirements:
|
84
|
-
- -
|
84
|
+
- - ~>
|
85
85
|
- !ruby/object:Gem::Version
|
86
|
-
version:
|
86
|
+
version: 1.0.2
|
87
87
|
type: :development
|
88
88
|
prerelease: false
|
89
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
90
|
none: false
|
91
91
|
requirements:
|
92
|
-
- -
|
92
|
+
- - ~>
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
94
|
+
version: 1.0.2
|
95
95
|
description: A fast, safe and extensible Markdown to (X)HTML parser
|
96
96
|
email: vicent@github.com
|
97
97
|
executables:
|
@@ -140,7 +140,8 @@ files:
|
|
140
140
|
- test/smarty_pants_test.rb
|
141
141
|
- test/stripdown_render_test.rb
|
142
142
|
homepage: http://github.com/vmg/redcarpet
|
143
|
-
licenses:
|
143
|
+
licenses:
|
144
|
+
- MIT
|
144
145
|
post_install_message:
|
145
146
|
rdoc_options: []
|
146
147
|
require_paths:
|