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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a71580a92ad22dcb405e134d54fd2bf8dc9256574211e85e637ad018aa962160
4
- data.tar.gz: 3071848d3d1967ff4682373cfd2824f142354759a23bb386ade7f341ddacfb63
3
+ metadata.gz: 2a893196013756c877e4baa3d62eb2d3b862684748ed4f329a9723779e30bbeb
4
+ data.tar.gz: abfac14092805a87a5bdb0c7210ddb157b35a22391a8393a8401fdc547d2f902
5
5
  SHA512:
6
- metadata.gz: 11c7cf78f53700f9b2a7ece59eb9cf105ecd14e646bcfa47c24aa5b676deaec991479ef3ffd91139799ee97903b3deefd98da6963a58ac32a05bb9e9a0636e95
7
- data.tar.gz: c1a3635873ee7cc6a0274734c6bc558fb4043bf3987943043c3a58ec836f4b1487a27f6129729a1662127af73293721cb5af1df79aefacc49983a0d5a3e535d8
6
+ metadata.gz: 2fdb47e22271964a0a5caef5dc9054a6a5d50cfd81c01665ddfe9aa8e66539ce97125019bea46700ff54227602ce45fd3af98bd48824fe3460aefd6ce6ec3828
7
+ data.tar.gz: 9927a0d0fe778ac799dcd499727623c7bb35cc2a46a5745042c88d65685502d7bc04384c265155af214f046a2a27f72cf4b73b2d3ddba6a987de85939b6cfe56
@@ -1,6 +1,6 @@
1
1
  Count Name
2
2
  ======= ====
3
- 932 Thomas Leitner <t_leitner@gmx.at>
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.2.1
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(DISPATCHER[el.type], el, indent)
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(DISPATCHER[inner_el.type], inner_el, indent)
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 && (el.options[:ial][:refs].include?('toc') rescue nil)
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[:ial] && (el.options[:ial][:refs] || []).include?('footnotes')
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
- (el.options[:ial][:refs].include?('toc') rescue nil)
429
+ el.options.dig(:ial, :refs)&.include?('toc')
430
430
  res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
431
- (el.options[:ial][:refs].include?('footnotes') rescue nil)
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] && (el.options[:ial][:refs].include?('toc') rescue nil)
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
- cache[:span] = opts.merge(span_opts).update(wrap: false)
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
@@ -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
@@ -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>[A-Za-z][\w:-]*)}\z/
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)
@@ -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('')
@@ -10,6 +10,6 @@
10
10
  module Kramdown
11
11
 
12
12
  # The kramdown version.
13
- VERSION = '2.2.1'
13
+ VERSION = '2.3.0'
14
14
 
15
15
  end
@@ -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
@@ -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}$/ }
@@ -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].must_equal(expected_line)
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
- doc.warnings.must_equal ["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"]
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.must_equal expect
24
+ assert_equal(expect, str_sc.current_line_number)
25
25
  end
26
26
  end
27
27
  end
@@ -1,13 +1,12 @@
1
- <?xml version="1.0"?>
1
+ <p>&lt;?xml version=”1.0”?&gt;</p>
2
2
 
3
3
  <p>para</p>
4
4
 
5
- <? test ?>
6
- <p>para</p>
5
+ <p>&lt;? test ?&gt; para</p>
7
6
 
8
7
  <p>other</p>
9
8
 
10
- <?
11
- multiline *text*
9
+ <p>&lt;?
10
+ multiline <em>text</em>
12
11
  is allowed
13
- ?>
12
+ ?&gt;</p>
@@ -19,3 +19,5 @@ some *para*
19
19
  Some text[^ab].
20
20
 
21
21
  [^ab]: Some text.
22
+
23
+ {::options template="/etc/passwd" /}
@@ -2,7 +2,7 @@
2
2
 
3
3
  <p><a href="test">title</a> is a title.</p>
4
4
 
5
- <p>This is <? a PI ?>.</p>
5
+ <p>This is &lt;? a PI ?&gt;.</p>
6
6
 
7
7
  <p>This is <!-- a --> comment.</p>
8
8
 
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.2.1
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-04-23 00:00:00.000000000 Z
11
+ date: 2020-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rexml