kramdown 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of kramdown might be problematic. Click here for more details.
- data/CONTRIBUTERS +1 -1
- data/ChangeLog +594 -0
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/data/kramdown/document.html +11 -2
- data/doc/default.template +2 -2
- data/doc/index.page +1 -2
- data/doc/quickref.page +2 -2
- data/doc/syntax.page +270 -179
- data/lib/kramdown/converter/html.rb +43 -29
- data/lib/kramdown/converter/kramdown.rb +97 -73
- data/lib/kramdown/converter/latex.rb +18 -13
- data/lib/kramdown/document.rb +8 -6
- data/lib/kramdown/options.rb +7 -10
- data/lib/kramdown/parser/html.rb +29 -21
- data/lib/kramdown/parser/kramdown.rb +19 -3
- data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -0
- data/lib/kramdown/parser/kramdown/attribute_list.rb +18 -12
- data/lib/kramdown/parser/kramdown/autolink.rb +1 -1
- data/lib/kramdown/parser/kramdown/block_boundary.rb +46 -0
- data/lib/kramdown/parser/kramdown/blockquote.rb +7 -3
- data/lib/kramdown/parser/kramdown/codeblock.rb +5 -3
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +1 -1
- data/lib/kramdown/parser/kramdown/extension.rb +22 -8
- data/lib/kramdown/parser/kramdown/footnote.rb +3 -2
- data/lib/kramdown/parser/kramdown/header.rb +10 -10
- data/lib/kramdown/parser/kramdown/html.rb +16 -14
- data/lib/kramdown/parser/kramdown/html_entity.rb +1 -1
- data/lib/kramdown/parser/kramdown/link.rb +8 -8
- data/lib/kramdown/parser/kramdown/list.rb +36 -29
- data/lib/kramdown/parser/kramdown/math.rb +15 -4
- data/lib/kramdown/parser/kramdown/paragraph.rb +14 -3
- data/lib/kramdown/parser/kramdown/table.rb +17 -9
- data/lib/kramdown/utils.rb +1 -0
- data/lib/kramdown/utils/html.rb +9 -9
- data/lib/kramdown/utils/ordered_hash.rb +79 -0
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +9 -12
- data/test/test_files.rb +6 -1
- data/test/testcases/block/02_eob/middle.html +0 -1
- data/test/testcases/block/04_header/atx_header.html +5 -2
- data/test/testcases/block/04_header/atx_header.text +3 -1
- data/test/testcases/block/04_header/setext_header.html +4 -5
- data/test/testcases/block/04_header/setext_header.html.19 +30 -0
- data/test/testcases/block/05_blockquote/lazy.html +34 -0
- data/test/testcases/block/05_blockquote/lazy.text +20 -0
- data/test/testcases/block/05_blockquote/nested.html +1 -0
- data/test/testcases/block/05_blockquote/nested.text +1 -0
- data/test/testcases/block/05_blockquote/with_code_blocks.html +2 -2
- data/test/testcases/block/06_codeblock/lazy.html +4 -0
- data/test/testcases/block/06_codeblock/lazy.text +5 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end_1.html +2 -0
- data/test/testcases/block/06_codeblock/no_newline_at_end_1.text +2 -0
- data/test/testcases/block/06_codeblock/with_ial.html +6 -0
- data/test/testcases/block/06_codeblock/with_ial.text +5 -0
- data/test/testcases/block/07_horizontal_rule/normal.html +0 -2
- data/test/testcases/block/07_horizontal_rule/normal.text +0 -2
- data/test/testcases/block/08_list/item_ial.html +1 -3
- data/test/testcases/block/08_list/lazy.html +39 -0
- data/test/testcases/block/08_list/lazy.text +29 -0
- data/test/testcases/block/08_list/list_and_others.html +5 -3
- data/test/testcases/block/08_list/list_and_others.text +1 -0
- data/test/testcases/block/08_list/other_first_element.html +2 -2
- data/test/testcases/block/08_list/other_first_element.text +1 -1
- data/test/testcases/block/08_list/simple_ul.html +0 -13
- data/test/testcases/block/08_list/simple_ul.text +0 -7
- data/test/testcases/block/08_list/special_cases.html +8 -31
- data/test/testcases/block/08_list/special_cases.text +2 -15
- data/test/testcases/block/09_html/comment.html +2 -2
- data/test/testcases/block/09_html/html_to_native/emphasis.html +2 -0
- data/test/testcases/block/09_html/html_to_native/emphasis.text +2 -0
- data/test/testcases/block/09_html/html_to_native/table_normal.html +2 -1
- data/test/testcases/block/09_html/html_to_native/table_simple.html +4 -2
- data/test/testcases/block/09_html/invalid_html_1.html +2 -0
- data/test/testcases/block/09_html/parse_as_raw.html +2 -2
- data/test/testcases/block/09_html/parse_as_span.html +1 -1
- data/test/testcases/block/09_html/simple.html +2 -0
- data/test/testcases/block/09_html/simple.html.19 +2 -0
- data/test/testcases/block/09_html/simple.text +2 -0
- data/test/testcases/block/11_ial/auto_id_and_ial.html +1 -1
- data/test/testcases/block/11_ial/simple.html +2 -3
- data/test/testcases/block/12_extension/comment.html +3 -1
- data/test/testcases/block/12_extension/comment.text +2 -1
- data/test/testcases/block/12_extension/ignored.html +5 -1
- data/test/testcases/block/12_extension/ignored.text +1 -1
- data/test/testcases/block/12_extension/nomarkdown.html +5 -1
- data/test/testcases/block/12_extension/nomarkdown.kramdown +20 -0
- data/test/testcases/block/12_extension/nomarkdown.latex +13 -0
- data/test/testcases/block/12_extension/nomarkdown.text +11 -1
- data/test/testcases/block/13_definition_list/item_ial.html +1 -3
- data/test/testcases/block/13_definition_list/item_ial.text +1 -1
- data/test/testcases/block/13_definition_list/simple.html +2 -2
- data/test/testcases/block/14_table/errors.html +5 -0
- data/test/testcases/block/14_table/errors.text +6 -0
- data/test/testcases/block/14_table/header.text +1 -1
- data/test/testcases/block/14_table/no_table.text +1 -1
- data/test/testcases/block/14_table/simple.html +78 -0
- data/test/testcases/block/14_table/simple.text +22 -0
- data/test/testcases/block/15_math/normal.html +11 -4
- data/test/testcases/block/15_math/normal.text +10 -0
- data/test/testcases/encoding.html +1 -1
- data/test/testcases/span/01_link/image_in_a.html +3 -3
- data/test/testcases/span/01_link/imagelinks.html +7 -7
- data/test/testcases/span/01_link/inline.html +11 -5
- data/test/testcases/span/01_link/inline.html.19 +11 -5
- data/test/testcases/span/01_link/inline.text +11 -5
- data/test/testcases/span/01_link/link_defs.html +2 -1
- data/test/testcases/span/01_link/link_defs.text +4 -0
- data/test/testcases/span/01_link/reference.html +3 -0
- data/test/testcases/span/01_link/reference.html.19 +3 -0
- data/test/testcases/span/01_link/reference.text +5 -0
- data/test/testcases/span/03_codespan/highlighting.html +1 -0
- data/test/testcases/span/03_codespan/highlighting.text +1 -0
- data/test/testcases/span/04_footnote/definitions.html +3 -0
- data/test/testcases/span/04_footnote/definitions.latex +3 -4
- data/test/testcases/span/04_footnote/definitions.text +6 -0
- data/test/testcases/span/04_footnote/footnote_nr.latex +1 -5
- data/test/testcases/span/04_footnote/markers.latex +5 -14
- data/test/testcases/span/05_html/markdown_attr.html +1 -1
- data/test/testcases/span/05_html/markdown_attr.text +1 -1
- data/test/testcases/span/05_html/normal.html +5 -3
- data/test/testcases/span/05_html/normal.text +2 -0
- data/test/testcases/span/escaped_chars/normal.html +2 -0
- data/test/testcases/span/escaped_chars/normal.text +2 -0
- data/test/testcases/span/extension/comment.html +2 -2
- data/test/testcases/span/extension/ignored.html +1 -1
- data/test/testcases/span/text_substitutions/typography.html +1 -1
- data/test/testcases/span/text_substitutions/typography.html.19 +1 -1
- data/test/testcases/span/text_substitutions/typography.text +1 -1
- metadata +20 -5
- data/test/testcases/block/05_blockquote/only_first_quoted.html +0 -8
- data/test/testcases/block/05_blockquote/only_first_quoted.text +0 -4
@@ -49,6 +49,7 @@ module Kramdown
|
|
49
49
|
options = opts.dup.merge(:parent => el)
|
50
50
|
el.children.each_with_index do |inner_el, index|
|
51
51
|
options[:index] = index
|
52
|
+
options[:result] = result
|
52
53
|
result << send("convert_#{inner_el.type}", inner_el, options)
|
53
54
|
end
|
54
55
|
result
|
@@ -59,7 +60,7 @@ module Kramdown
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def convert_blank(el, opts)
|
62
|
-
""
|
63
|
+
opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n"
|
63
64
|
end
|
64
65
|
|
65
66
|
def convert_text(el, opts)
|
@@ -76,12 +77,12 @@ module Kramdown
|
|
76
77
|
|
77
78
|
def convert_standalone_image(el, opts, img)
|
78
79
|
attrs = attribute_list(el)
|
79
|
-
"\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n\\caption{#{escape(el.children.first.
|
80
|
+
"\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n\\caption{#{escape(el.children.first.attr['alt'])}}\n\\end{figure}#{attrs}\n"
|
80
81
|
end
|
81
82
|
|
82
83
|
def convert_codeblock(el, opts)
|
83
|
-
show_whitespace = el.
|
84
|
-
lang = el.
|
84
|
+
show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/
|
85
|
+
lang = el.attr['lang']
|
85
86
|
if show_whitespace || lang
|
86
87
|
result = "\\lstset{showspaces=%s,showtabs=%s}\n" % (show_whitespace ? ['true', 'true'] : ['false', 'false'])
|
87
88
|
result += "\\lstset{language=#{lang}}\n" if lang
|
@@ -95,7 +96,7 @@ module Kramdown
|
|
95
96
|
|
96
97
|
def latex_environment(type, el, text)
|
97
98
|
attrs = attribute_list(el)
|
98
|
-
"\\begin{#{type}}#{attrs}\n#{text}\n\\end{#{type}}#{attrs}\n"
|
99
|
+
"\\begin{#{type}}#{attrs}\n#{text.rstrip}\n\\end{#{type}}#{attrs}\n"
|
99
100
|
end
|
100
101
|
|
101
102
|
def convert_blockquote(el, opts)
|
@@ -112,7 +113,7 @@ module Kramdown
|
|
112
113
|
}
|
113
114
|
def convert_header(el, opts)
|
114
115
|
type = HEADER_TYPES[el.options[:level]]
|
115
|
-
if ((
|
116
|
+
if ((id = el.attr['id']) ||
|
116
117
|
(@doc.options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) &&
|
117
118
|
(@doc.options[:toc_depth] <= 0 || el.options[:level] <= @doc.options[:toc_depth])
|
118
119
|
"\\hypertarget{#{id}}{}\\#{type}{#{inner(el, opts)}}\\label{#{id}}\n\n"
|
@@ -213,7 +214,7 @@ module Kramdown
|
|
213
214
|
end
|
214
215
|
|
215
216
|
def convert_a(el, opts)
|
216
|
-
url = el.
|
217
|
+
url = el.attr['href']
|
217
218
|
if url =~ /^#/
|
218
219
|
"\\hyperlink{#{url[1..-1]}}{#{inner(el, opts)}}"
|
219
220
|
else
|
@@ -222,12 +223,12 @@ module Kramdown
|
|
222
223
|
end
|
223
224
|
|
224
225
|
def convert_img(el, opts)
|
225
|
-
if el.
|
226
|
+
if el.attr['src'] =~ /^(https?|ftps?):\/\//
|
226
227
|
@doc.warnings << "Cannot include non-local image"
|
227
228
|
''
|
228
|
-
elsif !el.options
|
229
|
+
elsif !el.options.attr['src'].empty?
|
229
230
|
@doc.conversion_infos[:packages] << 'graphicx'
|
230
|
-
"\\includegraphics{#{el.
|
231
|
+
"\\includegraphics{#{el.attr['src']}}"
|
231
232
|
else
|
232
233
|
@doc.warnings << "Cannot include image with empty path"
|
233
234
|
''
|
@@ -240,11 +241,15 @@ module Kramdown
|
|
240
241
|
|
241
242
|
def convert_footnote(el, opts)
|
242
243
|
@doc.conversion_infos[:packages] << 'fancyvrb'
|
243
|
-
"\\footnote{#{inner(@doc.parse_infos[:footnotes][el.options[:name]][:content], opts)}}"
|
244
|
+
"\\footnote{#{inner(@doc.parse_infos[:footnotes][el.options[:name]][:content], opts).rstrip}}"
|
244
245
|
end
|
245
246
|
|
246
247
|
def convert_raw(el, opts)
|
247
|
-
|
248
|
+
if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('latex')
|
249
|
+
el.value + (el.options[:category] == :block ? "\n" : '')
|
250
|
+
else
|
251
|
+
''
|
252
|
+
end
|
248
253
|
end
|
249
254
|
|
250
255
|
def convert_em(el, opts)
|
@@ -561,7 +566,7 @@ module Kramdown
|
|
561
566
|
end
|
562
567
|
|
563
568
|
def attribute_list(el)
|
564
|
-
attrs =
|
569
|
+
attrs = el.attr.map {|k,v| v.nil? ? '' : " #{k}=\"#{v.to_s}\""}.compact.sort.join('')
|
565
570
|
attrs = " % #{attrs}" if !attrs.empty?
|
566
571
|
attrs
|
567
572
|
end
|
data/lib/kramdown/document.rb
CHANGED
@@ -136,10 +136,12 @@ module Kramdown
|
|
136
136
|
# Many elements don't use this field.
|
137
137
|
attr_accessor :value
|
138
138
|
|
139
|
+
# The attributes of the element. Uses an Utils::OrderedHash to retain the insertion order.
|
140
|
+
attr_reader :attr
|
141
|
+
|
139
142
|
# The options hash for the element. It is used for storing arbitray options as well as the
|
140
143
|
# following special contents:
|
141
144
|
#
|
142
|
-
# - *Attributes* of the element under the <tt>:attr</tt> key
|
143
145
|
# - Category of the element, either <tt>:block</tt> or <tt>:span</tt>, under the
|
144
146
|
# <tt>:category</tt> key. If this key is absent, it can be assumed that the element is in the
|
145
147
|
# <tt>:span</tt> category.
|
@@ -149,15 +151,15 @@ module Kramdown
|
|
149
151
|
attr_accessor :children
|
150
152
|
|
151
153
|
|
152
|
-
# Create a new Element object of type +type+. The optional parameters +value
|
153
|
-
# also be set in this constructor for convenience.
|
154
|
-
def initialize(type, value = nil, options = {})
|
155
|
-
@type, @value, @options = type, value, options
|
154
|
+
# Create a new Element object of type +type+. The optional parameters +value+, +attr+ and
|
155
|
+
# +options+ can also be set in this constructor for convenience.
|
156
|
+
def initialize(type, value = nil, attr = nil, options = {})
|
157
|
+
@type, @value, @attr, @options = type, value, Utils::OrderedHash.new(attr), options
|
156
158
|
@children = []
|
157
159
|
end
|
158
160
|
|
159
161
|
def inspect #:nodoc:
|
160
|
-
"<kd:#{@type}#{@value.nil? ? '' : ' ' + @value.inspect}#{options.empty? ? '' : ' ' + @options.inspect}#{@children.empty? ? '' : ' ' + @children.inspect}>"
|
162
|
+
"<kd:#{@type}#{@value.nil? ? '' : ' ' + @value.inspect} #{@attr.inspect}#{options.empty? ? '' : ' ' + @options.inspect}#{@children.empty? ? '' : ' ' + @children.inspect}>"
|
161
163
|
end
|
162
164
|
|
163
165
|
end
|
data/lib/kramdown/options.rb
CHANGED
@@ -260,16 +260,6 @@ styles are directly applied to the code elements).
|
|
260
260
|
|
261
261
|
Default: style
|
262
262
|
Used by: HTML converter
|
263
|
-
EOF
|
264
|
-
|
265
|
-
define(:numeric_entities, Boolean, false, <<EOF)
|
266
|
-
DEPRECATED: Defines whether entities are output using names or numeric values
|
267
|
-
|
268
|
-
Note that this option is deprecated and replaced by the entities option.
|
269
|
-
This option will be removed in a future release.
|
270
|
-
|
271
|
-
Default: false
|
272
|
-
Used by: HTML converter, kramdown converter
|
273
263
|
EOF
|
274
264
|
|
275
265
|
define(:entity_output, Symbol, :as_char, <<EOF)
|
@@ -292,6 +282,13 @@ and h2 headers but not for h3, h4, etc. A value of 0 uses all header levels.
|
|
292
282
|
|
293
283
|
Default: 0
|
294
284
|
Used by: HTML/Latex converter
|
285
|
+
EOF
|
286
|
+
|
287
|
+
define(:line_width, Integer, 72, <<EOF)
|
288
|
+
Defines the line width to be used when outputting a document
|
289
|
+
|
290
|
+
Default: 72
|
291
|
+
Used by: kramdown converter
|
295
292
|
EOF
|
296
293
|
|
297
294
|
end
|
data/lib/kramdown/parser/html.rb
CHANGED
@@ -39,7 +39,7 @@ module Kramdown
|
|
39
39
|
HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m
|
40
40
|
HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})\s*=\s*(["'])(.*?)\2/m
|
41
41
|
HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}\s*=\s*(["']).*?\3)*)\s*(\/)?>/m
|
42
|
-
HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::
|
42
|
+
HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::UNAME_STR})\s*>/m
|
43
43
|
HTML_ENTITY_RE = /&([\w:][\-\w\.:]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/
|
44
44
|
|
45
45
|
|
@@ -80,10 +80,10 @@ module Kramdown
|
|
80
80
|
def handle_html_start_tag
|
81
81
|
name = @src[1]
|
82
82
|
closed = !@src[4].nil?
|
83
|
-
attrs =
|
83
|
+
attrs = Utils::OrderedHash.new
|
84
84
|
@src[2].scan(HTML_ATTRIBUTE_RE).each {|attr,sep,val| attrs[attr] = val}
|
85
85
|
|
86
|
-
el = Element.new(:html_element, name,
|
86
|
+
el = Element.new(:html_element, name, attrs, :category => :block)
|
87
87
|
@tree.children << el
|
88
88
|
|
89
89
|
if !closed && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value)
|
@@ -129,9 +129,9 @@ module Kramdown
|
|
129
129
|
if result = @src.scan_until(HTML_RAW_START)
|
130
130
|
add_text(result, @tree, :text)
|
131
131
|
if result = @src.scan(HTML_COMMENT_RE)
|
132
|
-
@tree.children << Element.new(:xml_comment, result, :category => :block
|
132
|
+
@tree.children << Element.new(:xml_comment, result, nil, :category => :block)
|
133
133
|
elsif result = @src.scan(HTML_INSTRUCTION_RE)
|
134
|
-
@tree.children << Element.new(:xml_pi, result, :category => :block
|
134
|
+
@tree.children << Element.new(:xml_pi, result, nil, :category => :block)
|
135
135
|
elsif @src.scan(HTML_TAG_RE)
|
136
136
|
handle_html_start_tag(&block)
|
137
137
|
elsif @src.scan(HTML_TAG_CLOSE_RE)
|
@@ -242,7 +242,7 @@ module Kramdown
|
|
242
242
|
elsif %w{mdash ndash hellip laquo raquo}.include?(val)
|
243
243
|
Element.new(:typographic_sym, val.intern)
|
244
244
|
else
|
245
|
-
Element.new(:entity, entity(val), :original => src.matched)
|
245
|
+
Element.new(:entity, entity(val), nil, :original => src.matched)
|
246
246
|
end
|
247
247
|
else
|
248
248
|
result << Element.new(:text, src.scan(/.*/m))
|
@@ -253,8 +253,7 @@ module Kramdown
|
|
253
253
|
|
254
254
|
def process_html_element(el, do_conversion = true, preserve_text = false)
|
255
255
|
el.options = {:category => HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block,
|
256
|
-
:parse_type => HTML_PARSE_AS[el.value]
|
257
|
-
:attr => el.options[:attr]
|
256
|
+
:parse_type => HTML_PARSE_AS[el.value]
|
258
257
|
}
|
259
258
|
process_children(el, do_conversion, preserve_text)
|
260
259
|
end
|
@@ -263,15 +262,13 @@ module Kramdown
|
|
263
262
|
el.children.delete_if {|c| c.type == :text}
|
264
263
|
end
|
265
264
|
|
266
|
-
SPAN_ELEMENTS = [:em, :strong, :br, :a, :img, :codespan, :entity, :smart_quote, :typographic_sym, :math]
|
267
|
-
|
268
265
|
def wrap_text_children(el)
|
269
266
|
tmp = []
|
270
267
|
last_is_p = false
|
271
268
|
el.children.each do |c|
|
272
269
|
if c.options[:category] != :block || c.type == :text
|
273
270
|
if !last_is_p
|
274
|
-
tmp << Element.new(:p, nil, :transparent => true)
|
271
|
+
tmp << Element.new(:p, nil, nil, :transparent => true)
|
275
272
|
last_is_p = true
|
276
273
|
end
|
277
274
|
tmp.last.children << c
|
@@ -306,7 +303,7 @@ module Kramdown
|
|
306
303
|
|
307
304
|
def set_basics(el, type, category, opts = {})
|
308
305
|
el.type = type
|
309
|
-
el.options = {:category => category
|
306
|
+
el.options = {:category => category}.merge(opts)
|
310
307
|
el.value = nil
|
311
308
|
end
|
312
309
|
|
@@ -316,7 +313,7 @@ module Kramdown
|
|
316
313
|
end
|
317
314
|
|
318
315
|
def convert_a(el)
|
319
|
-
if el.
|
316
|
+
if el.attr['href']
|
320
317
|
set_basics(el, :a, :span)
|
321
318
|
process_children(el)
|
322
319
|
else
|
@@ -324,6 +321,16 @@ module Kramdown
|
|
324
321
|
end
|
325
322
|
end
|
326
323
|
|
324
|
+
def convert_b(el)
|
325
|
+
set_basics(el, :strong, :span)
|
326
|
+
process_children(el)
|
327
|
+
end
|
328
|
+
|
329
|
+
def convert_i(el)
|
330
|
+
set_basics(el, :em, :span)
|
331
|
+
process_children(el)
|
332
|
+
end
|
333
|
+
|
327
334
|
def convert_h1(el)
|
328
335
|
set_basics(el, :header, :block, :level => el.value[1..1].to_i)
|
329
336
|
extract_text(el, el.options[:raw_text] = '')
|
@@ -366,6 +373,7 @@ module Kramdown
|
|
366
373
|
set_basics(el, :codeblock, :block)
|
367
374
|
end
|
368
375
|
el.value = result.first.value
|
376
|
+
el.children.clear
|
369
377
|
end
|
370
378
|
end
|
371
379
|
alias :convert_pre :convert_code
|
@@ -388,7 +396,7 @@ module Kramdown
|
|
388
396
|
end
|
389
397
|
calc_alignment.call(el)
|
390
398
|
if el.children.first.type == :tr
|
391
|
-
tbody = Element.new(:tbody, nil, :category => :block)
|
399
|
+
tbody = Element.new(:tbody, nil, nil, :category => :block)
|
392
400
|
tbody.children = el.children
|
393
401
|
el.children = [tbody]
|
394
402
|
end
|
@@ -429,17 +437,17 @@ module Kramdown
|
|
429
437
|
alias :convert_span :convert_div
|
430
438
|
|
431
439
|
def is_math_tag?(el)
|
432
|
-
el.
|
440
|
+
el.attr['class'].to_s =~ /\bmath\b/ &&
|
433
441
|
el.children.size == 1 && el.children.first.type == :text
|
434
442
|
end
|
435
443
|
|
436
444
|
def handle_math_tag(el)
|
437
445
|
set_basics(el, :math, (el.value == 'div' ? :block : :span))
|
438
446
|
el.value = el.children.shift.value
|
439
|
-
if el.
|
440
|
-
el.
|
447
|
+
if el.attr['class'] =~ /^\s*math\s*$/
|
448
|
+
el.attr.delete('class')
|
441
449
|
else
|
442
|
-
el.
|
450
|
+
el.attr['class'].sub!(/\s?math/, '')
|
443
451
|
end
|
444
452
|
el.value.gsub!(/&(amp|quot|gt|lt);/) do |m|
|
445
453
|
case m
|
@@ -462,11 +470,11 @@ module Kramdown
|
|
462
470
|
|
463
471
|
while true
|
464
472
|
if result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/)
|
465
|
-
@tree.children << Element.new(:xml_pi, result.strip, :category => :block)
|
473
|
+
@tree.children << Element.new(:xml_pi, result.strip, nil, :category => :block)
|
466
474
|
elsif result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/)
|
467
|
-
@tree.children << Element.new(:html_doctype, result.strip, :category => :block)
|
475
|
+
@tree.children << Element.new(:html_doctype, result.strip, nil, :category => :block)
|
468
476
|
elsif result = @src.scan(/\s*#{HTML_COMMENT_RE}/)
|
469
|
-
@tree.children << Element.new(:xml_comment, result.strip, :category => :block)
|
477
|
+
@tree.children << Element.new(:xml_comment, result.strip, nil, :category => :block)
|
470
478
|
else
|
471
479
|
break
|
472
480
|
end
|
@@ -168,17 +168,28 @@ module Kramdown
|
|
168
168
|
# Update the tree by parsing all <tt>:raw_text</tt> elements with the span level parser
|
169
169
|
# (resets +@tree+, +@src+ and the +@stack+) and by updating the attributes from the IALs.
|
170
170
|
def update_tree(element)
|
171
|
+
last_blank = nil
|
171
172
|
element.children.map! do |child|
|
172
173
|
if child.type == :raw_text
|
174
|
+
last_blank = nil
|
173
175
|
@stack, @tree, @text_type = [], nil, :text
|
174
176
|
@src = StringScanner.new(child.value)
|
175
177
|
parse_spans(child)
|
176
178
|
child.children
|
177
179
|
elsif child.type == :eob
|
178
180
|
[]
|
181
|
+
elsif child.type == :blank
|
182
|
+
if last_blank
|
183
|
+
last_blank.value += child.value
|
184
|
+
[]
|
185
|
+
else
|
186
|
+
last_blank = child
|
187
|
+
child
|
188
|
+
end
|
179
189
|
else
|
190
|
+
last_blank = nil
|
180
191
|
update_tree(child)
|
181
|
-
update_attr_with_ial(child.
|
192
|
+
update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial]
|
182
193
|
child
|
183
194
|
end
|
184
195
|
end.flatten!
|
@@ -227,8 +238,13 @@ module Kramdown
|
|
227
238
|
ial[:refs].each do |ref|
|
228
239
|
update_attr_with_ial(attr, ref) if ref = @doc.parse_infos[:ald][ref]
|
229
240
|
end if ial[:refs]
|
230
|
-
|
231
|
-
|
241
|
+
ial.each do |k,v|
|
242
|
+
if k == 'class'
|
243
|
+
attr[k] = ((attr[k] || '') + " #{v}").lstrip
|
244
|
+
elsif k.kind_of?(String)
|
245
|
+
attr[k] = v
|
246
|
+
end
|
247
|
+
end
|
232
248
|
end
|
233
249
|
|
234
250
|
# Create a new block level element, taking care of applying a preceding block IAL if it exists.
|
@@ -32,6 +32,7 @@ module Kramdown
|
|
32
32
|
abbrev_id, abbrev_text = @src[1], @src[2].strip
|
33
33
|
warning("Duplicate abbreviation ID '#{abbrev_id}' - overwriting") if @doc.parse_infos[:abbrev_defs][abbrev_id]
|
34
34
|
@doc.parse_infos[:abbrev_defs][abbrev_id] = abbrev_text
|
35
|
+
@tree.children << Element.new(:eob, :abbrev_def)
|
35
36
|
true
|
36
37
|
end
|
37
38
|
define_parser(:abbrev_definition, ABBREV_DEFINITION_START)
|
@@ -43,8 +43,13 @@ module Kramdown
|
|
43
43
|
# Update the +ial+ with the information from the inline attribute list +opts+.
|
44
44
|
def update_ial_with_ial(ial, opts)
|
45
45
|
(ial[:refs] ||= []) << opts[:refs]
|
46
|
-
|
47
|
-
|
46
|
+
opts.each do |k,v|
|
47
|
+
if k == 'class'
|
48
|
+
ial[k] = ((ial[k] || '') + " #{v}").lstrip
|
49
|
+
elsif k.kind_of?(String)
|
50
|
+
ial[k] = v
|
51
|
+
end
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
|
@@ -53,7 +58,7 @@ module Kramdown
|
|
53
58
|
ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/
|
54
59
|
ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/
|
55
60
|
ALD_TYPE_CLASS_NAME = /\.(#{ALD_ID_NAME})/
|
56
|
-
ALD_TYPE_ID_NAME = /#(
|
61
|
+
ALD_TYPE_ID_NAME = /#(\w[\w:-]*)/
|
57
62
|
ALD_TYPE_REF = /(#{ALD_ID_NAME})/
|
58
63
|
ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}|#{ALD_TYPE_REF})(?=\s|\Z)/
|
59
64
|
ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/
|
@@ -61,24 +66,25 @@ module Kramdown
|
|
61
66
|
# Parse the attribute list definition at the current location.
|
62
67
|
def parse_ald
|
63
68
|
@src.pos += @src.matched_size
|
64
|
-
parse_attribute_list(@src[2], @doc.parse_infos[:ald][@src[1]] ||=
|
65
|
-
@tree.children << Element.new(:eob)
|
69
|
+
parse_attribute_list(@src[2], @doc.parse_infos[:ald][@src[1]] ||= Utils::OrderedHash.new)
|
70
|
+
@tree.children << Element.new(:eob, :ald)
|
66
71
|
true
|
67
72
|
end
|
68
73
|
define_parser(:ald, ALD_START)
|
69
74
|
|
70
75
|
|
71
|
-
|
76
|
+
IAL_BLOCK = /\{:(?!:|\/)(#{ALD_ANY_CHARS}+)\}\s*?\n/
|
77
|
+
IAL_BLOCK_START = /^#{OPT_SPACE}#{IAL_BLOCK}/
|
72
78
|
|
73
79
|
# Parse the inline attribute list at the current location.
|
74
80
|
def parse_block_ial
|
75
81
|
@src.pos += @src.matched_size
|
76
82
|
if @tree.children.last && @tree.children.last.type != :blank && @tree.children.last.type != :eob
|
77
|
-
parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||=
|
83
|
+
parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= Utils::OrderedHash.new)
|
84
|
+
@tree.children << Element.new(:eob, :ial) unless @src.check(IAL_BLOCK_START)
|
78
85
|
else
|
79
|
-
parse_attribute_list(@src[1], @block_ial =
|
86
|
+
parse_attribute_list(@src[1], @block_ial = Utils::OrderedHash.new)
|
80
87
|
end
|
81
|
-
@tree.children << Element.new(:eob) unless @src.check(IAL_BLOCK_START)
|
82
88
|
true
|
83
89
|
end
|
84
90
|
define_parser(:block_ial, IAL_BLOCK_START)
|
@@ -90,10 +96,10 @@ module Kramdown
|
|
90
96
|
def parse_span_ial
|
91
97
|
@src.pos += @src.matched_size
|
92
98
|
if @tree.children.last && @tree.children.last.type != :text
|
93
|
-
attr =
|
99
|
+
attr = Utils::OrderedHash.new
|
94
100
|
parse_attribute_list(@src[1], attr)
|
95
|
-
update_ial_with_ial(@tree.children.last.options[:ial] ||=
|
96
|
-
update_attr_with_ial(@tree.children.last.
|
101
|
+
update_ial_with_ial(@tree.children.last.options[:ial] ||= Utils::OrderedHash.new, attr)
|
102
|
+
update_attr_with_ial(@tree.children.last.attr, attr)
|
97
103
|
else
|
98
104
|
warning("Ignoring span IAL because preceding element is just text")
|
99
105
|
end
|
@@ -43,7 +43,7 @@ module Kramdown
|
|
43
43
|
@src.pos += @src.matched_size
|
44
44
|
href = @src[1]
|
45
45
|
href= "mailto:#{href}" if @src[2].nil?
|
46
|
-
el = Element.new(:a, nil, {
|
46
|
+
el = Element.new(:a, nil, {'href' => href})
|
47
47
|
add_text(@src[1].sub(/^mailto:/, ''), el)
|
48
48
|
@tree.children << el
|
49
49
|
end
|