kramdown 0.2.0 → 0.3.0
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.
Potentially problematic release.
This version of kramdown might be problematic. Click here for more details.
- data/ChangeLog +267 -0
- data/VERSION +1 -1
- data/benchmark/benchmark.rb +2 -1
- data/benchmark/generate_data.rb +110 -0
- data/benchmark/historic-jruby-1.4.0.dat +7 -0
- data/benchmark/historic-ruby-1.8.6.dat +7 -0
- data/benchmark/historic-ruby-1.8.7.dat +7 -0
- data/benchmark/historic-ruby-1.9.1p243.dat +7 -0
- data/benchmark/historic-ruby-1.9.2dev.dat +7 -0
- data/benchmark/static-jruby-1.4.0.dat +7 -0
- data/benchmark/static-ruby-1.8.6.dat +7 -0
- data/benchmark/static-ruby-1.8.7.dat +7 -0
- data/benchmark/static-ruby-1.9.1p243.dat +7 -0
- data/benchmark/static-ruby-1.9.2dev.dat +7 -0
- data/benchmark/testing.sh +1 -1
- data/doc/index.page +5 -5
- data/doc/installation.page +3 -3
- data/doc/quickref.page +3 -3
- data/doc/syntax.page +133 -101
- data/doc/tests.page +9 -1
- data/lib/kramdown/compatibility.rb +34 -0
- data/lib/kramdown/converter.rb +26 -8
- data/lib/kramdown/document.rb +2 -1
- data/lib/kramdown/parser.rb +1 -1192
- data/lib/kramdown/parser/kramdown.rb +272 -0
- data/lib/kramdown/parser/kramdown/attribute_list.rb +102 -0
- data/lib/kramdown/parser/kramdown/autolink.rb +42 -0
- data/lib/kramdown/parser/kramdown/blank_line.rb +43 -0
- data/lib/kramdown/parser/kramdown/blockquote.rb +42 -0
- data/lib/kramdown/parser/kramdown/codeblock.rb +62 -0
- data/lib/kramdown/parser/kramdown/codespan.rb +57 -0
- data/lib/kramdown/parser/kramdown/emphasis.rb +69 -0
- data/lib/kramdown/parser/kramdown/eob.rb +39 -0
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +38 -0
- data/lib/kramdown/parser/kramdown/extension.rb +65 -0
- data/lib/kramdown/parser/kramdown/footnote.rb +72 -0
- data/lib/kramdown/parser/kramdown/header.rb +81 -0
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +39 -0
- data/lib/kramdown/parser/kramdown/html.rb +253 -0
- data/lib/kramdown/{deprecated.rb → parser/kramdown/html_entity.rb} +10 -12
- data/lib/kramdown/parser/kramdown/line_break.rb +38 -0
- data/lib/kramdown/parser/kramdown/link.rb +153 -0
- data/lib/kramdown/parser/kramdown/list.rb +225 -0
- data/lib/kramdown/parser/kramdown/paragraph.rb +44 -0
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +48 -0
- data/lib/kramdown/version.rb +1 -1
- data/test/testcases/block/09_html/comment.html +1 -0
- data/test/testcases/block/09_html/comment.text +1 -1
- data/test/testcases/block/09_html/content_model/tables.text +2 -2
- data/test/testcases/block/09_html/not_parsed.html +10 -0
- data/test/testcases/block/09_html/not_parsed.text +9 -0
- data/test/testcases/block/09_html/parse_as_raw.html +4 -0
- data/test/testcases/block/09_html/parse_as_raw.text +2 -0
- data/test/testcases/block/09_html/parse_block_html.html +4 -0
- data/test/testcases/block/09_html/parse_block_html.text +3 -0
- data/test/testcases/block/09_html/processing_instruction.html +1 -0
- data/test/testcases/block/09_html/processing_instruction.text +1 -1
- data/test/testcases/block/09_html/simple.html +8 -15
- data/test/testcases/block/09_html/simple.text +2 -12
- data/test/testcases/span/02_emphasis/normal.html +8 -4
- data/test/testcases/span/02_emphasis/normal.text +6 -2
- data/test/testcases/span/05_html/markdown_attr.html +2 -1
- data/test/testcases/span/05_html/markdown_attr.text +2 -1
- data/test/testcases/span/05_html/normal.html +6 -2
- data/test/testcases/span/05_html/normal.text +4 -0
- metadata +35 -4
- data/lib/kramdown/parser/registry.rb +0 -62
@@ -0,0 +1,225 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'kramdown/parser/kramdown/blank_line'
|
24
|
+
require 'kramdown/parser/kramdown/eob'
|
25
|
+
require 'kramdown/parser/kramdown/horizontal_rule'
|
26
|
+
|
27
|
+
module Kramdown
|
28
|
+
module Parser
|
29
|
+
class Kramdown
|
30
|
+
|
31
|
+
# Used for parsing the first line of a list item or a definition, i.e. the line with list item
|
32
|
+
# marker or the definition marker.
|
33
|
+
def parse_first_list_line(indentation, content)
|
34
|
+
if content =~ /^\s*\n/
|
35
|
+
indentation = 4
|
36
|
+
else
|
37
|
+
while content =~ /^ *\t/
|
38
|
+
temp = content.scan(/^ */).first.length + indentation
|
39
|
+
content.sub!(/^( *)(\t+)/) {$1 + " "*(4 - (temp % 4)) + " "*($2.length - 1)*4}
|
40
|
+
end
|
41
|
+
indentation += content.scan(/^ */).first.length
|
42
|
+
end
|
43
|
+
content.sub!(/^\s*/, '')
|
44
|
+
|
45
|
+
indent_re = /^ {#{indentation}}/
|
46
|
+
content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*?\n/
|
47
|
+
[content, indentation, content_re, indent_re]
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/
|
52
|
+
LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/
|
53
|
+
LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/
|
54
|
+
|
55
|
+
# Parse the ordered or unordered list at the current location.
|
56
|
+
def parse_list
|
57
|
+
if @tree.children.last && @tree.children.last.type == :p # last element must not be a paragraph
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
|
62
|
+
list = Element.new(type)
|
63
|
+
|
64
|
+
item = nil
|
65
|
+
indent_re = nil
|
66
|
+
content_re = nil
|
67
|
+
eob_found = false
|
68
|
+
nested_list_found = false
|
69
|
+
while !@src.eos?
|
70
|
+
if @src.check(HR_START)
|
71
|
+
break
|
72
|
+
elsif @src.scan(list_start_re)
|
73
|
+
item = Element.new(:li)
|
74
|
+
item.value, indentation, content_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
75
|
+
list.children << item
|
76
|
+
|
77
|
+
list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ :
|
78
|
+
/^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/)
|
79
|
+
nested_list_found = false
|
80
|
+
elsif result = @src.scan(content_re)
|
81
|
+
result.sub!(/^(\t+)/) { " "*4*($1 ? $1.length : 0) }
|
82
|
+
result.sub!(indent_re, '')
|
83
|
+
if !nested_list_found && result =~ LIST_START
|
84
|
+
parse_blocks(item, item.value)
|
85
|
+
if item.children.length == 1 && item.children.first.type == :p
|
86
|
+
item.value = ''
|
87
|
+
else
|
88
|
+
item.children.clear
|
89
|
+
end
|
90
|
+
nested_list_found = true
|
91
|
+
end
|
92
|
+
item.value << result
|
93
|
+
elsif result = @src.scan(BLANK_LINE)
|
94
|
+
nested_list_found = true
|
95
|
+
item.value << result
|
96
|
+
elsif @src.scan(EOB_MARKER)
|
97
|
+
eob_found = true
|
98
|
+
break
|
99
|
+
else
|
100
|
+
break
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
@tree.children << list
|
105
|
+
|
106
|
+
last = nil
|
107
|
+
list.children.each do |it|
|
108
|
+
temp = Element.new(:temp)
|
109
|
+
parse_blocks(temp, it.value)
|
110
|
+
it.children += temp.children
|
111
|
+
it.value = nil
|
112
|
+
next if it.children.size == 0
|
113
|
+
|
114
|
+
if it.children.first.type == :p && (it.children.length < 2 || it.children[1].type != :blank ||
|
115
|
+
(it == list.children.last && it.children.length == 2 && !eob_found))
|
116
|
+
text = it.children.shift.children.first
|
117
|
+
text.value += "\n" if !it.children.empty? && it.children[0].type != :blank
|
118
|
+
it.children.unshift(text)
|
119
|
+
else
|
120
|
+
it.options[:first_is_block] = true
|
121
|
+
end
|
122
|
+
|
123
|
+
if it.children.last.type == :blank
|
124
|
+
last = it.children.pop
|
125
|
+
else
|
126
|
+
last = nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
@tree.children << last if !last.nil? && !eob_found
|
131
|
+
|
132
|
+
true
|
133
|
+
end
|
134
|
+
define_parser(:list, LIST_START)
|
135
|
+
|
136
|
+
|
137
|
+
DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/
|
138
|
+
|
139
|
+
# Parse the ordered or unordered list at the current location.
|
140
|
+
def parse_definition_list
|
141
|
+
children = @tree.children
|
142
|
+
if !children.last || (children.length == 1 && children.last.type != :p ) ||
|
143
|
+
(children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
|
144
|
+
return false
|
145
|
+
end
|
146
|
+
|
147
|
+
first_as_para = false
|
148
|
+
deflist = Element.new(:dl)
|
149
|
+
para = @tree.children.pop
|
150
|
+
if para.type == :blank
|
151
|
+
para = @tree.children.pop
|
152
|
+
first_as_para = true
|
153
|
+
end
|
154
|
+
para.children.first.value.split("\n").each do |term|
|
155
|
+
el = Element.new(:dt)
|
156
|
+
el.children << Element.new(:text, term)
|
157
|
+
deflist.children << el
|
158
|
+
end
|
159
|
+
|
160
|
+
item = nil
|
161
|
+
indent_re = nil
|
162
|
+
content_re = nil
|
163
|
+
def_start_re = DEFINITION_LIST_START
|
164
|
+
while !@src.eos?
|
165
|
+
if @src.scan(def_start_re)
|
166
|
+
item = Element.new(:dd)
|
167
|
+
item.options[:first_as_para] = first_as_para
|
168
|
+
item.value, indentation, content_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
169
|
+
deflist.children << item
|
170
|
+
|
171
|
+
def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
|
172
|
+
first_as_para = false
|
173
|
+
elsif result = @src.scan(content_re)
|
174
|
+
result.sub!(/^(\t+)/) { " "*4*($1 ? $1.length : 0) }
|
175
|
+
result.sub!(indent_re, '')
|
176
|
+
item.value << result
|
177
|
+
first_as_para = false
|
178
|
+
elsif result = @src.scan(BLANK_LINE)
|
179
|
+
first_as_para = true
|
180
|
+
item.value << result
|
181
|
+
else
|
182
|
+
break
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
last = nil
|
187
|
+
deflist.children.each do |it|
|
188
|
+
next if it.type == :dt
|
189
|
+
|
190
|
+
parse_blocks(it, it.value)
|
191
|
+
it.value = nil
|
192
|
+
next if it.children.size == 0
|
193
|
+
|
194
|
+
if it.children.last.type == :blank
|
195
|
+
last = it.children.pop
|
196
|
+
else
|
197
|
+
last = nil
|
198
|
+
end
|
199
|
+
if it.children.first.type == :p && !it.options.delete(:first_as_para)
|
200
|
+
text = it.children.shift.children.first
|
201
|
+
text.value += "\n" if !it.children.empty?
|
202
|
+
it.children.unshift(text)
|
203
|
+
else
|
204
|
+
it.options[:first_is_block] = true
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
if @tree.children.length >= 1 && @tree.children.last.type == :dl
|
209
|
+
@tree.children[-1].children += deflist.children
|
210
|
+
elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl
|
211
|
+
@tree.children.pop
|
212
|
+
@tree.children[-1].children += deflist.children
|
213
|
+
else
|
214
|
+
@tree.children << deflist
|
215
|
+
end
|
216
|
+
|
217
|
+
@tree.children << last if !last.nil?
|
218
|
+
|
219
|
+
true
|
220
|
+
end
|
221
|
+
define_parser(:definition_list, DEFINITION_LIST_START)
|
222
|
+
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
module Kramdown
|
24
|
+
module Parser
|
25
|
+
class Kramdown
|
26
|
+
|
27
|
+
PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/
|
28
|
+
|
29
|
+
# Parse the paragraph at the current location.
|
30
|
+
def parse_paragraph
|
31
|
+
@src.pos += @src.matched_size
|
32
|
+
if @tree.children.last && @tree.children.last.type == :p
|
33
|
+
@tree.children.last.children.first.value << "\n" << @src.matched.chomp
|
34
|
+
else
|
35
|
+
@tree.children << Element.new(:p)
|
36
|
+
add_text(@src.matched.lstrip.chomp, @tree.children.last)
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
define_parser(:paragraph, PARAGRAPH_START)
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2009 Thomas Leitner <t_leitner@gmx.at>
|
5
|
+
#
|
6
|
+
# This file is part of kramdown.
|
7
|
+
#
|
8
|
+
# kramdown is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
module Kramdown
|
24
|
+
module Parser
|
25
|
+
class Kramdown
|
26
|
+
|
27
|
+
TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :ellipsis],
|
28
|
+
['\\<<', '<<'], ['\\>>', '>>'],
|
29
|
+
['<< ', :laquo_space], [' >>', :raquo_space],
|
30
|
+
['<<', :laquo], ['>>', :raquo]]
|
31
|
+
TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten]
|
32
|
+
TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/
|
33
|
+
|
34
|
+
# Parse the typographic symbols at the current location.
|
35
|
+
def parse_typographic_syms
|
36
|
+
@src.pos += @src.matched_size
|
37
|
+
val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
|
38
|
+
if val.kind_of?(Symbol)
|
39
|
+
@tree.children << Element.new(:typographic_sym, val)
|
40
|
+
else
|
41
|
+
add_text(val.dup)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE)
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/kramdown/version.rb
CHANGED
@@ -7,8 +7,18 @@ This is some text
|
|
7
7
|
</div></div>
|
8
8
|
|
9
9
|
<div>
|
10
|
+
|
10
11
|
</div>
|
11
12
|
|
12
13
|
<div>
|
13
14
|
<p><a href="/">Foo</a></p>
|
14
15
|
</div>
|
16
|
+
|
17
|
+
<p>This is some
|
18
|
+
text</p>
|
19
|
+
|
20
|
+
<p><a href="http://example.com">http://example.com</a></p>
|
21
|
+
|
22
|
+
<div>
|
23
|
+
<http://example.com>
|
24
|
+
</div>
|
@@ -23,25 +23,17 @@ weiter
|
|
23
23
|
</div>
|
24
24
|
<div style=" "></div>
|
25
25
|
</div>
|
26
|
-
<div>
|
26
|
+
<div>
|
27
|
+
<p>bar </p>
|
28
|
+
</div>
|
27
29
|
</div>
|
28
30
|
|
29
31
|
<p>para5</p>
|
30
32
|
|
31
|
-
<div>
|
32
|
-
|
33
|
-
<div>id
|
34
|
-
</div>
|
35
|
-
test
|
36
|
-
|
37
|
-
<div>hallo<div>test</div>
|
38
|
-
<p>hallo</p>
|
39
|
-
</div>
|
40
|
-
|
41
|
-
<div>hallo<div>test
|
42
|
-
<p>hallo</p>
|
43
|
-
</div>
|
33
|
+
<div>
|
34
|
+
<p>id</p>
|
44
35
|
</div>
|
36
|
+
<p>test</p>
|
45
37
|
|
46
38
|
<div>
|
47
39
|
<p>hallo</p>
|
@@ -52,7 +44,8 @@ weiter
|
|
52
44
|
|
53
45
|
<p>para6</p>
|
54
46
|
|
55
|
-
<div
|
47
|
+
<div>
|
48
|
+
<div class="clear"></div>
|
56
49
|
<p>Another para.</p>
|
57
50
|
</div>
|
58
51
|
|