minidown 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +4 -0
- data/bin/minidown +33 -0
- data/lib/minidown.rb +13 -0
- data/lib/minidown/document.rb +142 -0
- data/lib/minidown/element.rb +40 -0
- data/lib/minidown/elements.rb +15 -0
- data/lib/minidown/elements/block_element.rb +37 -0
- data/lib/minidown/elements/code_block_element.rb +44 -0
- data/lib/minidown/elements/dividing_line_element.rb +11 -0
- data/lib/minidown/elements/html_element.rb +22 -0
- data/lib/minidown/elements/indent_code_element.rb +23 -0
- data/lib/minidown/elements/line_element.rb +28 -0
- data/lib/minidown/elements/list_element.rb +36 -0
- data/lib/minidown/elements/list_group_element.rb +87 -0
- data/lib/minidown/elements/order_list_element.rb +20 -0
- data/lib/minidown/elements/paragraph_element.rb +56 -0
- data/lib/minidown/elements/raw_html_element.rb +11 -0
- data/lib/minidown/elements/table_element.rb +80 -0
- data/lib/minidown/elements/text_element.rb +198 -0
- data/lib/minidown/elements/unorder_list_element.rb +31 -0
- data/lib/minidown/html_helper.rb +18 -0
- data/lib/minidown/parser.rb +19 -0
- data/lib/minidown/utils.rb +28 -0
- data/lib/minidown/version.rb +3 -0
- data/minidown.gemspec +26 -0
- data/spec/blank_line_spec.rb +21 -0
- data/spec/code_block_spec.rb +182 -0
- data/spec/dividing_line_spec.rb +35 -0
- data/spec/h1_and_h2_spec.rb +55 -0
- data/spec/indent_block_spec.rb +17 -0
- data/spec/li_spec.rb +354 -0
- data/spec/minidown_spec.rb +12 -0
- data/spec/paragraph_spec.rb +17 -0
- data/spec/raw_html_spec.rb +43 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/start_with_gt_spec.rb +70 -0
- data/spec/start_with_shape_spec.rb +42 -0
- data/spec/table_spec.rb +63 -0
- data/spec/task_list_spec.rb +18 -0
- data/spec/text_element_spec.rb +317 -0
- metadata +175 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Minidown
|
2
|
+
class UnorderListElement < ListGroupElement
|
3
|
+
TaskRegexp = /\A\[([ x])\](.+)/
|
4
|
+
NestRegexp = /\A(\s*)[*\-+]\s+(.+)/
|
5
|
+
ListRegexp = Minidown::Utils::Regexp[:unorder_list]
|
6
|
+
|
7
|
+
def initialize doc, line, indent_level = 0
|
8
|
+
super doc, line
|
9
|
+
if content =~ TaskRegexp
|
10
|
+
@task_ul ||= true
|
11
|
+
list = ListElement.new(doc, $2)
|
12
|
+
list.task_list = true
|
13
|
+
list.checked = ($1 == 'x'.freeze)
|
14
|
+
else
|
15
|
+
list = ListElement.new(doc, content)
|
16
|
+
end
|
17
|
+
@children << list
|
18
|
+
@lists = @children.dup
|
19
|
+
@indent_level = indent_level
|
20
|
+
@put_back = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_html
|
24
|
+
attr = nil
|
25
|
+
attr = {class: 'task-list'.freeze} if @task_ul
|
26
|
+
build_tag 'ul'.freeze, attr do |content|
|
27
|
+
children.each { |child| content << child.to_html}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Minidown
|
2
|
+
module HtmlHelper
|
3
|
+
def build_tag name, attr = nil
|
4
|
+
content = ''
|
5
|
+
yield content if block_given?
|
6
|
+
if attr
|
7
|
+
attr = attr.map{|k, v| "#{k}=\"#{v}\""}.join ' '.freeze
|
8
|
+
"<#{name} #{attr}>#{content}</#{name}>"
|
9
|
+
else
|
10
|
+
"<#{name}>#{content}</#{name}>"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def br_tag
|
15
|
+
'<br>'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Minidown
|
2
|
+
class Parser
|
3
|
+
def initialize options = {}
|
4
|
+
@options = options.freeze
|
5
|
+
end
|
6
|
+
|
7
|
+
def render str
|
8
|
+
parse(str).to_html
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def parse str
|
13
|
+
lines = str.split Utils::Regexp[:lines]
|
14
|
+
doc = Document.new lines, @options
|
15
|
+
doc.parse
|
16
|
+
doc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Minidown
|
2
|
+
module Utils
|
3
|
+
Regexp = {
|
4
|
+
lines: /\n|\r\n/,
|
5
|
+
blank_line: /\A\s*\z/,
|
6
|
+
raw_html: /\A\s*(\<(?=[^\<\>]).+(?<=[^\<\>])\>)*\s*\z/,
|
7
|
+
h1_or_h2: /\A([=-]{3,})(.*)/,
|
8
|
+
start_with_shape: /\A(\#{1,6})\s*(.+?)\s*#*\z/,
|
9
|
+
start_with_quote: /\A\>\s*(.+)/,
|
10
|
+
unorder_list: /\A(\s*)[*\-+]\s+(.+)/,
|
11
|
+
order_list: /\A(\s*)\d+\.\s+(.+)/,
|
12
|
+
code_block: /\A\s*[`~]{3,}\s*(\S*)/,
|
13
|
+
table: /\A\|?([^\|]+(?:\|[^\|]*)*)\|?\s*\z/,
|
14
|
+
dividing_line: /\A(\s*[*-]\s*){3,}\z/,
|
15
|
+
indent_code: /\A\s{4}(.+)/,
|
16
|
+
pipe_symbol: /\|/
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def escape_html str
|
21
|
+
sanitized_str = str.dup
|
22
|
+
sanitized_str.gsub! "<".freeze, "<".freeze
|
23
|
+
sanitized_str.gsub! ">".freeze, ">".freeze
|
24
|
+
sanitized_str
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/minidown.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'minidown/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "minidown"
|
8
|
+
spec.version = Minidown::VERSION
|
9
|
+
spec.authors = ["jjy"]
|
10
|
+
spec.email = ["jjyruby@gmail.com"]
|
11
|
+
spec.description = %q{Minidown is a lightweight & fast markdown parser, with complete GFM support.}
|
12
|
+
spec.summary = %q{Minidown is a lightweight & fast markdown parser, with complete GFM support.}
|
13
|
+
spec.homepage = "https://github.com/jjyr/minidown"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "pry-nav"
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Minidown do
|
4
|
+
describe 'blank line' do
|
5
|
+
it 'should parse as nothing' do
|
6
|
+
['', "\n", "\n\n", "\n\n\n\n"].each do |str|
|
7
|
+
Minidown.render(str).should == ''
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should be ignore when blank is the first line' do
|
12
|
+
str = "\na"
|
13
|
+
Minidown.render(str).should == "<p>a</p>"
|
14
|
+
str = "\n\n h"
|
15
|
+
Minidown.render(str).should == "<p> h</p>"
|
16
|
+
["\n \n", "\n \n\n\n"].each do |str|
|
17
|
+
Minidown.render(str).should == "#{str.split(Minidown::Utils::Regexp[:lines]).last}".strip
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Minidown do
|
4
|
+
describe 'code_block' do
|
5
|
+
it 'should parse correct' do
|
6
|
+
str =<<HERE
|
7
|
+
```
|
8
|
+
should in code block
|
9
|
+
|
10
|
+
in block
|
11
|
+
```
|
12
|
+
HERE
|
13
|
+
Minidown.render(str).should == "<pre><code>should in code block\n\nin block</code></pre>"
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should allow tildes as well as backquotes' do
|
17
|
+
str =<<HERE
|
18
|
+
~~~
|
19
|
+
should in code block
|
20
|
+
|
21
|
+
in block
|
22
|
+
~~~
|
23
|
+
HERE
|
24
|
+
Minidown.render(str).should == "<pre><code>should in code block\n\nin block</code></pre>"
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should allow arbitrary number of `' do
|
28
|
+
str =<<HERE
|
29
|
+
````````````
|
30
|
+
should in code block
|
31
|
+
|
32
|
+
in block
|
33
|
+
````````````
|
34
|
+
HERE
|
35
|
+
Minidown.render(str).should == "<pre><code>should in code block\n\nin block</code></pre>"
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should allow arbitrary number of tildes' do
|
39
|
+
str =<<HERE
|
40
|
+
~~~~~~~~~~~
|
41
|
+
should in code block
|
42
|
+
|
43
|
+
in block
|
44
|
+
~~~~~~~~~~~
|
45
|
+
HERE
|
46
|
+
Minidown.render(str).should == "<pre><code>should in code block\n\nin block</code></pre>"
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
it 'should ignore space' do
|
51
|
+
str =<<HERE
|
52
|
+
```
|
53
|
+
should in code block
|
54
|
+
in block
|
55
|
+
```
|
56
|
+
HERE
|
57
|
+
Minidown.render(str).should == "<pre><code>should in code block\nin block</code></pre>"
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have lang attribute' do
|
61
|
+
str =<<HERE
|
62
|
+
``` ruby
|
63
|
+
should in code block
|
64
|
+
|
65
|
+
in block
|
66
|
+
```
|
67
|
+
HERE
|
68
|
+
Minidown.render(str).should == "<pre><code class=\"ruby\">should in code block\n\nin block</code></pre>"
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should have lang attribute with tildes' do
|
72
|
+
str =<<HERE
|
73
|
+
~~~ ruby
|
74
|
+
should in code block
|
75
|
+
|
76
|
+
in block
|
77
|
+
~~~
|
78
|
+
HERE
|
79
|
+
Minidown.render(str).should == "<pre><code class=\"ruby\">should in code block\n\nin block</code></pre>"
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should allow escape' do
|
83
|
+
str =<<HERE
|
84
|
+
\\```
|
85
|
+
should in code block
|
86
|
+
|
87
|
+
in block
|
88
|
+
\\```
|
89
|
+
HERE
|
90
|
+
Minidown.render(str).should == "<p>```<br>should in code block</p><p>in block<br>```</p>"
|
91
|
+
str =<<HERE
|
92
|
+
\\~~~
|
93
|
+
should in code block
|
94
|
+
|
95
|
+
in block
|
96
|
+
\\~~~
|
97
|
+
HERE
|
98
|
+
Minidown.render(str).should == "<p>~~~<br>should in code block</p><p>in block<br>~~~</p>"
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should not escape content' do
|
102
|
+
str =<<HERE
|
103
|
+
```
|
104
|
+
\\+
|
105
|
+
\\.
|
106
|
+
\\-
|
107
|
+
\\*
|
108
|
+
<>
|
109
|
+
```
|
110
|
+
HERE
|
111
|
+
Minidown.render(str).should == "<pre><code>\\+\n\\.\n\\-\n\\*\n<></code></pre>"
|
112
|
+
str =<<HERE
|
113
|
+
~~~
|
114
|
+
\\+
|
115
|
+
\\.
|
116
|
+
\\-
|
117
|
+
\\*
|
118
|
+
<>
|
119
|
+
~~~
|
120
|
+
HERE
|
121
|
+
Minidown.render(str).should == "<pre><code>\\+\n\\.\n\\-\n\\*\n<></code></pre>"
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should escape html tag' do
|
125
|
+
str ='```
|
126
|
+
<a>hello</a>
|
127
|
+
```'
|
128
|
+
Minidown.render(str).should == "<pre><code><a>hello</a></code></pre>"
|
129
|
+
str ='~~~
|
130
|
+
<a>hello</a>
|
131
|
+
~~~'
|
132
|
+
Minidown.render(str).should == "<pre><code><a>hello</a></code></pre>"
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should not auto convert' do
|
136
|
+
str = '```
|
137
|
+
jjyruby@gmail.com
|
138
|
+
```'
|
139
|
+
Minidown.render(str).should == '<pre><code>jjyruby@gmail.com</code></pre>'
|
140
|
+
str = '~~~
|
141
|
+
jjyruby@gmail.com
|
142
|
+
~~~'
|
143
|
+
Minidown.render(str).should == '<pre><code>jjyruby@gmail.com</code></pre>'
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "work with code block handler" do
|
147
|
+
it "work with handler" do
|
148
|
+
str = '``` ruby
|
149
|
+
puts "We love ruby!"
|
150
|
+
```'
|
151
|
+
handler = ->(lang, content){"`#{content}` is write in #{lang}"}
|
152
|
+
Minidown.render(str, code_block_handler: handler).should == '`puts "We love ruby!"` is write in ruby'
|
153
|
+
end
|
154
|
+
|
155
|
+
it "lang should return empty if not specific language" do
|
156
|
+
str = '```
|
157
|
+
not specific language
|
158
|
+
```'
|
159
|
+
handler = ->(lang, content){ "#{content}, so lang is #{lang.inspect}" }
|
160
|
+
Minidown.render(str, code_block_handler: handler).should == 'not specific language, so lang is nil'
|
161
|
+
end
|
162
|
+
|
163
|
+
it "handler should pass raw content" do
|
164
|
+
str = '```
|
165
|
+
<script>
|
166
|
+
```'
|
167
|
+
handler = ->(lang, content){ content.gsub("<", "{").gsub(">", "}") }
|
168
|
+
Minidown.render(str, code_block_handler: handler).should == '{script}'
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should not escape <>" do
|
172
|
+
test_cases = %w{<script> <> < >}
|
173
|
+
handler = ->(lang, content){ content }
|
174
|
+
parser = Minidown::Parser.new(code_block_handler: handler)
|
175
|
+
test_cases.each do |case_s|
|
176
|
+
str = "```\n#{case_s}\n```"
|
177
|
+
parser.render(str).should == case_s
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Minidown do
|
4
|
+
describe 'dividing line' do
|
5
|
+
it 'parsed correct' do
|
6
|
+
str = '***'
|
7
|
+
Minidown.render(str).should == '<hr>'
|
8
|
+
str = '---'
|
9
|
+
Minidown.render(str).should == '<hr>'
|
10
|
+
str = ' *** '
|
11
|
+
Minidown.render(str).should == '<hr>'
|
12
|
+
str = ' * * * '
|
13
|
+
Minidown.render(str).should == '<hr>'
|
14
|
+
str = ' -- - '
|
15
|
+
Minidown.render(str).should == '<hr>'
|
16
|
+
str = '----'
|
17
|
+
Minidown.render(str).should == '<hr>'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should not parse if any other character' do
|
21
|
+
str = 'f---'
|
22
|
+
Minidown.render(str).should == '<p>f---</p>'
|
23
|
+
|
24
|
+
str = '* * *z'
|
25
|
+
Minidown.render(str).should == '<ul><li><em> </em>z</li></ul>'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should allow escape' do
|
29
|
+
str = "\\----"
|
30
|
+
Minidown.render(str).should == '<p>----</p>'
|
31
|
+
str = "\\* * *"
|
32
|
+
Minidown.render(str).should == '<p>* <em> </em></p>'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Minidown do
|
4
|
+
describe '======== or -------' do
|
5
|
+
it 'should parse as text' do
|
6
|
+
%w{===== =====hello ------nihao}.each do |str|
|
7
|
+
Minidown.render(str).should == "<p>#{str}</p>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should parse as h1' do
|
12
|
+
%w{======= ==== === = ==}.each do |s|
|
13
|
+
str =<<HERE
|
14
|
+
h1
|
15
|
+
#{s}
|
16
|
+
HERE
|
17
|
+
if s.size < 3
|
18
|
+
Minidown.render(str).should == "<p>h1<br>#{s}</p>"
|
19
|
+
else
|
20
|
+
Minidown.render(str).should == "<h1>h1</h1>"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should parse as h2' do
|
26
|
+
%w{------- ---- --- - --}.each do |s|
|
27
|
+
str =<<HERE
|
28
|
+
h2
|
29
|
+
#{s}
|
30
|
+
HERE
|
31
|
+
if s.size < 3
|
32
|
+
Minidown.render(str).should == "<p>h2<br>#{s}</p>"
|
33
|
+
else
|
34
|
+
Minidown.render(str).should == "<h2>h2</h2>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should parse newtext' do
|
40
|
+
%w{------ =======}.each do |s|
|
41
|
+
str =<<HERE
|
42
|
+
title
|
43
|
+
#{s}should show text
|
44
|
+
HERE
|
45
|
+
tag = (s[0] == '-' ? 'h2' : 'h1')
|
46
|
+
Minidown.render(str).should == "<#{tag}>title</#{tag}><p>should show text</p>"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should not parse as h2 if preline is h tag' do
|
51
|
+
str = "#### [ruby](http://ruby-lang.org/)\n---"
|
52
|
+
Minidown.render(str).should == "<h4><a href=\"http://ruby-lang.org/\">ruby</a></h4><hr>"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Minidown do
|
4
|
+
describe 'indent should parse as code block' do
|
5
|
+
it 'should parse correct' do
|
6
|
+
str =<<HERE
|
7
|
+
Here is a Python code example
|
8
|
+
without syntax highlighting:
|
9
|
+
|
10
|
+
def foo:
|
11
|
+
if not bar:
|
12
|
+
return true
|
13
|
+
HERE
|
14
|
+
Minidown.render(str).should == "<p>Here is a Python code example<br>without syntax highlighting:</p><pre><code>def foo:\n if not bar:\n return true</code></pre>"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|