greenmat 3.2.2.1 → 3.5.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +17 -4
  3. data/CHANGELOG.md +21 -0
  4. data/COPYING +17 -11
  5. data/Gemfile +2 -2
  6. data/README.md +19 -13
  7. data/bin/greenmat +4 -40
  8. data/ext/greenmat/autolink.c +29 -16
  9. data/ext/greenmat/buffer.c +24 -17
  10. data/ext/greenmat/buffer.h +18 -13
  11. data/ext/greenmat/gm_markdown.c +38 -14
  12. data/ext/greenmat/gm_render.c +60 -21
  13. data/ext/greenmat/greenmat.h +22 -0
  14. data/ext/greenmat/houdini.h +25 -0
  15. data/ext/greenmat/houdini_href_e.c +27 -11
  16. data/ext/greenmat/houdini_html_e.c +22 -1
  17. data/ext/greenmat/html.c +130 -48
  18. data/ext/greenmat/html.h +19 -14
  19. data/ext/greenmat/html_smartypants.c +47 -20
  20. data/ext/greenmat/markdown.c +42 -30
  21. data/ext/greenmat/markdown.h +17 -15
  22. data/ext/greenmat/stack.c +22 -0
  23. data/ext/greenmat/stack.h +22 -0
  24. data/greenmat.gemspec +4 -3
  25. data/lib/greenmat.rb +1 -1
  26. data/lib/greenmat/cli.rb +86 -0
  27. data/lib/greenmat/compat.rb +0 -5
  28. data/lib/greenmat/render_strip.rb +13 -1
  29. data/lib/greenmat/version.rb +1 -1
  30. data/spec/greenmat/markdown_spec.rb +123 -0
  31. data/test/custom_render_test.rb +41 -2
  32. data/test/greenmat_bin_test.rb +80 -0
  33. data/test/greenmat_compat_test.rb +6 -6
  34. data/test/html5_test.rb +60 -38
  35. data/test/html_render_test.rb +162 -128
  36. data/test/html_toc_render_test.rb +74 -11
  37. data/test/markdown_test.rb +261 -161
  38. data/test/safe_render_test.rb +5 -6
  39. data/test/smarty_html_test.rb +19 -13
  40. data/test/smarty_pants_test.rb +10 -0
  41. data/test/stripdown_render_test.rb +38 -9
  42. data/test/test_helper.rb +30 -9
  43. metadata +34 -19
  44. data/tasks/generate_xcode_project.rake +0 -5
data/ext/greenmat/stack.h CHANGED
@@ -1,3 +1,25 @@
1
+ /*
2
+ * Copyright (c) 2015, Vicent Marti
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
1
23
  #ifndef STACK_H__
2
24
  #define STACK_H__
3
25
 
data/greenmat.gemspec CHANGED
@@ -21,9 +21,10 @@ Gem::Specification.new do |s|
21
21
  s.executables = ["greenmat"]
22
22
  s.require_paths = ["lib"]
23
23
 
24
+ s.add_development_dependency "activesupport"
24
25
  s.add_development_dependency "nokogiri", "~> 1.6.0"
25
- s.add_development_dependency "rake-compiler", "~> 0.8.3"
26
+ s.add_development_dependency "rake", "~> 12.2.1"
27
+ s.add_development_dependency "rake-compiler", "~> 1.0.3"
26
28
  s.add_development_dependency "rspec", "~> 3.2"
27
- s.add_development_dependency "rubygems-xcodeproj_generator", '~> 0.1'
28
- s.add_development_dependency "test-unit", "~> 2.5.4"
29
+ s.add_development_dependency "test-unit", "~> 3.2.3"
29
30
  end
data/lib/greenmat.rb CHANGED
@@ -53,7 +53,7 @@ module Greenmat
53
53
  '>' => '>',
54
54
  '"' => '"',
55
55
  "'" => ''',
56
- "/" => '&#x2F',
56
+ "/" => '/',
57
57
  })
58
58
  end
59
59
  end
@@ -0,0 +1,86 @@
1
+ require 'greenmat'
2
+ require 'optparse'
3
+
4
+ module Greenmat
5
+ # This class aims at easing the creation of custom
6
+ # binary for your needs. For example, you can add new
7
+ # options or change the existing ones. The parsing
8
+ # is handled by Ruby's OptionParser. For instance:
9
+ #
10
+ # class Custom::CLI < Greenmat::CLI
11
+ # def self.options_parser
12
+ # super.tap do |opts|
13
+ # opts.on("--rainbow") do
14
+ # @@options[:rainbow] = true
15
+ # end
16
+ # end
17
+ # end
18
+ #
19
+ # def self.render_object
20
+ # @@options[:rainbow] ? RainbowRender : super
21
+ # end
22
+ # end
23
+ class CLI
24
+ def self.options_parser
25
+ @@options = {
26
+ render_extensions: {},
27
+ parse_extensions: {},
28
+ smarty_pants: false
29
+ }
30
+
31
+ OptionParser.new do |opts|
32
+ opts.banner = "Usage: greenmat [--parse <extension>...] " \
33
+ "[--render <extension>...] [--smarty] <file>..."
34
+
35
+ opts.on("--parse EXTENSION", "Enable a parsing extension") do |ext|
36
+ ext = ext.gsub('-', '_').to_sym
37
+ @@options[:parse_extensions][ext] = true
38
+ end
39
+
40
+ opts.on("--render EXTENSION", "Enable a rendering extension") do |ext|
41
+ ext = ext.gsub('-', '_').to_sym
42
+ @@options[:render_extensions][ext] = true
43
+ end
44
+
45
+ opts.on("--smarty", "Enable Smarty Pants") do
46
+ @@options[:smarty_pants] = true
47
+ end
48
+
49
+ opts.on_tail("-v", "--version", "Display the current version") do
50
+ STDOUT.puts "Greenmat #{Greenmat::VERSION}"
51
+ exit
52
+ end
53
+
54
+ opts.on_tail("-h", "--help", "Display this help message") do
55
+ puts opts
56
+ exit
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.process(args)
62
+ self.legacy_parse!(args)
63
+ self.options_parser.parse!(args)
64
+ STDOUT.write parser_object.render(ARGF.read)
65
+ end
66
+
67
+ def self.render_object
68
+ @@options[:smarty_pants] ? Render::SmartyHTML : Render::HTML
69
+ end
70
+
71
+ def self.parser_object
72
+ renderer = render_object.new(@@options[:render_extensions])
73
+ Greenmat::Markdown.new(renderer, @@options[:parse_extensions])
74
+ end
75
+
76
+ def self.legacy_parse!(args) # :nodoc:
77
+ # Workaround for backward compatibility as OptionParser
78
+ # doesn't support the --flag-OPTION syntax.
79
+ args.select {|a| a =~ /--(parse|render)-/ }.each do |arg|
80
+ args.delete(arg)
81
+ arg = arg.partition(/\b-/)
82
+ args.push(arg.first, arg.last)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,8 +1,3 @@
1
- require 'greenmat'
2
-
3
- # Deprecated: Please use the default API to parse Markdown
4
- # documents ; this layer will be removed in Greenmat 4.0.
5
- #
6
1
  # Creates an instance of Greenmat with the RedCloth API.
7
2
  class GreenmatCompat
8
3
  attr_accessor :text
@@ -13,7 +13,7 @@ module Greenmat
13
13
  :autolink, :codespan, :double_emphasis,
14
14
  :emphasis, :underline, :raw_html,
15
15
  :triple_emphasis, :strikethrough,
16
- :superscript,
16
+ :superscript, :highlight, :quote,
17
17
 
18
18
  # footnotes
19
19
  :footnotes, :footnote_def, :footnote_ref,
@@ -43,6 +43,18 @@ module Greenmat
43
43
  def header(text, header_level)
44
44
  text + "\n"
45
45
  end
46
+
47
+ def table(header, body)
48
+ "#{header}#{body}"
49
+ end
50
+
51
+ def table_row(content)
52
+ content + "\n"
53
+ end
54
+
55
+ def table_cell(content, alignment)
56
+ content + "\t"
57
+ end
46
58
  end
47
59
  end
48
60
  end
@@ -1,3 +1,3 @@
1
1
  module Greenmat
2
- VERSION = '3.2.2.1'
2
+ VERSION = '3.5.1.1'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'greenmat'
2
+ require "active_support/core_ext/string/strip"
2
3
 
3
4
  module Greenmat
4
5
  RSpec.describe Markdown do
@@ -61,5 +62,127 @@ module Greenmat
61
62
  end
62
63
  end
63
64
  end
65
+
66
+ context 'with fenced_code_blocks option' do
67
+ let(:options) { { fenced_code_blocks: true } }
68
+
69
+ context 'with language and filename syntax' do
70
+ let(:text) do
71
+ <<-EOS.strip_heredoc
72
+ ```ruby:example.rb
73
+ puts :foo
74
+ ```
75
+ EOS
76
+ end
77
+
78
+ it 'generates <code> tag with data-metadata attribute' do
79
+ expect(rendered_html).to eq <<-EOS.strip_heredoc
80
+ <pre><code data-metadata="ruby:example.rb">puts :foo
81
+ </code></pre>
82
+ EOS
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'with deeply nested list' do
88
+ let(:text) do
89
+ <<-EOS.strip_heredoc
90
+ * 1
91
+ * 2
92
+ * 3
93
+ * 4
94
+ * 5
95
+ * 6
96
+ * 7
97
+ * 8
98
+ * 9
99
+ * 10
100
+ * 11
101
+ EOS
102
+ end
103
+
104
+ it 'renders the list up to 10 nesting and then gives up' do
105
+ expect(rendered_html).to eq <<-EOS.strip_heredoc
106
+ <ul>
107
+ <li>1
108
+
109
+ <ul>
110
+ <li>2
111
+
112
+ <ul>
113
+ <li>3
114
+
115
+ <ul>
116
+ <li>4
117
+
118
+ <ul>
119
+ <li>5
120
+
121
+ <ul>
122
+ <li>6
123
+
124
+ <ul>
125
+ <li>7
126
+
127
+ <ul>
128
+ <li>8
129
+
130
+ <ul>
131
+ <li>9
132
+
133
+ <ul>
134
+ <li>10
135
+
136
+ <ul>
137
+ <li></li>
138
+ </ul></li>
139
+ </ul></li>
140
+ </ul></li>
141
+ </ul></li>
142
+ </ul></li>
143
+ </ul></li>
144
+ </ul></li>
145
+ </ul></li>
146
+ </ul></li>
147
+ </ul></li>
148
+ </ul>
149
+ EOS
150
+ end
151
+ end
152
+
153
+ context 'with a deeply nested structure that can exist in the wild' do
154
+ let(:text) do
155
+ <<-EOS.strip_heredoc
156
+ > > * 1
157
+ > > * 2
158
+ > > * 3
159
+ > > * [_**Qiita**_](https://qiita.com)
160
+ EOS
161
+ end
162
+
163
+ it 'renders it properly' do
164
+ expect(rendered_html).to eq <<-EOS.strip_heredoc
165
+ <blockquote>
166
+ <blockquote>
167
+ <ul>
168
+ <li>1
169
+
170
+ <ul>
171
+ <li>2
172
+
173
+ <ul>
174
+ <li>3
175
+
176
+ <ul>
177
+ <li><a href="https://qiita.com"><em><strong>Qiita</strong></em></a></li>
178
+ </ul></li>
179
+ </ul></li>
180
+ </ul></li>
181
+ </ul>
182
+ </blockquote>
183
+ </blockquote>
184
+ EOS
185
+ end
186
+ end
64
187
  end
65
188
  end
@@ -4,16 +4,48 @@ require 'test_helper'
4
4
  class CustomRenderTest < Greenmat::TestCase
5
5
  class SimpleRender < Greenmat::Render::HTML
6
6
  def emphasis(text)
7
- "<em class=\"cool\">#{text}</em>"
7
+ if @options[:no_intra_emphasis]
8
+ return %(<em class="no_intra_emphasis">#{text}</em>)
9
+ end
10
+
11
+ %(<em class="cool">#{text}</em>)
12
+ end
13
+
14
+ def header(text, level)
15
+ "My little poney" if @options[:with_toc_data]
8
16
  end
9
17
  end
10
18
 
11
19
  def test_simple_overload
12
20
  md = Greenmat::Markdown.new(SimpleRender)
13
- html_equal "<p>This is <em class=\"cool\">just</em> a test</p>\n",
21
+ assert_equal "<p>This is <em class=\"cool\">just</em> a test</p>\n",
14
22
  md.render("This is *just* a test")
15
23
  end
16
24
 
25
+ def test_renderer_options
26
+ parser = Greenmat::Markdown.new(SimpleRender.new(with_toc_data: true))
27
+ output = parser.render("# A title")
28
+
29
+ assert_match "My little poney", output
30
+ end
31
+
32
+ def test_markdown_options
33
+ parser = Greenmat::Markdown.new(SimpleRender, no_intra_emphasis: true)
34
+ output = parser.render("*foo*")
35
+
36
+ assert_match "no_intra_emphasis", output
37
+ end
38
+
39
+ def test_original_options_hash_is_not_mutated
40
+ options = { with_toc_data: true }
41
+ render = SimpleRender.new(options)
42
+ parser = Greenmat::Markdown.new(render, tables: true)
43
+
44
+ computed_options = render.instance_variable_get(:"@options")
45
+
46
+ refute_equal computed_options.object_id, options.object_id
47
+ end
48
+
17
49
  class NilPreprocessRenderer < Greenmat::Render::HTML
18
50
  def preprocess(fulldoc)
19
51
  nil
@@ -25,4 +57,11 @@ class CustomRenderTest < Greenmat::TestCase
25
57
  assert_equal(nil,md.render("Anything"))
26
58
  end
27
59
 
60
+ def test_base_render_without_quote_callback
61
+ # Regression test for https://github.com/vmg/greenmat/issues/569
62
+ render = Class.new(Greenmat::Render::Base)
63
+ parser = Greenmat::Markdown.new render.new, quote: true
64
+
65
+ assert_equal "", parser.render(%(a "quote"))
66
+ end
28
67
  end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+ require 'tempfile'
3
+
4
+ class GreenmatBinTest < Greenmat::TestCase
5
+ def setup
6
+ @fixture_file = Tempfile.new('bin')
7
+ @fixture_path = @fixture_file.path
8
+
9
+ @fixture_file.write "A ==simple== fixture file -- with " \
10
+ "a [link](https://github.com)."
11
+ @fixture_file.rewind
12
+ end
13
+
14
+ def teardown
15
+ @fixture_file.unlink
16
+ end
17
+
18
+ def test_vanilla_bin
19
+ run_bin(@fixture_path)
20
+
21
+ expected = "<p>A ==simple== fixture file -- with " \
22
+ "a <a href=\"https://github.com\">link</a>.</p>\n"
23
+
24
+ assert_equal expected, @output
25
+ end
26
+
27
+ def test_enabling_a_parse_option
28
+ run_bin("--parse", "highlight", @fixture_path)
29
+
30
+ assert_output "<mark>"
31
+ refute_output "=="
32
+ end
33
+
34
+ def test_enabling_a_render_option
35
+ run_bin("--render", "no-links", @fixture_path)
36
+
37
+ assert_output "[link]"
38
+ refute_output "</a>"
39
+ end
40
+
41
+ def test_enabling_smarty_pants
42
+ run_bin("--smarty", @fixture_path)
43
+
44
+ assert_output "&ndash"
45
+ refute_output "--"
46
+ end
47
+
48
+ def test_version_option
49
+ run_bin("--version")
50
+ assert_output "Greenmat #{Greenmat::VERSION}"
51
+ end
52
+
53
+ def test_legacy_option_parsing
54
+ run_bin("--parse-highlight", "--render-no-links", @fixture_path)
55
+
56
+ assert_output "<mark>"
57
+ refute_output "=="
58
+
59
+ assert_output "[link]"
60
+ refute_output "</a>"
61
+ end
62
+
63
+ private
64
+
65
+ def run_bin(*args)
66
+ bin_path = File.expand_path('../../bin/greenmat', __FILE__)
67
+ ruby = RbConfig.ruby
68
+ IO.popen("#{ruby} #{bin_path} #{args.join(" ")}") do |stream|
69
+ @output = stream.read
70
+ end
71
+ end
72
+
73
+ def assert_output(pattern)
74
+ assert_match pattern, @output
75
+ end
76
+
77
+ def refute_output(pattern)
78
+ refute_match Regexp.new(pattern), @output
79
+ end
80
+ end