redcarpet 2.0.1 → 2.1.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 +1 -1
- data/bin/redcarpet +23 -2
- data/ext/redcarpet/markdown.c +7 -0
- data/ext/redcarpet/rc_markdown.c +11 -14
- data/ext/redcarpet/rc_render.c +6 -8
- data/ext/redcarpet/redcarpet.h +5 -2
- data/lib/redcarpet.rb +58 -7
- data/lib/redcarpet/render_strip.rb +33 -0
- data/redcarpet.gemspec +2 -1
- data/test/redcarpet_test.rb +48 -0
- metadata +5 -4
data/README.markdown
CHANGED
@@ -66,7 +66,7 @@ settings, and reused between parses.
|
|
66
66
|
:tables - parse tables, PHP-Markdown style
|
67
67
|
|
68
68
|
:fenced_code_blocks - parse fenced code blocks, PHP-Markdown
|
69
|
-
style
|
69
|
+
style. Blocks delimited with 3 or more `~` or backticks
|
70
70
|
will be considered as code, without the need to be
|
71
71
|
indented. An optional language name may be added at the
|
72
72
|
end of the opening fence for the code block
|
data/bin/redcarpet
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Usage: redcarpet [<file>...]
|
2
|
+
# Usage: redcarpet [--parse-<extension>...] [--render-<extension>] [<file>...]
|
3
3
|
# Convert one or more Markdown files to HTML and write to standard output. With
|
4
4
|
# no <file> or when <file> is '-', read Markdown source text from standard input.
|
5
|
+
# With <extension>s, perform additional Markdown processing before writing output.
|
5
6
|
if ARGV.include?('--help')
|
6
7
|
File.read(__FILE__).split("\n").grep(/^# /).each do |line|
|
7
8
|
puts line[2..-1]
|
@@ -9,5 +10,25 @@ if ARGV.include?('--help')
|
|
9
10
|
exit 0
|
10
11
|
end
|
11
12
|
|
13
|
+
root = File.expand_path('../../', __FILE__)
|
14
|
+
$:.unshift File.expand_path('lib', root)
|
15
|
+
|
12
16
|
require 'redcarpet'
|
13
|
-
|
17
|
+
|
18
|
+
render_extensions = {}
|
19
|
+
parse_extensions = {}
|
20
|
+
|
21
|
+
ARGV.delete_if do |arg|
|
22
|
+
if arg =~ /^--render-([\w-]+)$/
|
23
|
+
arg = $1.gsub('-', '_')
|
24
|
+
render_extensions[arg.to_sym] = true
|
25
|
+
elsif arg =~ /^--parse-([\w-]+)$/
|
26
|
+
arg = $1.gsub('-', '_')
|
27
|
+
parse_extensions[arg.to_sym] = true
|
28
|
+
else
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
render = Redcarpet::Render::HTML.new(render_extensions)
|
34
|
+
STDOUT.write(Redcarpet::Markdown.new(render, parse_extensions).render(ARGF.read))
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -2361,6 +2361,7 @@ void
|
|
2361
2361
|
sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, struct sd_markdown *md)
|
2362
2362
|
{
|
2363
2363
|
#define MARKDOWN_GROW(x) ((x) + ((x) >> 1))
|
2364
|
+
static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
|
2364
2365
|
|
2365
2366
|
struct buf *text;
|
2366
2367
|
size_t beg, end;
|
@@ -2377,6 +2378,12 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
|
|
2377
2378
|
|
2378
2379
|
/* first pass: looking for references, copying everything else */
|
2379
2380
|
beg = 0;
|
2381
|
+
|
2382
|
+
/* Skip a possible UTF-8 BOM, even though the Unicode standard
|
2383
|
+
* discourages having these in UTF-8 documents */
|
2384
|
+
if (doc_size >= 3 && memcmp(document, UTF8_BOM, 3) == 0)
|
2385
|
+
beg += 3;
|
2386
|
+
|
2380
2387
|
while (beg < doc_size) /* iterating over lines */
|
2381
2388
|
if (is_ref(document, beg, doc_size, &end, md->refs))
|
2382
2389
|
beg = end;
|
data/ext/redcarpet/rc_markdown.c
CHANGED
@@ -24,6 +24,8 @@ static void rb_redcarpet_md_flags(VALUE hash, unsigned int *enabled_extensions_p
|
|
24
24
|
{
|
25
25
|
unsigned int extensions = 0;
|
26
26
|
|
27
|
+
Check_Type(hash, T_HASH);
|
28
|
+
|
27
29
|
/**
|
28
30
|
* Markdown extensions -- all disabled by default
|
29
31
|
*/
|
@@ -89,18 +91,6 @@ static VALUE rb_redcarpet_md__new(int argc, VALUE *argv, VALUE klass)
|
|
89
91
|
return rb_markdown;
|
90
92
|
}
|
91
93
|
|
92
|
-
static void check_utf8_encoding(VALUE str)
|
93
|
-
{
|
94
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
95
|
-
rb_encoding *enc = rb_enc_get(str);
|
96
|
-
if (enc != rb_utf8_encoding() && enc != rb_usascii_encoding()) {
|
97
|
-
rb_raise(rb_eTypeError,
|
98
|
-
"Input must be UTF-8 or US-ASCII, %s given", rb_enc_name(enc));
|
99
|
-
}
|
100
|
-
#endif
|
101
|
-
}
|
102
|
-
|
103
|
-
|
104
94
|
static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
105
95
|
{
|
106
96
|
VALUE rb_rndr;
|
@@ -108,7 +98,6 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
108
98
|
struct sd_markdown *markdown;
|
109
99
|
|
110
100
|
Check_Type(text, T_STRING);
|
111
|
-
check_utf8_encoding(text);
|
112
101
|
|
113
102
|
rb_rndr = rb_iv_get(self, "@renderer");
|
114
103
|
Data_Get_Struct(self, struct sd_markdown, markdown);
|
@@ -116,6 +105,14 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
116
105
|
if (rb_respond_to(rb_rndr, rb_intern("preprocess")))
|
117
106
|
text = rb_funcall(rb_rndr, rb_intern("preprocess"), 1, text);
|
118
107
|
|
108
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
109
|
+
{
|
110
|
+
struct rb_redcarpet_rndr *renderer;
|
111
|
+
Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, renderer);
|
112
|
+
renderer->options.active_enc = rb_enc_get(text);
|
113
|
+
}
|
114
|
+
#endif
|
115
|
+
|
119
116
|
/* initialize buffers */
|
120
117
|
output_buf = bufnew(128);
|
121
118
|
|
@@ -127,7 +124,7 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
127
124
|
markdown);
|
128
125
|
|
129
126
|
/* build the Ruby string */
|
130
|
-
text = redcarpet_str_new(output_buf->data, output_buf->size);
|
127
|
+
text = redcarpet_str_new(output_buf->data, output_buf->size, rb_enc_get(text));
|
131
128
|
|
132
129
|
bufrelease(output_buf);
|
133
130
|
|
data/ext/redcarpet/rc_render.c
CHANGED
@@ -40,13 +40,11 @@ VALUE rb_cRenderHTML;
|
|
40
40
|
VALUE rb_cRenderHTML_TOC;
|
41
41
|
VALUE rb_mSmartyPants;
|
42
42
|
|
43
|
-
|
44
|
-
buf2str(
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
49
|
-
|
43
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
44
|
+
#define buf2str(t) ((t) ? redcarpet_str_new((t)->data, (t)->size, opt->active_enc) : Qnil)
|
45
|
+
#else
|
46
|
+
#define buf2str(t) ((t) ? redcarpet_str_new((t)->data, (t)->size, NULL) : Qnil)
|
47
|
+
#endif
|
50
48
|
|
51
49
|
static void
|
52
50
|
rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
|
@@ -413,7 +411,7 @@ static VALUE rb_redcarpet_smartypants_render(VALUE self, VALUE text)
|
|
413
411
|
output_buf = bufnew(128);
|
414
412
|
|
415
413
|
sdhtml_smartypants(output_buf, RSTRING_PTR(text), RSTRING_LEN(text));
|
416
|
-
result = redcarpet_str_new(output_buf->data, output_buf->size);
|
414
|
+
result = redcarpet_str_new(output_buf->data, output_buf->size, rb_enc_get(text));
|
417
415
|
|
418
416
|
bufrelease(output_buf);
|
419
417
|
return result;
|
data/ext/redcarpet/redcarpet.h
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
|
8
8
|
#ifdef HAVE_RUBY_ENCODING_H
|
9
9
|
# include <ruby/encoding.h>
|
10
|
-
# define redcarpet_str_new(data, size) rb_enc_str_new(data, size,
|
10
|
+
# define redcarpet_str_new(data, size, enc) rb_enc_str_new(data, size, enc)
|
11
11
|
#else
|
12
|
-
# define redcarpet_str_new(data, size) rb_str_new(data, size)
|
12
|
+
# define redcarpet_str_new(data, size, enc) rb_str_new(data, size)
|
13
13
|
#endif
|
14
14
|
|
15
15
|
#include "markdown.h"
|
@@ -23,6 +23,9 @@ struct redcarpet_renderopt {
|
|
23
23
|
struct html_renderopt html;
|
24
24
|
VALUE self;
|
25
25
|
VALUE base_class;
|
26
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
27
|
+
rb_encoding *active_enc;
|
28
|
+
#endif
|
26
29
|
};
|
27
30
|
|
28
31
|
struct rb_redcarpet_rndr {
|
data/lib/redcarpet.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'redcarpet.so'
|
2
2
|
|
3
3
|
module Redcarpet
|
4
|
-
VERSION = '2.0
|
4
|
+
VERSION = '2.1.0'
|
5
5
|
|
6
6
|
class Markdown
|
7
7
|
attr_reader :renderer
|
@@ -54,20 +54,71 @@ module Redcarpet
|
|
54
54
|
end
|
55
55
|
|
56
56
|
# Compatibility class;
|
57
|
-
# Creates
|
58
|
-
# API. This instance has no extensions enabled whatsoever,
|
59
|
-
# and no accessors to change this. 100% pure, standard
|
60
|
-
# Markdown.
|
57
|
+
# Creates an instance of Redcarpet with the RedCloth API.
|
61
58
|
class RedcarpetCompat
|
62
59
|
attr_accessor :text
|
63
60
|
|
64
|
-
def initialize(text, *
|
61
|
+
def initialize(text, *exts)
|
62
|
+
exts_hash, render_hash = *parse_extensions_and_renderer_options(exts)
|
65
63
|
@text = text
|
66
|
-
|
64
|
+
renderer = Redcarpet::Render::HTML.new(render_hash)
|
65
|
+
@markdown = Redcarpet::Markdown.new(renderer, exts_hash)
|
67
66
|
end
|
68
67
|
|
69
68
|
def to_html(*_dummy)
|
70
69
|
@markdown.render(@text)
|
71
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
EXTENSION_MAP = {
|
75
|
+
# old name => new name
|
76
|
+
:autolink => :autolink,
|
77
|
+
:fenced_code => :fenced_code_blocks,
|
78
|
+
:filter_html => :filter_html,
|
79
|
+
:hard_wrap => :hard_wrap,
|
80
|
+
:lax_htmlblock => :lax_html_blocks,
|
81
|
+
:no_image => :no_images,
|
82
|
+
:no_intraemphasis => :no_intra_emphasis,
|
83
|
+
:no_links => :no_links,
|
84
|
+
:filter_styles => :no_styles,
|
85
|
+
:safelink => :safe_links_only,
|
86
|
+
:space_header => :space_after_headers,
|
87
|
+
:strikethrough => :strikethrough,
|
88
|
+
:tables => :tables,
|
89
|
+
:with_toc_data => :generate_toc,
|
90
|
+
:xhtml => :xhtml,
|
91
|
+
# old names with no new mapping
|
92
|
+
:gh_blockcode => nil,
|
93
|
+
:no_tables => nil,
|
94
|
+
:smart => nil,
|
95
|
+
:strict => nil
|
96
|
+
}
|
97
|
+
|
98
|
+
RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles,
|
99
|
+
:safe_links_only, :with_toc_data, :hard_wrap, :xhtml]
|
100
|
+
|
101
|
+
def rename_extensions(exts)
|
102
|
+
exts.map do |old_name|
|
103
|
+
if new_name = EXTENSION_MAP[old_name]
|
104
|
+
new_name
|
105
|
+
else
|
106
|
+
old_name
|
107
|
+
end
|
108
|
+
end.compact
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns two hashes, the extensions and renderer options
|
112
|
+
# given the extension list
|
113
|
+
def parse_extensions_and_renderer_options(exts)
|
114
|
+
exts = rename_extensions(exts)
|
115
|
+
exts.partition {|ext| !RENDERER_OPTIONS.include?(ext) }.
|
116
|
+
map {|list| list_to_truthy_hash(list) }
|
117
|
+
end
|
118
|
+
|
119
|
+
# Turns a list of symbols into a hash of <tt>symbol => true</tt>.
|
120
|
+
def list_to_truthy_hash(list)
|
121
|
+
list.inject({}) {|h, k| h[k] = true; h }
|
122
|
+
end
|
72
123
|
end
|
73
124
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module Redcarpet
|
3
|
+
module Render
|
4
|
+
# Markdown-stripping renderer. Turns Markdown into plaintext
|
5
|
+
# Thanks to @toupeira (Markus Koller)
|
6
|
+
class StripDown < Base
|
7
|
+
# Methods where the first argument is the text content
|
8
|
+
[
|
9
|
+
# block-level calls
|
10
|
+
:block_code, :block_quote,
|
11
|
+
:block_html, :header, :list,
|
12
|
+
:list_item, :paragraph,
|
13
|
+
|
14
|
+
# span-level calls
|
15
|
+
:autolink, :codespan, :double_emphasis,
|
16
|
+
:emphasis, :raw_html, :triple_emphasis,
|
17
|
+
:strikethrough, :superscript,
|
18
|
+
|
19
|
+
# low level rendering
|
20
|
+
:entity, :normal_text
|
21
|
+
].each do |method|
|
22
|
+
define_method method do |*args|
|
23
|
+
args.first
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Other methods where the text content is in another argument
|
28
|
+
def link(link, title, content)
|
29
|
+
content
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/redcarpet.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'redcarpet'
|
4
|
-
s.version = '2.0
|
4
|
+
s.version = '2.1.0'
|
5
5
|
s.summary = "Markdown that smells nice"
|
6
6
|
s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
|
7
7
|
s.date = '2011-09-14'
|
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
|
|
36
36
|
lib/redcarpet.rb
|
37
37
|
lib/redcarpet/compat.rb
|
38
38
|
lib/redcarpet/render_man.rb
|
39
|
+
lib/redcarpet/render_strip.rb
|
39
40
|
redcarpet.gemspec
|
40
41
|
sundown
|
41
42
|
test/redcarpet_test.rb
|
data/test/redcarpet_test.rb
CHANGED
@@ -209,6 +209,18 @@ class MarkdownTest < Test::Unit::TestCase
|
|
209
209
|
output = @markdown.render(input)
|
210
210
|
assert_equal input.encoding.name, output.encoding.name
|
211
211
|
end
|
212
|
+
|
213
|
+
def test_should_return_string_in_same_encoding_not_in_utf8
|
214
|
+
input = "testing".encode('US-ASCII')
|
215
|
+
output = @markdown.render(input)
|
216
|
+
assert_equal input.encoding.name, output.encoding.name
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_should_accept_non_utf8_or_ascii
|
220
|
+
input = "testing \xAB\xCD".force_encoding('ASCII-8BIT')
|
221
|
+
output = @markdown.render(input)
|
222
|
+
assert_equal 'ASCII-8BIT', output.encoding.name
|
223
|
+
end
|
212
224
|
end
|
213
225
|
|
214
226
|
def test_that_tags_can_have_dashes_and_underscores
|
@@ -318,6 +330,42 @@ class CustomRenderTest < Test::Unit::TestCase
|
|
318
330
|
end
|
319
331
|
end
|
320
332
|
|
333
|
+
class RedcarpetCompatTest < Test::Unit::TestCase
|
334
|
+
def test_simple_compat_api
|
335
|
+
html = RedcarpetCompat.new("This is_just_a test").to_html
|
336
|
+
html_equal "<p>This is<em>just</em>a test</p>", html
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_compat_api_enables_extensions
|
340
|
+
html = RedcarpetCompat.new("This is_just_a test", :no_intra_emphasis).to_html
|
341
|
+
html_equal "<p>This is_just_a test</p>", html
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_compat_api_knows_fenced_code_extension
|
345
|
+
text = "```ruby\nx = 'foo'\n```"
|
346
|
+
html = RedcarpetCompat.new(text, :fenced_code).to_html
|
347
|
+
html_equal "<pre><code class=\"ruby\">x = 'foo'\n</code></pre>", html
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_compat_api_ignores_gh_blockcode_extension
|
351
|
+
text = "```ruby\nx = 'foo'\n```"
|
352
|
+
html = RedcarpetCompat.new(text, :fenced_code, :gh_blockcode).to_html
|
353
|
+
html_equal "<pre><code class=\"ruby\">x = 'foo'\n</code></pre>", html
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_compat_api_knows_no_intraemphasis_extension
|
357
|
+
html = RedcarpetCompat.new("This is_just_a test", :no_intraemphasis).to_html
|
358
|
+
html_equal "<p>This is_just_a test</p>", html
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_translate_outdated_extensions
|
362
|
+
# these extensions are no longer used
|
363
|
+
exts = [:gh_blockcode, :no_tables, :smart, :strict]
|
364
|
+
html = RedcarpetCompat.new('"TEST"', *exts).to_html
|
365
|
+
html_equal "<p>"TEST"</p>", html
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
321
369
|
# Disabled by default
|
322
370
|
# (these are the easy ones -- the evil ones are not disclosed)
|
323
371
|
class PathologicalInputsTest # < Test::Unit::TestCase
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Natacha Port\xC3\xA9"
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/redcarpet.rb
|
68
68
|
- lib/redcarpet/compat.rb
|
69
69
|
- lib/redcarpet/render_man.rb
|
70
|
+
- lib/redcarpet/render_strip.rb
|
70
71
|
- redcarpet.gemspec
|
71
72
|
- test/redcarpet_test.rb
|
72
73
|
homepage: http://github.com/tanoku/redcarpet
|
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
99
|
requirements: []
|
99
100
|
|
100
101
|
rubyforge_project:
|
101
|
-
rubygems_version: 1.8.
|
102
|
+
rubygems_version: 1.8.15
|
102
103
|
signing_key:
|
103
104
|
specification_version: 3
|
104
105
|
summary: Markdown that smells nice
|