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.

@@ -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 .Blocks delimited with 3 or more `~` or backticks
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
@@ -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
- STDOUT.write(Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(ARGF.read))
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))
@@ -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;
@@ -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
 
@@ -40,13 +40,11 @@ VALUE rb_cRenderHTML;
40
40
  VALUE rb_cRenderHTML_TOC;
41
41
  VALUE rb_mSmartyPants;
42
42
 
43
- static inline VALUE
44
- buf2str(const struct buf *text)
45
- {
46
- if (!text || !text->size) return Qnil;
47
- return redcarpet_str_new(text->data, text->size);
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;
@@ -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, rb_utf8_encoding())
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 {
@@ -1,7 +1,7 @@
1
1
  require 'redcarpet.so'
2
2
 
3
3
  module Redcarpet
4
- VERSION = '2.0.1'
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 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.
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, *_dummy)
61
+ def initialize(text, *exts)
62
+ exts_hash, render_hash = *parse_extensions_and_renderer_options(exts)
65
63
  @text = text
66
- @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
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
@@ -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.1'
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
@@ -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>&quot;TEST&quot;</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: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 0
9
8
  - 1
10
- version: 2.0.1
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.6
102
+ rubygems_version: 1.8.15
102
103
  signing_key:
103
104
  specification_version: 3
104
105
  summary: Markdown that smells nice