kramdown 2.2.1 → 2.3.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.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +3 -1
- data/VERSION +1 -1
- data/lib/kramdown/converter/html.rb +5 -7
- data/lib/kramdown/converter/kramdown.rb +2 -2
- data/lib/kramdown/converter/latex.rb +1 -1
- data/lib/kramdown/converter/syntax_highlighter/rouge.rb +16 -8
- data/lib/kramdown/element.rb +8 -0
- data/lib/kramdown/options.rb +10 -0
- data/lib/kramdown/parser/kramdown/extensions.rb +6 -0
- data/lib/kramdown/parser/kramdown/header.rb +2 -1
- data/lib/kramdown/parser/kramdown/html.rb +2 -8
- data/lib/kramdown/utils/html.rb +2 -0
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +7 -0
- data/test/test_files.rb +1 -0
- data/test/test_location.rb +2 -2
- data/test/test_string_scanner_kramdown.rb +1 -1
- data/test/testcases/block/09_html/processing_instruction.html +5 -6
- data/test/testcases/block/12_extension/options.text +2 -0
- data/test/testcases/span/05_html/normal.html +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a893196013756c877e4baa3d62eb2d3b862684748ed4f329a9723779e30bbeb
|
4
|
+
data.tar.gz: abfac14092805a87a5bdb0c7210ddb157b35a22391a8393a8401fdc547d2f902
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fdb47e22271964a0a5caef5dc9054a6a5d50cfd81c01665ddfe9aa8e66539ce97125019bea46700ff54227602ce45fd3af98bd48824fe3460aefd6ce6ec3828
|
7
|
+
data.tar.gz: 9927a0d0fe778ac799dcd499727623c7bb35cc2a46a5745042c88d65685502d7bc04384c265155af214f046a2a27f72cf4b73b2d3ddba6a987de85939b6cfe56
|
data/CONTRIBUTERS
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Count Name
|
2
2
|
======= ====
|
3
|
-
|
3
|
+
943 Thomas Leitner <t_leitner@gmx.at>
|
4
4
|
18 Ashwin Maroli <ashmaroli@gmail.com>
|
5
5
|
7 Christian Cornelssen <ccorn@1tein.de>
|
6
6
|
6 Gioele Barabucci <gioele@svario.it>
|
@@ -13,6 +13,7 @@
|
|
13
13
|
3 gettalong <t_leitner@gmx.at>
|
14
14
|
3 Brandur <brandur@mutelight.org>
|
15
15
|
3 Ben Armston <ben.armston@googlemail.com>
|
16
|
+
3 Ashwin Maroli <ashmaroli@users.noreply.github.com>
|
16
17
|
3 Alex Marandon <contact@alexmarandon.com>
|
17
18
|
2 Tom Thorogood <me+github@tomthorogood.co.uk>
|
18
19
|
2 Parker Moore <parkrmoore@gmail.com>
|
@@ -40,6 +41,7 @@
|
|
40
41
|
1 scherr <maximilianscherr@gmail.com>
|
41
42
|
1 Postmodern <postmodern.mod3@gmail.com>
|
42
43
|
1 Pete Michaud <michaudp@gmail.com>
|
44
|
+
1 Noah Doersing <doersino@gmail.com>
|
43
45
|
1 myqlarson <myqlarson@gmail.com>
|
44
46
|
1 milo.simpson <milo.simpson@bazaarvoice.com>
|
45
47
|
1 Michal Till <michal.till@gmail.com>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
@@ -49,15 +49,13 @@ module Kramdown
|
|
49
49
|
|
50
50
|
# stash string representation of symbol to avoid allocations from multiple interpolations.
|
51
51
|
@highlighter_class = " highlighter-#{options[:syntax_highlighter]}"
|
52
|
+
@dispatcher = Hash.new {|h, k| h[k] = :"convert_#{k}" }
|
52
53
|
end
|
53
54
|
|
54
|
-
# The mapping of element type to conversion method.
|
55
|
-
DISPATCHER = Hash.new {|h, k| h[k] = "convert_#{k}" }
|
56
|
-
|
57
55
|
# Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of
|
58
56
|
# the element.
|
59
57
|
def convert(el, indent = -@indent)
|
60
|
-
send(
|
58
|
+
send(@dispatcher[el.type], el, indent)
|
61
59
|
end
|
62
60
|
|
63
61
|
# Return the converted content of the children of +el+ as a string. The parameter +indent+ has
|
@@ -70,7 +68,7 @@ module Kramdown
|
|
70
68
|
indent += @indent
|
71
69
|
@stack.push(el)
|
72
70
|
el.children.each do |inner_el|
|
73
|
-
result << send(
|
71
|
+
result << send(@dispatcher[inner_el.type], inner_el, indent)
|
74
72
|
end
|
75
73
|
@stack.pop
|
76
74
|
result
|
@@ -160,10 +158,10 @@ module Kramdown
|
|
160
158
|
private_constant :ZERO_TO_ONETWENTYEIGHT
|
161
159
|
|
162
160
|
def convert_ul(el, indent)
|
163
|
-
if !@toc_code &&
|
161
|
+
if !@toc_code && el.options.dig(:ial, :refs)&.include?('toc')
|
164
162
|
@toc_code = [el.type, el.attr, ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join]
|
165
163
|
@toc_code.last
|
166
|
-
elsif !@footnote_location && el.options
|
164
|
+
elsif !@footnote_location && el.options.dig(:ial, :refs)&.include?('footnotes')
|
167
165
|
@footnote_location = ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join
|
168
166
|
else
|
169
167
|
format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
|
@@ -426,9 +426,9 @@ module Kramdown
|
|
426
426
|
end
|
427
427
|
end.compact.join('')
|
428
428
|
res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
429
|
-
|
429
|
+
el.options.dig(:ial, :refs)&.include?('toc')
|
430
430
|
res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
431
|
-
|
431
|
+
el.options.dig(:ial, :refs)&.include?('footnotes')
|
432
432
|
if el.type == :dl && el.options[:ial] && el.options[:ial][:refs]
|
433
433
|
auto_ids = el.options[:ial][:refs].select {|ref| ref.start_with?('auto_ids') }.join(" ")
|
434
434
|
res = auto_ids << (res.strip.empty? ? '' : " #{res}") unless auto_ids.empty?
|
@@ -127,7 +127,7 @@ module Kramdown
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def convert_ul(el, opts)
|
130
|
-
if !@data[:has_toc] &&
|
130
|
+
if !@data[:has_toc] && el.options.dig(:ial, :refs)&.include?('toc')
|
131
131
|
@data[:has_toc] = true
|
132
132
|
'\tableofcontents'
|
133
133
|
else
|
@@ -45,18 +45,26 @@ module Kramdown::Converter::SyntaxHighlighter
|
|
45
45
|
cache = converter.data[:syntax_highlighter_rouge] = {}
|
46
46
|
|
47
47
|
opts = converter.options[:syntax_highlighter_opts].dup
|
48
|
-
span_opts = (opts.delete(:span) || {}).dup
|
49
|
-
block_opts = (opts.delete(:block) || {}).dup
|
50
|
-
[span_opts, block_opts].each do |hash|
|
51
|
-
hash.keys.each do |k|
|
52
|
-
hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k)
|
53
|
-
end
|
54
|
-
end
|
55
48
|
|
56
|
-
|
49
|
+
span_opts = opts.delete(:span)&.dup || {}
|
50
|
+
block_opts = opts.delete(:block)&.dup || {}
|
51
|
+
normalize_keys(span_opts)
|
52
|
+
normalize_keys(block_opts)
|
53
|
+
|
54
|
+
cache[:span] = opts.merge(span_opts)
|
55
|
+
cache[:span][:wrap] = false
|
56
|
+
|
57
57
|
cache[:block] = opts.merge(block_opts)
|
58
58
|
end
|
59
59
|
|
60
|
+
def self.normalize_keys(hash)
|
61
|
+
return if hash.empty?
|
62
|
+
|
63
|
+
hash.keys.each do |k|
|
64
|
+
hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
60
68
|
def self.formatter_class(opts = {})
|
61
69
|
case formatter = opts[:formatter]
|
62
70
|
when Class
|
data/lib/kramdown/element.rb
CHANGED
@@ -14,6 +14,14 @@ module Kramdown
|
|
14
14
|
# kramdown only uses this one class for representing all available elements in an element tree
|
15
15
|
# (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor.
|
16
16
|
#
|
17
|
+
# The root of a kramdown element tree has to be an element of type :root. It needs to have certain
|
18
|
+
# option keys set so that conversions work correctly. If only a part of a tree should be
|
19
|
+
# converted, duplicate the root node and assign the #children appropriately, e.g:
|
20
|
+
#
|
21
|
+
# root = doc.root
|
22
|
+
# new_root = root.dup
|
23
|
+
# new_root.children = [root.children[0]] # assign new array with elements to convert
|
24
|
+
#
|
17
25
|
# Following is a description of all supported element types.
|
18
26
|
#
|
19
27
|
# Note that the option :location may contain the start line number of an element in the source
|
data/lib/kramdown/options.rb
CHANGED
@@ -589,6 +589,16 @@ module Kramdown
|
|
589
589
|
Used by: HTML converter
|
590
590
|
EOF
|
591
591
|
|
592
|
+
define(:forbidden_inline_options, Object, %w[template], <<~EOF) do |val|
|
593
|
+
Defines the options that may not be set using the {::options} extension
|
594
|
+
|
595
|
+
Default: template
|
596
|
+
Used by: HTML converter
|
597
|
+
EOF
|
598
|
+
val.map! {|item| item.kind_of?(String) ? str_to_sym(item) : item }
|
599
|
+
simple_array_validator(val, :forbidden_inline_options)
|
600
|
+
end
|
601
|
+
|
592
602
|
end
|
593
603
|
|
594
604
|
end
|
@@ -110,6 +110,12 @@ module Kramdown
|
|
110
110
|
opts.select do |k, v|
|
111
111
|
k = k.to_sym
|
112
112
|
if Kramdown::Options.defined?(k)
|
113
|
+
if @options[:forbidden_inline_options].include?(k) ||
|
114
|
+
k == :forbidden_inline_options
|
115
|
+
warning("Option #{k} may not be set inline")
|
116
|
+
next false
|
117
|
+
end
|
118
|
+
|
113
119
|
begin
|
114
120
|
val = Kramdown::Options.parse(k, v)
|
115
121
|
@options[k] = val
|
@@ -8,6 +8,7 @@
|
|
8
8
|
#
|
9
9
|
|
10
10
|
require 'kramdown/parser/kramdown/block_boundary'
|
11
|
+
require 'rexml/xmltokens'
|
11
12
|
|
12
13
|
module Kramdown
|
13
14
|
module Parser
|
@@ -40,7 +41,7 @@ module Kramdown
|
|
40
41
|
|
41
42
|
protected
|
42
43
|
|
43
|
-
HEADER_ID = /[\t ]{#(?<id
|
44
|
+
HEADER_ID = /[\t ]{#(?<id>#{REXML::XMLTokens::NAME_START_CHAR}#{REXML::XMLTokens::NAME_CHAR}*)}\z/
|
44
45
|
|
45
46
|
# Returns header text and optional ID.
|
46
47
|
def parse_header_contents
|
@@ -65,7 +65,7 @@ module Kramdown
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}
|
68
|
+
HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}|!--|\/)/
|
69
69
|
|
70
70
|
# Parse the HTML at the current position as block-level HTML.
|
71
71
|
def parse_block_html
|
@@ -74,10 +74,6 @@ module Kramdown
|
|
74
74
|
@tree.children << Element.new(:xml_comment, result, nil, category: :block, location: line)
|
75
75
|
@src.scan(TRAILING_WHITESPACE)
|
76
76
|
true
|
77
|
-
elsif (result = @src.scan(HTML_INSTRUCTION_RE))
|
78
|
-
@tree.children << Element.new(:xml_pi, result, nil, category: :block, location: line)
|
79
|
-
@src.scan(TRAILING_WHITESPACE)
|
80
|
-
true
|
81
77
|
else
|
82
78
|
if @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/o) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase)
|
83
79
|
@src.pos += @src.matched_size
|
@@ -100,15 +96,13 @@ module Kramdown
|
|
100
96
|
end
|
101
97
|
define_parser(:block_html, HTML_BLOCK_START)
|
102
98
|
|
103
|
-
HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}
|
99
|
+
HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}|!--|\/)/
|
104
100
|
|
105
101
|
# Parse the HTML at the current position as span-level HTML.
|
106
102
|
def parse_span_html
|
107
103
|
line = @src.current_line_number
|
108
104
|
if (result = @src.scan(HTML_COMMENT_RE))
|
109
105
|
@tree.children << Element.new(:xml_comment, result, nil, category: :span, location: line)
|
110
|
-
elsif (result = @src.scan(HTML_INSTRUCTION_RE))
|
111
|
-
@tree.children << Element.new(:xml_pi, result, nil, category: :span, location: line)
|
112
106
|
elsif (result = @src.scan(HTML_TAG_CLOSE_RE))
|
113
107
|
warning("Found invalidly used HTML closing tag for '#{@src[1]}' on line #{line}")
|
114
108
|
add_text(result)
|
data/lib/kramdown/utils/html.rb
CHANGED
@@ -42,6 +42,8 @@ module Kramdown
|
|
42
42
|
|
43
43
|
# Return the HTML representation of the attributes +attr+.
|
44
44
|
def html_attributes(attr)
|
45
|
+
return '' if attr.empty?
|
46
|
+
|
45
47
|
attr.map do |k, v|
|
46
48
|
v.nil? || (k == 'id' && v.strip.empty?) ? '' : " #{k}=\"#{escape_html(v.to_s, :attribute)}\""
|
47
49
|
end.join('')
|
data/lib/kramdown/version.rb
CHANGED
data/man/man1/kramdown.1
CHANGED
@@ -118,6 +118,13 @@ This option can be used to set a prefix for footnote IDs\. This is useful when r
|
|
118
118
|
Default: \[u2018]\[u2019] Used by: HTML
|
119
119
|
.RE
|
120
120
|
.TP
|
121
|
+
\fB\-\-forbidden\-inline\-options\fP \fIARG\fP
|
122
|
+
Defines the options that may not be set using the {::options} extension
|
123
|
+
.RS
|
124
|
+
.P
|
125
|
+
Default: template Used by: HTML converter
|
126
|
+
.RE
|
127
|
+
.TP
|
121
128
|
\fB\-\-header\-offset\fP \fIARG\fP
|
122
129
|
Sets the output offset for headers
|
123
130
|
.RS
|
data/test/test_files.rb
CHANGED
@@ -231,6 +231,7 @@ class TestFiles < Minitest::Test
|
|
231
231
|
'test/testcases/block/15_math/gh_128.html', # bc of mathjax and HTML parser
|
232
232
|
'test/testcases/span/04_footnote/backlink_inline.html', # bc of mathjax
|
233
233
|
'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image
|
234
|
+
'test/testcases/block/09_html/processing_instruction.html', # bc of PI
|
234
235
|
].compact
|
235
236
|
Dir[File.dirname(__FILE__) + '/testcases/**/*.html'].each do |html_file|
|
236
237
|
next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}$/ }
|
data/test/test_location.rb
CHANGED
@@ -18,7 +18,7 @@ describe 'location' do
|
|
18
18
|
def check_element_for_location(element)
|
19
19
|
if (match = /^line-(\d+)/.match(element.attr['class'] || ''))
|
20
20
|
expected_line = match[1].to_i
|
21
|
-
element.options[:location]
|
21
|
+
assert_equal(expected_line, element.options[:location])
|
22
22
|
end
|
23
23
|
element.children.each do |child|
|
24
24
|
check_element_for_location(child)
|
@@ -187,7 +187,7 @@ describe 'location' do
|
|
187
187
|
*[duplicate]: The second definition
|
188
188
|
)
|
189
189
|
doc = Kramdown::Document.new(test_string.strip)
|
190
|
-
|
190
|
+
assert_equal(["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"], doc.warnings)
|
191
191
|
end
|
192
192
|
|
193
193
|
it 'handles abbreviations' do
|
@@ -21,7 +21,7 @@ describe Kramdown::Utils::StringScanner do
|
|
21
21
|
it "computes the correct current_line_number for example ##{i + 1}" do
|
22
22
|
str_sc = Kramdown::Utils::StringScanner.new(test_string)
|
23
23
|
scan_regexes.each {|scan_re| str_sc.scan_until(scan_re) }
|
24
|
-
str_sc.current_line_number
|
24
|
+
assert_equal(expect, str_sc.current_line_number)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
|
1
|
+
<p><?xml version=”1.0”?></p>
|
2
2
|
|
3
3
|
<p>para</p>
|
4
4
|
|
5
|
-
|
6
|
-
<p>para</p>
|
5
|
+
<p><? test ?> para</p>
|
7
6
|
|
8
7
|
<p>other</p>
|
9
8
|
|
10
|
-
|
11
|
-
multiline
|
9
|
+
<p><?
|
10
|
+
multiline <em>text</em>
|
12
11
|
is allowed
|
13
|
-
|
12
|
+
?></p>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kramdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Leitner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rexml
|