kramdown 1.17.0 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +4 -2
- data/VERSION +1 -1
- data/bin/kramdown +13 -14
- data/lib/kramdown.rb +2 -2
- data/lib/kramdown/converter.rb +6 -7
- data/lib/kramdown/converter/base.rb +18 -29
- data/lib/kramdown/converter/hash_ast.rb +4 -4
- data/lib/kramdown/converter/html.rb +82 -67
- data/lib/kramdown/converter/kramdown.rb +83 -78
- data/lib/kramdown/converter/latex.rb +53 -47
- data/lib/kramdown/converter/man.rb +22 -25
- data/lib/kramdown/converter/math_engine/mathjax.rb +10 -10
- data/lib/kramdown/converter/remove_html_tags.rb +2 -2
- data/lib/kramdown/converter/syntax_highlighter.rb +2 -2
- data/lib/kramdown/converter/syntax_highlighter/minted.rb +2 -2
- data/lib/kramdown/converter/syntax_highlighter/rouge.rb +5 -5
- data/lib/kramdown/converter/toc.rb +5 -5
- data/lib/kramdown/document.rb +9 -11
- data/lib/kramdown/element.rb +11 -9
- data/lib/kramdown/error.rb +2 -2
- data/lib/kramdown/options.rb +258 -384
- data/lib/kramdown/parser.rb +2 -3
- data/lib/kramdown/parser/base.rb +7 -6
- data/lib/kramdown/parser/html.rb +103 -95
- data/lib/kramdown/parser/kramdown.rb +32 -36
- data/lib/kramdown/parser/kramdown/abbreviation.rb +13 -10
- data/lib/kramdown/parser/kramdown/autolink.rb +3 -3
- data/lib/kramdown/parser/kramdown/blank_line.rb +2 -2
- data/lib/kramdown/parser/kramdown/block_boundary.rb +2 -2
- data/lib/kramdown/parser/kramdown/blockquote.rb +4 -5
- data/lib/kramdown/parser/kramdown/codeblock.rb +4 -5
- data/lib/kramdown/parser/kramdown/codespan.rb +5 -5
- data/lib/kramdown/parser/kramdown/emphasis.rb +6 -6
- data/lib/kramdown/parser/kramdown/eob.rb +2 -2
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +2 -2
- data/lib/kramdown/parser/kramdown/extensions.rb +31 -26
- data/lib/kramdown/parser/kramdown/footnote.rb +7 -6
- data/lib/kramdown/parser/kramdown/header.rb +6 -6
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +3 -3
- data/lib/kramdown/parser/kramdown/html.rb +31 -26
- data/lib/kramdown/parser/kramdown/html_entity.rb +6 -5
- data/lib/kramdown/parser/kramdown/line_break.rb +3 -3
- data/lib/kramdown/parser/kramdown/link.rb +13 -11
- data/lib/kramdown/parser/kramdown/list.rb +38 -40
- data/lib/kramdown/parser/kramdown/math.rb +4 -5
- data/lib/kramdown/parser/kramdown/paragraph.rb +5 -5
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +23 -23
- data/lib/kramdown/parser/kramdown/table.rb +18 -17
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +8 -8
- data/lib/kramdown/parser/markdown.rb +9 -8
- data/lib/kramdown/utils.rb +5 -6
- data/lib/kramdown/utils/configurable.rb +7 -6
- data/lib/kramdown/utils/entities.rb +286 -289
- data/lib/kramdown/utils/html.rb +10 -12
- data/lib/kramdown/utils/lru_cache.rb +3 -2
- data/lib/kramdown/utils/string_scanner.rb +2 -3
- data/lib/kramdown/utils/unidecoder.rb +8 -6
- data/lib/kramdown/version.rb +3 -3
- data/man/man1/kramdown.1 +3 -107
- data/test/run_tests.rb +6 -6
- data/test/test_files.rb +122 -298
- data/test/test_location.rb +8 -30
- data/test/test_string_scanner_kramdown.rb +6 -9
- data/test/testcases/block/06_codeblock/highlighting-opts.html +6 -6
- data/test/testcases/block/06_codeblock/highlighting.html +5 -6
- data/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options +1 -1
- data/test/testcases/block/07_horizontal_rule/error.html +2 -2
- data/test/testcases/block/09_html/html5_attributes.html +2 -0
- data/test/testcases/block/09_html/html5_attributes.text +2 -0
- data/test/testcases/block/09_html/html_to_native/typography.html +1 -1
- data/test/testcases/block/09_html/simple.html +1 -1
- data/test/testcases/block/12_extension/options3.html +7 -6
- data/test/testcases/block/12_extension/options3.text +2 -2
- data/test/testcases/span/01_link/inline.html +1 -1
- data/test/testcases/span/01_link/reference.html +3 -3
- data/test/testcases/span/03_codespan/highlighting.html +1 -1
- data/test/testcases/span/text_substitutions/entities_as_char.html +1 -1
- metadata +5 -234
- data/Rakefile +0 -341
- data/benchmark/benchmark.rb +0 -43
- data/benchmark/benchmark.sh +0 -74
- data/benchmark/generate_data.rb +0 -119
- data/benchmark/mdbasics.text +0 -306
- data/benchmark/mdsyntax.text +0 -888
- data/benchmark/testing.sh +0 -12
- data/benchmark/timing.sh +0 -10
- data/doc/_design.scss +0 -441
- data/doc/bg.png +0 -0
- data/doc/default.scss +0 -217
- data/doc/default.template +0 -62
- data/doc/documentation.page +0 -84
- data/doc/documentation.template +0 -36
- data/doc/index.page +0 -113
- data/doc/installation.page +0 -88
- data/doc/links.markdown +0 -6
- data/doc/metainfo +0 -13
- data/doc/news.feed +0 -9
- data/doc/news.page +0 -29
- data/doc/options.page +0 -49
- data/doc/quickref.page +0 -603
- data/doc/sidebar.template +0 -22
- data/doc/sitemap.sitemap +0 -5
- data/doc/syntax.page +0 -1799
- data/doc/tests.page +0 -104
- data/doc/virtual +0 -14
- data/lib/kramdown/converter/math_engine/itex2mml.rb +0 -39
- data/lib/kramdown/converter/math_engine/katex.rb +0 -35
- data/lib/kramdown/converter/math_engine/mathjaxnode.rb +0 -56
- data/lib/kramdown/converter/math_engine/ritex.rb +0 -38
- data/lib/kramdown/converter/math_engine/sskatex.rb +0 -97
- data/lib/kramdown/converter/pdf.rb +0 -625
- data/lib/kramdown/converter/syntax_highlighter/coderay.rb +0 -81
- data/lib/kramdown/parser/gfm.rb +0 -188
- data/lib/kramdown/utils/ordered_hash.rb +0 -18
- data/setup.rb +0 -1585
- data/test/testcases/block/07_horizontal_rule/error.html.19 +0 -7
- data/test/testcases/block/09_html/html_to_native/typography.html.19 +0 -1
- data/test/testcases/block/09_html/simple.html.19 +0 -60
- data/test/testcases/block/15_math/itex2mml.html +0 -1
- data/test/testcases/block/15_math/itex2mml.options +0 -1
- data/test/testcases/block/15_math/itex2mml.text +0 -1
- data/test/testcases/block/15_math/katex.html.19 +0 -2
- data/test/testcases/block/15_math/katex.options +0 -1
- data/test/testcases/block/15_math/katex.text +0 -2
- data/test/testcases/block/15_math/mathjaxnode.html.19 +0 -27
- data/test/testcases/block/15_math/mathjaxnode.options +0 -1
- data/test/testcases/block/15_math/mathjaxnode.text +0 -1
- data/test/testcases/block/15_math/mathjaxnode_notexhints.html.19 +0 -23
- data/test/testcases/block/15_math/mathjaxnode_notexhints.options +0 -3
- data/test/testcases/block/15_math/mathjaxnode_notexhints.text +0 -1
- data/test/testcases/block/15_math/mathjaxnode_semantics.html.19 +0 -32
- data/test/testcases/block/15_math/mathjaxnode_semantics.options +0 -3
- data/test/testcases/block/15_math/mathjaxnode_semantics.text +0 -1
- data/test/testcases/block/15_math/ritex.html +0 -1
- data/test/testcases/block/15_math/ritex.options +0 -1
- data/test/testcases/block/15_math/ritex.text +0 -1
- data/test/testcases/block/15_math/sskatex.html.19 +0 -2
- data/test/testcases/block/15_math/sskatex.options +0 -1
- data/test/testcases/block/15_math/sskatex.text +0 -2
- data/test/testcases/span/01_link/inline.html.19 +0 -46
- data/test/testcases/span/01_link/reference.html.19 +0 -37
- data/test/testcases/span/math/itex2mml.html +0 -1
- data/test/testcases/span/math/itex2mml.options +0 -1
- data/test/testcases/span/math/itex2mml.text +0 -1
- data/test/testcases/span/math/katex.html.19 +0 -1
- data/test/testcases/span/math/katex.options +0 -1
- data/test/testcases/span/math/katex.text +0 -1
- data/test/testcases/span/math/mathjaxnode.html.19 +0 -27
- data/test/testcases/span/math/mathjaxnode.options +0 -1
- data/test/testcases/span/math/mathjaxnode.text +0 -1
- data/test/testcases/span/math/ritex.html +0 -1
- data/test/testcases/span/math/ritex.options +0 -1
- data/test/testcases/span/math/ritex.text +0 -1
- data/test/testcases/span/math/sskatex.html.19 +0 -1
- data/test/testcases/span/math/sskatex.options +0 -1
- data/test/testcases/span/math/sskatex.text +0 -1
- data/test/testcases/span/text_substitutions/entities_as_char.html.19 +0 -1
- data/test/testcases_gfm/atx_header.html +0 -3
- data/test/testcases_gfm/atx_header.text +0 -3
- data/test/testcases_gfm/backticks_disable_highlighting.html +0 -2
- data/test/testcases_gfm/backticks_disable_highlighting.options +0 -1
- data/test/testcases_gfm/backticks_disable_highlighting.text +0 -3
- data/test/testcases_gfm/backticks_syntax.html +0 -20
- data/test/testcases_gfm/backticks_syntax.text +0 -19
- data/test/testcases_gfm/codeblock_fenced.html +0 -20
- data/test/testcases_gfm/codeblock_fenced.options +0 -1
- data/test/testcases_gfm/codeblock_fenced.text +0 -21
- data/test/testcases_gfm/hard_line_breaks.html +0 -3
- data/test/testcases_gfm/hard_line_breaks.text +0 -3
- data/test/testcases_gfm/hard_line_breaks_off.html +0 -2
- data/test/testcases_gfm/hard_line_breaks_off.options +0 -1
- data/test/testcases_gfm/hard_line_breaks_off.text +0 -2
- data/test/testcases_gfm/header_ids.html +0 -27
- data/test/testcases_gfm/header_ids.html.19 +0 -27
- data/test/testcases_gfm/header_ids.options +0 -1
- data/test/testcases_gfm/header_ids.text +0 -27
- data/test/testcases_gfm/header_ids_with_prefix.html +0 -3
- data/test/testcases_gfm/header_ids_with_prefix.options +0 -2
- data/test/testcases_gfm/header_ids_with_prefix.text +0 -3
- data/test/testcases_gfm/no_typographic.html +0 -3
- data/test/testcases_gfm/no_typographic.html.19 +0 -3
- data/test/testcases_gfm/no_typographic.options +0 -1
- data/test/testcases_gfm/no_typographic.text +0 -3
- data/test/testcases_gfm/paragraph_end-disabled.html +0 -31
- data/test/testcases_gfm/paragraph_end-disabled.options +0 -1
- data/test/testcases_gfm/paragraph_end-disabled.text +0 -27
- data/test/testcases_gfm/paragraph_end.html +0 -38
- data/test/testcases_gfm/paragraph_end.text +0 -27
- data/test/testcases_gfm/strikethrough.html +0 -27
- data/test/testcases_gfm/strikethrough.html.19 +0 -27
- data/test/testcases_gfm/strikethrough.text +0 -27
- data/test/testcases_gfm/task_list.html +0 -40
- data/test/testcases_gfm/task_list.text +0 -26
- data/test/testcases_gfm/two_para_hard_line_breaks.html +0 -4
- data/test/testcases_gfm/two_para_hard_line_breaks.text +0 -4
data/lib/kramdown/parser.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
1
|
+
# -*- coding: utf-8; frozen_string_literal: true -*-
|
2
2
|
#
|
3
3
|
#--
|
4
|
-
# Copyright (C) 2009-
|
4
|
+
# Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
|
5
5
|
#
|
6
6
|
# This file is part of kramdown which is licensed under the MIT.
|
7
7
|
#++
|
@@ -20,7 +20,6 @@ module Kramdown
|
|
20
20
|
autoload :Kramdown, 'kramdown/parser/kramdown'
|
21
21
|
autoload :Html, 'kramdown/parser/html'
|
22
22
|
autoload :Markdown, 'kramdown/parser/markdown'
|
23
|
-
autoload :GFM, 'kramdown/parser/gfm'
|
24
23
|
|
25
24
|
end
|
26
25
|
|
data/lib/kramdown/parser/base.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
1
|
+
# -*- coding: utf-8; frozen_string_literal: true -*-
|
2
2
|
#
|
3
3
|
#--
|
4
|
-
# Copyright (C) 2009-
|
4
|
+
# Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
|
5
5
|
#
|
6
6
|
# This file is part of kramdown which is licensed under the MIT.
|
7
7
|
#++
|
@@ -52,8 +52,8 @@ module Kramdown
|
|
52
52
|
def initialize(source, options)
|
53
53
|
@source = source
|
54
54
|
@options = Kramdown::Options.merge(options)
|
55
|
-
@root = Element.new(:root, nil, nil, :
|
56
|
-
:
|
55
|
+
@root = Element.new(:root, nil, nil, encoding: (source.encoding rescue nil), location: 1,
|
56
|
+
options: {}, abbrev_defs: {}, abbrev_attr: {})
|
57
57
|
@warnings = []
|
58
58
|
@text_type = :text
|
59
59
|
end
|
@@ -83,7 +83,7 @@ module Kramdown
|
|
83
83
|
# Add the given warning +text+ to the warning array.
|
84
84
|
def warning(text)
|
85
85
|
@warnings << text
|
86
|
-
#TODO: add position information
|
86
|
+
# TODO: add position information
|
87
87
|
end
|
88
88
|
|
89
89
|
# Modify the string +source+ to be usable by the parser (unifies line ending characters to
|
@@ -103,7 +103,8 @@ module Kramdown
|
|
103
103
|
if last && last.type == type
|
104
104
|
last.value << text
|
105
105
|
elsif !text.empty?
|
106
|
-
|
106
|
+
location = (last && last.options[:location] || tree.options[:location])
|
107
|
+
tree.children << Element.new(type, text, nil, location: location)
|
107
108
|
end
|
108
109
|
end
|
109
110
|
|
data/lib/kramdown/parser/html.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
1
|
+
# -*- coding: utf-8; frozen_string_literal: true -*-
|
2
2
|
#
|
3
3
|
#--
|
4
|
-
# Copyright (C) 2009-
|
4
|
+
# Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
|
5
5
|
#
|
6
6
|
# This file is part of kramdown which is licensed under the MIT.
|
7
7
|
#++
|
@@ -29,36 +29,39 @@ module Kramdown
|
|
29
29
|
HTML_DOCTYPE_RE = /<!DOCTYPE.*?>/im
|
30
30
|
HTML_COMMENT_RE = /<!--(.*?)-->/m
|
31
31
|
HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m
|
32
|
-
HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})(?:\s*=\s*(
|
33
|
-
HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(
|
32
|
+
HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})(?:\s*=\s*(?:(\p{Word}+)|("|')(.*?)\3))?/m
|
33
|
+
HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(?:\p{Word}+|("|').*?\3))?)*)\s*(\/)?>/m
|
34
34
|
HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::UNAME_STR})\s*>/m
|
35
35
|
HTML_ENTITY_RE = /&([\w:][\-\w\.:]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/
|
36
36
|
|
37
|
-
HTML_CONTENT_MODEL_BLOCK = %w
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
HTML_CONTENT_MODEL_BLOCK = %w[address applet article aside blockquote body
|
38
|
+
dd details div dl fieldset figure figcaption
|
39
|
+
footer form header hgroup iframe li main
|
40
|
+
map menu nav noscript object section summary td]
|
41
|
+
HTML_CONTENT_MODEL_SPAN = %w[a abbr acronym b bdo big button cite caption del dfn dt em
|
42
|
+
h1 h2 h3 h4 h5 h6 i ins label legend optgroup p q rb rbc
|
43
|
+
rp rt rtc ruby select small span strong sub sup th tt]
|
44
|
+
HTML_CONTENT_MODEL_RAW = %w[script style math option textarea pre code kbd samp var]
|
44
45
|
# The following elements are also parsed as raw since they need child elements that cannot
|
45
46
|
# be expressed using kramdown syntax: colgroup table tbody thead tfoot tr ul ol
|
46
47
|
|
47
|
-
HTML_CONTENT_MODEL = Hash.new {|h,k| h[k] = :raw}
|
48
|
-
HTML_CONTENT_MODEL_BLOCK.each {|i| HTML_CONTENT_MODEL[i] = :block}
|
49
|
-
HTML_CONTENT_MODEL_SPAN.each {|i| HTML_CONTENT_MODEL[i] = :span}
|
50
|
-
HTML_CONTENT_MODEL_RAW.each {|i| HTML_CONTENT_MODEL[i] = :raw}
|
48
|
+
HTML_CONTENT_MODEL = Hash.new {|h, k| h[k] = :raw }
|
49
|
+
HTML_CONTENT_MODEL_BLOCK.each {|i| HTML_CONTENT_MODEL[i] = :block }
|
50
|
+
HTML_CONTENT_MODEL_SPAN.each {|i| HTML_CONTENT_MODEL[i] = :span }
|
51
|
+
HTML_CONTENT_MODEL_RAW.each {|i| HTML_CONTENT_MODEL[i] = :raw }
|
51
52
|
|
52
53
|
# Some HTML elements like script belong to both categories (i.e. are valid in block and
|
53
54
|
# span HTML) and don't appear therefore!
|
54
55
|
# script, textarea
|
55
|
-
HTML_SPAN_ELEMENTS = %w
|
56
|
-
|
57
|
-
|
58
|
-
HTML_BLOCK_ELEMENTS = %w
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
HTML_SPAN_ELEMENTS = %w[a abbr acronym b big bdo br button cite code del dfn em i img input
|
57
|
+
ins kbd label mark option q rb rbc rp rt rtc ruby samp select small
|
58
|
+
span strong sub sup tt u var]
|
59
|
+
HTML_BLOCK_ELEMENTS = %w[address article aside applet body blockquote caption col colgroup
|
60
|
+
dd div dl dt fieldset figcaption footer form h1 h2 h3 h4 h5 h6
|
61
|
+
header hgroup hr html head iframe legend menu li main map nav ol
|
62
|
+
optgroup p pre section summary table tbody td th thead tfoot tr ul]
|
63
|
+
HTML_ELEMENTS_WITHOUT_BODY = %w[area base br col command embed hr img input keygen link
|
64
|
+
meta param source track wbr]
|
62
65
|
|
63
66
|
HTML_ELEMENT = Hash.new(false)
|
64
67
|
(HTML_SPAN_ELEMENTS + HTML_BLOCK_ELEMENTS + HTML_ELEMENTS_WITHOUT_BODY +
|
@@ -67,7 +70,6 @@ module Kramdown
|
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
70
|
-
|
71
73
|
# Contains the parsing methods. This module can be mixed into any parser to get HTML parsing
|
72
74
|
# functionality. The only thing that must be provided by the class are instance variable
|
73
75
|
# @stack for storing the needed state and @src (instance of StringScanner) for the actual
|
@@ -88,7 +90,7 @@ module Kramdown
|
|
88
90
|
closed = !@src[4].nil?
|
89
91
|
attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[name])
|
90
92
|
|
91
|
-
el = Element.new(:html_element, name, attrs, :
|
93
|
+
el = Element.new(:html_element, name, attrs, category: :block)
|
92
94
|
el.options[:location] = line if line
|
93
95
|
@tree.children << el
|
94
96
|
|
@@ -110,13 +112,13 @@ module Kramdown
|
|
110
112
|
# If the optional +in_html_tag+ parameter is set to +false+, attributes are not modified to
|
111
113
|
# contain only lowercase letters.
|
112
114
|
def parse_html_attributes(str, line = nil, in_html_tag = true)
|
113
|
-
attrs =
|
114
|
-
str.scan(HTML_ATTRIBUTE_RE).each do |attr,
|
115
|
+
attrs = {}
|
116
|
+
str.scan(HTML_ATTRIBUTE_RE).each do |attr, val, _sep, quoted_val|
|
115
117
|
attr.downcase! if in_html_tag
|
116
|
-
if attrs.
|
118
|
+
if attrs.key?(attr)
|
117
119
|
warning("Duplicate HTML attribute '#{attr}' on line #{line || '?'} - overwriting previous one")
|
118
120
|
end
|
119
|
-
attrs[attr] = val || ""
|
121
|
+
attrs[attr] = val || quoted_val || ""
|
120
122
|
end
|
121
123
|
attrs
|
122
124
|
end
|
@@ -151,13 +153,13 @@ module Kramdown
|
|
151
153
|
|
152
154
|
done = false
|
153
155
|
while !@src.eos? && !done
|
154
|
-
if result = @src.scan_until(HTML_RAW_START)
|
156
|
+
if (result = @src.scan_until(HTML_RAW_START))
|
155
157
|
add_text(result, @tree, :text)
|
156
158
|
line = @src.current_line_number
|
157
|
-
if result = @src.scan(HTML_COMMENT_RE)
|
158
|
-
@tree.children << Element.new(:xml_comment, result, nil, :
|
159
|
-
elsif result = @src.scan(HTML_INSTRUCTION_RE)
|
160
|
-
@tree.children << Element.new(:xml_pi, result, nil, :
|
159
|
+
if (result = @src.scan(HTML_COMMENT_RE))
|
160
|
+
@tree.children << Element.new(:xml_comment, result, nil, category: :block, location: line)
|
161
|
+
elsif (result = @src.scan(HTML_INSTRUCTION_RE))
|
162
|
+
@tree.children << Element.new(:xml_pi, result, nil, category: :block, location: line)
|
161
163
|
elsif @src.scan(HTML_TAG_RE)
|
162
164
|
if method(:handle_html_start_tag).arity.abs >= 1
|
163
165
|
handle_html_start_tag(line, &block)
|
@@ -169,7 +171,8 @@ module Kramdown
|
|
169
171
|
done = true
|
170
172
|
else
|
171
173
|
add_text(@src.matched, @tree, :text)
|
172
|
-
warning("Found invalidly used HTML closing tag for '#{@src[1]}' on
|
174
|
+
warning("Found invalidly used HTML closing tag for '#{@src[1]}' on " \
|
175
|
+
"line #{line} - ignoring it")
|
173
176
|
end
|
174
177
|
else
|
175
178
|
add_text(@src.getch, @tree, :text)
|
@@ -177,7 +180,10 @@ module Kramdown
|
|
177
180
|
else
|
178
181
|
add_text(@src.rest, @tree, :text)
|
179
182
|
@src.terminate
|
180
|
-
|
183
|
+
if @tree.type == :html_element
|
184
|
+
warning("Found no end tag for '#{@tree.value}' on line " \
|
185
|
+
"#{@tree.options[:location]} - auto-closing it")
|
186
|
+
end
|
181
187
|
done = true
|
182
188
|
end
|
183
189
|
end
|
@@ -187,7 +193,6 @@ module Kramdown
|
|
187
193
|
|
188
194
|
end
|
189
195
|
|
190
|
-
|
191
196
|
# Converts HTML elements to native elements if possible.
|
192
197
|
class ElementConverter
|
193
198
|
|
@@ -196,14 +201,17 @@ module Kramdown
|
|
196
201
|
include Constants
|
197
202
|
include ::Kramdown::Utils::Entities
|
198
203
|
|
199
|
-
REMOVE_TEXT_CHILDREN =
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
204
|
+
REMOVE_TEXT_CHILDREN = %w[html head hgroup ol ul dl table colgroup tbody thead tfoot tr
|
205
|
+
select optgroup]
|
206
|
+
WRAP_TEXT_CHILDREN = %w[body section nav article aside header footer address div li dd
|
207
|
+
blockquote figure figcaption fieldset form]
|
208
|
+
REMOVE_WHITESPACE_CHILDREN = %w[body section nav article aside header footer address
|
209
|
+
div li dd blockquote figure figcaption td th fieldset form]
|
210
|
+
STRIP_WHITESPACE = %w[address article aside blockquote body caption dd div dl dt fieldset
|
211
|
+
figcaption form footer header h1 h2 h3 h4 h5 h6 legend li nav p
|
212
|
+
section td th]
|
213
|
+
SIMPLE_ELEMENTS = %w[em strong blockquote hr br img p thead tbody tfoot tr td th ul ol dl
|
214
|
+
li dl dt dd]
|
207
215
|
|
208
216
|
def initialize(root)
|
209
217
|
@root = root
|
@@ -228,11 +236,11 @@ module Kramdown
|
|
228
236
|
else parent.type.to_s
|
229
237
|
end
|
230
238
|
end
|
231
|
-
el.options.replace(
|
239
|
+
el.options.replace(category: (HTML_CONTENT_MODEL[ptype] == :span ? :span : :block))
|
232
240
|
return
|
233
241
|
when :html_element
|
234
242
|
when :root
|
235
|
-
el.children.each {|c| process(c)}
|
243
|
+
el.children.each {|c| process(c) }
|
236
244
|
remove_whitespace_children(el)
|
237
245
|
return
|
238
246
|
else return
|
@@ -277,18 +285,18 @@ module Kramdown
|
|
277
285
|
raw.gsub!(/\s+/, ' ') unless preserve
|
278
286
|
src = Kramdown::Utils::StringScanner.new(raw)
|
279
287
|
result = []
|
280
|
-
|
281
|
-
if tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/)
|
288
|
+
until src.eos?
|
289
|
+
if (tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/))
|
282
290
|
result << Element.new(:text, tmp)
|
283
291
|
src.scan(HTML_ENTITY_RE)
|
284
|
-
val = src[1] || (src[2]
|
285
|
-
result << if %w
|
292
|
+
val = src[1] || (src[2]&.to_i) || src[3].hex
|
293
|
+
result << if %w[lsquo rsquo ldquo rdquo].include?(val)
|
286
294
|
Element.new(:smart_quote, val.intern)
|
287
|
-
elsif %w
|
295
|
+
elsif %w[mdash ndash hellip laquo raquo].include?(val)
|
288
296
|
Element.new(:typographic_sym, val.intern)
|
289
297
|
else
|
290
298
|
begin
|
291
|
-
Element.new(:entity, entity(val), nil, :
|
299
|
+
Element.new(:entity, entity(val), nil, original: src.matched)
|
292
300
|
rescue ::Kramdown::Error
|
293
301
|
src.pos -= src.matched_size - 1
|
294
302
|
Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'))
|
@@ -303,13 +311,13 @@ module Kramdown
|
|
303
311
|
end
|
304
312
|
|
305
313
|
def process_html_element(el, do_conversion = true, preserve_text = false)
|
306
|
-
el.options.replace(:
|
307
|
-
:
|
314
|
+
el.options.replace(category: HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block,
|
315
|
+
content_model: (do_conversion ? HTML_CONTENT_MODEL[el.value] : :raw))
|
308
316
|
process_children(el, do_conversion, preserve_text)
|
309
317
|
end
|
310
318
|
|
311
319
|
def remove_text_children(el)
|
312
|
-
el.children.delete_if {|c| c.type == :text}
|
320
|
+
el.children.delete_if {|c| c.type == :text }
|
313
321
|
end
|
314
322
|
|
315
323
|
def wrap_text_children(el)
|
@@ -317,8 +325,8 @@ module Kramdown
|
|
317
325
|
last_is_p = false
|
318
326
|
el.children.each do |c|
|
319
327
|
if Element.category(c) != :block || c.type == :text
|
320
|
-
|
321
|
-
tmp << Element.new(:p, nil, nil, :
|
328
|
+
unless last_is_p
|
329
|
+
tmp << Element.new(:p, nil, nil, transparent: true)
|
322
330
|
last_is_p = true
|
323
331
|
end
|
324
332
|
tmp.last.children << c
|
@@ -346,8 +354,8 @@ module Kramdown
|
|
346
354
|
el.children = el.children.reject do |c|
|
347
355
|
i += 1
|
348
356
|
c.type == :text && c.value.strip.empty? &&
|
349
|
-
(i == 0 || i == el.children.length - 1 || (Element.category(el.children[i-1]) == :block &&
|
350
|
-
Element.category(el.children[i+1]) == :block))
|
357
|
+
(i == 0 || i == el.children.length - 1 || (Element.category(el.children[i - 1]) == :block &&
|
358
|
+
Element.category(el.children[i + 1]) == :block))
|
351
359
|
end
|
352
360
|
end
|
353
361
|
|
@@ -359,7 +367,7 @@ module Kramdown
|
|
359
367
|
|
360
368
|
def extract_text(el, raw)
|
361
369
|
raw << el.value.to_s if el.type == :text
|
362
|
-
el.children.each {|c| extract_text(c, raw)}
|
370
|
+
el.children.each {|c| extract_text(c, raw) }
|
363
371
|
end
|
364
372
|
|
365
373
|
def convert_textarea(el)
|
@@ -377,7 +385,7 @@ module Kramdown
|
|
377
385
|
|
378
386
|
EMPHASIS_TYPE_MAP = {'em' => :em, 'i' => :em, 'strong' => :strong, 'b' => :strong}
|
379
387
|
def convert_em(el)
|
380
|
-
text = ''
|
388
|
+
text = +''
|
381
389
|
extract_text(el, text)
|
382
390
|
if text =~ /\A\s/ || text =~ /\s\z/
|
383
391
|
process_html_element(el, false)
|
@@ -386,33 +394,33 @@ module Kramdown
|
|
386
394
|
process_children(el)
|
387
395
|
end
|
388
396
|
end
|
389
|
-
%w
|
397
|
+
%w[b strong i].each do |i|
|
390
398
|
alias_method("convert_#{i}".to_sym, :convert_em)
|
391
399
|
end
|
392
400
|
|
393
401
|
def convert_h1(el)
|
394
|
-
set_basics(el, :header, :
|
395
|
-
extract_text(el, el.options[:raw_text] = '')
|
402
|
+
set_basics(el, :header, level: el.value[1..1].to_i)
|
403
|
+
extract_text(el, el.options[:raw_text] = +'')
|
396
404
|
process_children(el)
|
397
405
|
end
|
398
|
-
%w
|
406
|
+
%w[h2 h3 h4 h5 h6].each do |i|
|
399
407
|
alias_method("convert_#{i}".to_sym, :convert_h1)
|
400
408
|
end
|
401
409
|
|
402
410
|
def convert_code(el)
|
403
|
-
raw = ''
|
411
|
+
raw = +''
|
404
412
|
extract_text(el, raw)
|
405
413
|
result = process_text(raw, true)
|
406
414
|
begin
|
407
|
-
str = result.inject('') do |mem, c|
|
415
|
+
str = result.inject(+'') do |mem, c|
|
408
416
|
if c.type == :text
|
409
417
|
mem << c.value
|
410
418
|
elsif c.type == :entity
|
411
|
-
if [60, 62, 34, 38].include?(c.value.code_point)
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
419
|
+
mem << if [60, 62, 34, 38].include?(c.value.code_point)
|
420
|
+
c.value.code_point.chr
|
421
|
+
else
|
422
|
+
c.value.char
|
423
|
+
end
|
416
424
|
elsif c.type == :smart_quote || c.type == :typographic_sym
|
417
425
|
mem << entity(c.value.to_s).char
|
418
426
|
else
|
@@ -421,14 +429,14 @@ module Kramdown
|
|
421
429
|
end
|
422
430
|
result.clear
|
423
431
|
result << Element.new(:text, str)
|
424
|
-
rescue
|
432
|
+
rescue StandardError
|
425
433
|
end
|
426
434
|
if result.length > 1 || result.first.type != :text
|
427
435
|
process_html_element(el, false, true)
|
428
436
|
else
|
429
437
|
if el.value == 'code'
|
430
438
|
set_basics(el, :codespan)
|
431
|
-
el.attr['class']
|
439
|
+
el.attr['class']&.gsub!(/\s+\bhighlighter-\w+\b|\bhighlighter-\w+\b\s*/, '')
|
432
440
|
else
|
433
441
|
set_basics(el, :codeblock)
|
434
442
|
if el.children.size == 1 && el.children.first.value == 'code'
|
@@ -440,10 +448,10 @@ module Kramdown
|
|
440
448
|
el.children.clear
|
441
449
|
end
|
442
450
|
end
|
443
|
-
alias
|
451
|
+
alias convert_pre convert_code
|
444
452
|
|
445
453
|
def convert_table(el)
|
446
|
-
|
454
|
+
unless is_simple_table?(el)
|
447
455
|
process_html_element(el, false)
|
448
456
|
return
|
449
457
|
end
|
@@ -463,17 +471,17 @@ module Kramdown
|
|
463
471
|
end
|
464
472
|
end
|
465
473
|
else
|
466
|
-
c.children.each {|cc| calc_alignment.call(cc)}
|
474
|
+
c.children.each {|cc| calc_alignment.call(cc) }
|
467
475
|
end
|
468
476
|
end
|
469
477
|
calc_alignment.call(el)
|
470
|
-
el.children.delete_if {|c| c.type == :html_element}
|
478
|
+
el.children.delete_if {|c| c.type == :html_element }
|
471
479
|
|
472
480
|
change_th_type = lambda do |c|
|
473
481
|
if c.type == :th
|
474
482
|
c.type = :td
|
475
483
|
else
|
476
|
-
c.children.each {|cc| change_th_type.call(cc)}
|
484
|
+
c.children.each {|cc| change_th_type.call(cc) }
|
477
485
|
end
|
478
486
|
end
|
479
487
|
change_th_type.call(el)
|
@@ -491,11 +499,11 @@ module Kramdown
|
|
491
499
|
(cc.type == :text || !HTML_BLOCK_ELEMENTS.include?(cc.value)) && only_phrasing_content.call(cc)
|
492
500
|
end
|
493
501
|
end
|
494
|
-
check_cells =
|
502
|
+
check_cells = proc do |c|
|
495
503
|
if c.value == 'th' || c.value == 'td'
|
496
|
-
return false
|
504
|
+
return false unless only_phrasing_content.call(c)
|
497
505
|
else
|
498
|
-
c.children.each {|cc| check_cells.call(cc)}
|
506
|
+
c.children.each {|cc| check_cells.call(cc) }
|
499
507
|
end
|
500
508
|
end
|
501
509
|
check_cells.call(el)
|
@@ -503,7 +511,7 @@ module Kramdown
|
|
503
511
|
nr_cells = 0
|
504
512
|
check_nr_cells = lambda do |t|
|
505
513
|
if t.value == 'tr'
|
506
|
-
count = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.length
|
514
|
+
count = t.children.select {|cc| cc.value == 'th' || cc.value == 'td' }.length
|
507
515
|
if count != nr_cells
|
508
516
|
if nr_cells == 0
|
509
517
|
nr_cells = count
|
@@ -513,16 +521,16 @@ module Kramdown
|
|
513
521
|
end
|
514
522
|
end
|
515
523
|
else
|
516
|
-
t.children.each {|cc| check_nr_cells.call(cc)}
|
524
|
+
t.children.each {|cc| check_nr_cells.call(cc) }
|
517
525
|
end
|
518
526
|
end
|
519
527
|
check_nr_cells.call(el)
|
520
528
|
return false if nr_cells == -1
|
521
529
|
|
522
530
|
alignment = nil
|
523
|
-
check_alignment =
|
531
|
+
check_alignment = proc do |t|
|
524
532
|
if t.value == 'tr'
|
525
|
-
cur_alignment = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.map do |cell|
|
533
|
+
cur_alignment = t.children.select {|cc| cc.value == 'th' || cc.value == 'td' }.map do |cell|
|
526
534
|
md = /text-align:\s+(center|left|right|justify|inherit)/.match(cell.attr['style'].to_s)
|
527
535
|
return false if md && (md[1] == 'justify' || md[1] == 'inherit')
|
528
536
|
md.nil? ? :default : md[1]
|
@@ -530,19 +538,19 @@ module Kramdown
|
|
530
538
|
alignment = cur_alignment if alignment.nil?
|
531
539
|
return false if alignment != cur_alignment
|
532
540
|
else
|
533
|
-
t.children.each {|cc| check_alignment.call(cc)}
|
541
|
+
t.children.each {|cc| check_alignment.call(cc) }
|
534
542
|
end
|
535
543
|
end
|
536
544
|
check_alignment.call(el)
|
537
545
|
|
538
546
|
check_rows = lambda do |t, type|
|
539
|
-
t.children.all? {|r| (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text}}
|
547
|
+
t.children.all? {|r| (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text }}
|
540
548
|
end
|
541
549
|
check_rows.call(el, 'td') ||
|
542
550
|
(el.children.all? do |t|
|
543
551
|
t.type == :text || (t.value == 'thead' && check_rows.call(t, 'th')) ||
|
544
552
|
((t.value == 'tfoot' || t.value == 'tbody') && check_rows.call(t, 'td'))
|
545
|
-
end && el.children.any? {|t| t.value == 'tbody'})
|
553
|
+
end && el.children.any? {|t| t.value == 'tbody' })
|
546
554
|
end
|
547
555
|
|
548
556
|
def convert_script(el)
|
@@ -558,7 +566,7 @@ module Kramdown
|
|
558
566
|
end
|
559
567
|
|
560
568
|
def handle_math_tag(el)
|
561
|
-
set_basics(el, :math, :
|
569
|
+
set_basics(el, :math, category: (el.attr['type'] =~ /mode=display/ ? :block : :span))
|
562
570
|
el.value = el.children.shift.value.sub(/\A(?:%\s*)?<!\[CDATA\[\n?(.*?)(?:\s%)?\]\]>\z/m, '\1')
|
563
571
|
el.attr.delete('type')
|
564
572
|
end
|
@@ -573,12 +581,12 @@ module Kramdown
|
|
573
581
|
@src = Kramdown::Utils::StringScanner.new(adapt_source(source))
|
574
582
|
|
575
583
|
while true
|
576
|
-
if result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/)
|
577
|
-
@tree.children << Element.new(:xml_pi, result.strip, nil, :
|
578
|
-
elsif result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/)
|
584
|
+
if (result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/))
|
585
|
+
@tree.children << Element.new(:xml_pi, result.strip, nil, category: :block)
|
586
|
+
elsif (result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/))
|
579
587
|
# ignore the doctype
|
580
|
-
elsif result = @src.scan(/\s*#{HTML_COMMENT_RE}/)
|
581
|
-
@tree.children << Element.new(:xml_comment, result.strip, nil, :
|
588
|
+
elsif (result = @src.scan(/\s*#{HTML_COMMENT_RE}/))
|
589
|
+
@tree.children << Element.new(:xml_comment, result.strip, nil, category: :block)
|
582
590
|
else
|
583
591
|
break
|
584
592
|
end
|