kramdown 2.2.1 → 2.3.2

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTERS +9 -1
  3. data/README.md +8 -2
  4. data/VERSION +1 -1
  5. data/lib/kramdown/converter/html.rb +15 -15
  6. data/lib/kramdown/converter/kramdown.rb +3 -3
  7. data/lib/kramdown/converter/latex.rb +2 -2
  8. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +17 -9
  9. data/lib/kramdown/element.rb +8 -0
  10. data/lib/kramdown/options.rb +20 -4
  11. data/lib/kramdown/parser/html.rb +8 -1
  12. data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -1
  13. data/lib/kramdown/parser/kramdown/codespan.rb +6 -2
  14. data/lib/kramdown/parser/kramdown/extensions.rb +6 -0
  15. data/lib/kramdown/parser/kramdown/header.rb +2 -1
  16. data/lib/kramdown/parser/kramdown/html.rb +2 -8
  17. data/lib/kramdown/parser/kramdown/list.rb +1 -0
  18. data/lib/kramdown/utils/html.rb +2 -0
  19. data/lib/kramdown/version.rb +1 -1
  20. data/man/man1/kramdown.1 +9 -0
  21. data/test/test_files.rb +13 -7
  22. data/test/test_location.rb +2 -2
  23. data/test/test_string_scanner_kramdown.rb +1 -1
  24. data/test/testcases/block/03_paragraph/standalone_image.html +5 -0
  25. data/test/testcases/block/03_paragraph/standalone_image.text +3 -0
  26. data/test/testcases/block/06_codeblock/rouge/multiple.html +1 -1
  27. data/test/testcases/block/06_codeblock/rouge/simple.html +1 -1
  28. data/test/testcases/block/09_html/processing_instruction.html +5 -6
  29. data/test/testcases/block/09_html/table.kramdown +8 -0
  30. data/test/testcases/block/09_html/table.text +7 -0
  31. data/test/testcases/block/12_extension/options.html +1 -1
  32. data/test/testcases/block/12_extension/options.text +2 -0
  33. data/test/testcases/block/12_extension/options2.html +1 -1
  34. data/test/testcases/block/14_table/table_with_footnote.html +1 -1
  35. data/test/testcases/block/16_toc/toc_with_footnotes.html +1 -1
  36. data/test/testcases/man/example.man +1 -1
  37. data/test/testcases/man/example.text +1 -1
  38. data/test/testcases/span/03_codespan/normal.html +4 -0
  39. data/test/testcases/span/03_codespan/normal.text +4 -0
  40. data/test/testcases/span/04_footnote/backlink_inline.html +1 -1
  41. data/test/testcases/span/04_footnote/backlink_text.html +1 -1
  42. data/test/testcases/span/04_footnote/footnote_nr.html +1 -1
  43. data/test/testcases/span/04_footnote/footnote_prefix.html +1 -1
  44. data/test/testcases/span/04_footnote/inside_footnote.html +3 -3
  45. data/test/testcases/span/04_footnote/markers.html +5 -5
  46. data/test/testcases/span/04_footnote/placement.html +1 -1
  47. data/test/testcases/span/04_footnote/regexp_problem.html +1 -1
  48. data/test/testcases/span/04_footnote/without_backlink.html +1 -1
  49. data/test/testcases/span/05_html/normal.html +1 -1
  50. data/test/testcases/span/abbreviations/abbrev_in_html.html +9 -0
  51. data/test/testcases/span/abbreviations/abbrev_in_html.text +10 -0
  52. data/test/testcases/span/abbreviations/in_footnote.html +1 -1
  53. data/test/testcases/span/text_substitutions/entities.html +1 -1
  54. data/test/testcases/span/text_substitutions/entities.text +1 -1
  55. metadata +15 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a71580a92ad22dcb405e134d54fd2bf8dc9256574211e85e637ad018aa962160
4
- data.tar.gz: 3071848d3d1967ff4682373cfd2824f142354759a23bb386ade7f341ddacfb63
3
+ metadata.gz: f656918e531f3b20c720da64a979ea287aabf5e9b2a9bb18599d968957926e41
4
+ data.tar.gz: 3150331b7195b4dd186984a301a174ca0943e85ad11c3aef47b797b9dd46ad58
5
5
  SHA512:
6
- metadata.gz: 11c7cf78f53700f9b2a7ece59eb9cf105ecd14e646bcfa47c24aa5b676deaec991479ef3ffd91139799ee97903b3deefd98da6963a58ac32a05bb9e9a0636e95
7
- data.tar.gz: c1a3635873ee7cc6a0274734c6bc558fb4043bf3987943043c3a58ec836f4b1487a27f6129729a1662127af73293721cb5af1df79aefacc49983a0d5a3e535d8
6
+ metadata.gz: d7b0d8a7af60a0c72a6a49b26a05fc8fe3c348458802f489891166711aad985d0240d8b8882432d81ba6a061fd78e5c598ddc6dd6fa5f5de7b1aa57cf5fc9514
7
+ data.tar.gz: bec4c4bb4705f28db0bc4b7f3e4f6105e531a8711870edd90f36b0e270a653305bef544116760d3748ef91f112d51e666b468c38cddc116bcdf8c1267fbab1d3
data/CONTRIBUTERS CHANGED
@@ -1,6 +1,6 @@
1
1
  Count Name
2
2
  ======= ====
3
- 932 Thomas Leitner <t_leitner@gmx.at>
3
+ 960 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,12 +13,14 @@
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>
19
20
  2 Nathanael Jones <nathanael.jones@gmail.com>
20
21
  2 Max Meyer <dev@fedux.org>
21
22
  2 Jo Hund <jhund@clearcove.ca>
23
+ 2 Carsten Bormann <cabo@tzi.org>
22
24
  2 Bran <m.versum@gmail.com>
23
25
  1 winniehell <git@winniehell.de>
24
26
  1 William <suttonwilliamd@gmail.com>
@@ -27,12 +29,15 @@
27
29
  1 Trevor Wennblom <trevor@well.com>
28
30
  1 tomykaira <tomykaira@gmail.com>
29
31
  1 tom93 <tomlevy93@gmail.com>
32
+ 1 Tobin Yehle <tobinyehle@gmail.com>
33
+ 1 timcraft <mail@timcraft.com>
30
34
  1 Tim Blair <tim@bla.ir>
31
35
  1 Tim Besard <tim.besard@gmail.com>
32
36
  1 Tim Bates <tim@rumpuslabs.com>
33
37
  1 Sun Yaozhu <yzyzsun@gmail.com>
34
38
  1 Stephen <stephengroat@users.noreply.github.com>
35
39
  1 Stephen Crosby <stevecrozz@gmail.com>
40
+ 1 Stan Hu <stanhu@gmail.com>
36
41
  1 Simon Lydell <simon.lydell@gmail.com>
37
42
  1 Simon Coffey <simon.coffey@futurelearn.com>
38
43
  1 Shusaku NAKAZATO <cu393uc@gmail.com>
@@ -40,6 +45,7 @@
40
45
  1 scherr <maximilianscherr@gmail.com>
41
46
  1 Postmodern <postmodern.mod3@gmail.com>
42
47
  1 Pete Michaud <michaudp@gmail.com>
48
+ 1 Noah Doersing <doersino@gmail.com>
43
49
  1 myqlarson <myqlarson@gmail.com>
44
50
  1 milo.simpson <milo.simpson@bazaarvoice.com>
45
51
  1 Michal Till <michal.till@gmail.com>
@@ -63,11 +69,13 @@
63
69
  1 Fangyi Zhou <me@fangyi.io>
64
70
  1 Diego Galeota <diegobg123@gmail.com>
65
71
  1 David Rodríguez <deivid.rodriguez@riseup.net>
72
+ 1 Daniel Bair <daniel@danielbair.com>
66
73
  1 Damien Pollet <damien.pollet@gmail.com>
67
74
  1 Christopher Jefferson <caj21@st-andrews.ac.uk>
68
75
  1 Cédric Boutillier <cedric.boutillier@gmail.com>
69
76
  1 Bob Lail <lail@squareup.com>
70
77
  1 Ashe Connor <ashe@kivikakk.ee>
78
+ 1 aschmitz <29508+aschmitz@users.noreply.github.com>
71
79
  1 Antoine Cotten <hello@acotten.com>
72
80
  1 Andrew <andrew.dale.wylie@gmail.com>
73
81
  1 Alpha Chen <alpha.chen@gmail.com>
data/README.md CHANGED
@@ -7,8 +7,14 @@ requests it is now released under the MIT license and therefore can easily be us
7
7
  projects, too.
8
8
 
9
9
  However, if you use kramdown in a commercial setting, please consider **contributing back any
10
- changes** for the benefit of the community and/or
11
- [**becoming a patron**](https://www.patreon.com/gettalong) - thanks!
10
+ changes** for the benefit of the community and/or [**becoming a
11
+ sponsor**](https://github.com/sponsors/gettalong/) or [**a
12
+ patron**](https://www.patreon.com/gettalong) - thanks!
13
+
14
+ Sponsors:
15
+
16
+ * **GROSSWEBER** provides <a href="http://grossweber.com/b/kramdown" target="_blank">software
17
+ development consulting and training services</a>.
12
18
 
13
19
 
14
20
  ## Introduction
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.1
1
+ 2.3.2
@@ -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
@@ -90,7 +88,7 @@ module Kramdown
90
88
  inner(el, indent)
91
89
  elsif el.children.size == 1 && el.children.first.type == :img &&
92
90
  el.children.first.options[:ial]&.[](:refs)&.include?('standalone')
93
- convert_standalone_image(el.children.first, indent)
91
+ convert_standalone_image(el, indent)
94
92
  else
95
93
  format_as_block_html("p", el.attr, inner(el, indent), indent)
96
94
  end
@@ -99,12 +97,14 @@ module Kramdown
99
97
  # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img
100
98
  # element.
101
99
  def convert_standalone_image(el, indent)
102
- attr = el.attr.dup
103
- figure_attr = {}
104
- figure_attr['class'] = attr.delete('class') if attr.key?('class')
105
- figure_attr['id'] = attr.delete('id') if attr.key?('id')
106
- body = "#{' ' * (indent + @indent)}<img#{html_attributes(attr)} />\n" \
107
- "#{' ' * (indent + @indent)}<figcaption>#{attr['alt']}</figcaption>\n"
100
+ figure_attr = el.attr.dup
101
+ image_attr = el.children.first.attr.dup
102
+
103
+ figure_attr['class'] = image_attr.delete('class') if image_attr.key?('class') and not figure_attr.key?('class')
104
+ figure_attr['id'] = image_attr.delete('id') if image_attr.key?('id') and not figure_attr.key?('id')
105
+
106
+ body = "#{' ' * (indent + @indent)}<img#{html_attributes(image_attr)} />\n" \
107
+ "#{' ' * (indent + @indent)}<figcaption>#{image_attr['alt']}</figcaption>\n"
108
108
  format_as_indented_block_html("figure", figure_attr, body, indent)
109
109
  end
110
110
 
@@ -160,10 +160,10 @@ module Kramdown
160
160
  private_constant :ZERO_TO_ONETWENTYEIGHT
161
161
 
162
162
  def convert_ul(el, indent)
163
- if !@toc_code && (el.options[:ial][:refs].include?('toc') rescue nil)
163
+ if !@toc_code && el.options.dig(:ial, :refs)&.include?('toc')
164
164
  @toc_code = [el.type, el.attr, ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join]
165
165
  @toc_code.last
166
- elsif !@footnote_location && el.options[:ial] && (el.options[:ial][:refs] || []).include?('footnotes')
166
+ elsif !@footnote_location && el.options.dig(:ial, :refs)&.include?('footnotes')
167
167
  @footnote_location = ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join
168
168
  else
169
169
  format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
@@ -304,7 +304,7 @@ module Kramdown
304
304
  @footnotes_by_name[name] = @footnotes.last
305
305
  end
306
306
  "<sup id=\"fnref:#{name}#{repeat}\" role=\"doc-noteref\">" \
307
- "<a href=\"#fn:#{name}\" class=\"footnote\">" \
307
+ "<a href=\"#fn:#{name}\" class=\"footnote\" rel=\"footnote\">" \
308
308
  "#{number}</a></sup>"
309
309
  end
310
310
 
@@ -182,7 +182,7 @@ module Kramdown
182
182
  result << inner(el, opts) << "\n"
183
183
  end
184
184
 
185
- HTML_TAGS_WITH_BODY = ['div', 'script', 'iframe', 'textarea']
185
+ HTML_TAGS_WITH_BODY = ['div', 'script', 'iframe', 'textarea', 'th', 'td']
186
186
 
187
187
  HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze
188
188
  private_constant :HTML_ELEMENT_TYPES
@@ -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
@@ -517,7 +517,7 @@ module Kramdown
517
517
  8194 => ['\hskip .5em\relax'],
518
518
  8195 => ['\quad'],
519
519
  } # :nodoc:
520
- ENTITY_CONV_TABLE.each_value {|v| v[0] = "{}#{v[0]}" }
520
+ ENTITY_CONV_TABLE.each_value {|v| v[0] = "#{v[0]}{}" }
521
521
 
522
522
  def entity_to_latex(entity)
523
523
  text, package = ENTITY_CONV_TABLE[entity.code_point]
@@ -45,24 +45,32 @@ 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
63
71
  formatter
64
72
  when /\A[[:upper:]][[:alnum:]_]*\z/
65
- ::Rouge::Formatters.const_get(formatter)
73
+ ::Rouge::Formatters.const_get(formatter, false)
66
74
  else
67
75
  # Available in Rouge 2.0 or later
68
76
  ::Rouge::Formatters::HTMLLegacy
@@ -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
@@ -39,6 +39,7 @@ module Kramdown
39
39
  ALLOWED_TYPES = [String, Integer, Float, Symbol, Boolean, Object]
40
40
 
41
41
  @options = {}
42
+ @cached_defaults = nil
42
43
 
43
44
  # Define a new option called +name+ (a Symbol) with the given +type+ (String, Integer, Float,
44
45
  # Symbol, Boolean, Object), default value +default+ and the description +desc+. If a block is
@@ -54,6 +55,7 @@ module Kramdown
54
55
  raise ArgumentError, "Invalid type for default value" if !(type === default) && !default.nil?
55
56
  raise ArgumentError, "Missing validator block" if type == Object && block.nil?
56
57
  @options[name] = Definition.new(name, type, default, desc, block)
58
+ @cached_defaults = nil
57
59
  end
58
60
 
59
61
  # Return all option definitions.
@@ -68,15 +70,17 @@ module Kramdown
68
70
 
69
71
  # Return a Hash with the default values for all options.
70
72
  def self.defaults
71
- temp = {}
72
- @options.each {|_n, o| temp[o.name] = o.default }
73
- temp
73
+ @cached_defaults ||= begin
74
+ temp = {}
75
+ @options.each {|_n, o| temp[o.name] = o.default }
76
+ temp.freeze
77
+ end
74
78
  end
75
79
 
76
80
  # Merge the #defaults Hash with the *parsed* options from the given Hash, i.e. only valid option
77
81
  # names are considered and their value is run through the #parse method.
78
82
  def self.merge(hash)
79
- temp = defaults
83
+ temp = defaults.dup
80
84
  hash.each do |k, v|
81
85
  k = k.to_sym
82
86
  temp[k] = @options.key?(k) ? parse(k, v) : v
@@ -589,6 +593,18 @@ module Kramdown
589
593
  Used by: HTML converter
590
594
  EOF
591
595
 
596
+ define(:forbidden_inline_options, Object, %w[template], <<~EOF) do |val|
597
+ Defines the options that may not be set using the {::options} extension
598
+
599
+ The value needs to be an array of option names.
600
+
601
+ Default: [template]
602
+ Used by: HTML converter
603
+ EOF
604
+ val.map! {|item| item.kind_of?(String) ? str_to_sym(item) : item }
605
+ simple_array_validator(val, :forbidden_inline_options)
606
+ end
607
+
592
608
  end
593
609
 
594
610
  end
@@ -240,7 +240,14 @@ module Kramdown
240
240
  return
241
241
  when :html_element
242
242
  when :root
243
- el.children.each {|c| process(c) }
243
+ el.children.map! do |c|
244
+ if c.type == :text
245
+ process_text(c.value, !do_conversion)
246
+ else
247
+ process(c)
248
+ c
249
+ end
250
+ end.flatten!
244
251
  remove_whitespace_children(el)
245
252
  return
246
253
  else return
@@ -46,7 +46,7 @@ module Kramdown
46
46
  regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries
47
47
  end
48
48
  el.children.map! do |child|
49
- if child.type == :text
49
+ if child.type == :text && el.options[:content_model] != :raw
50
50
  if child.value =~ regexps.first
51
51
  result = []
52
52
  strscan = Kramdown::Utils::StringScanner.new(child.value, child.options[:location])
@@ -20,7 +20,7 @@ module Kramdown
20
20
  simple = (result.length == 1)
21
21
  saved_pos = @src.save_pos
22
22
 
23
- if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/)
23
+ if simple && @src.pre_match =~ /\s\Z|\A\Z/ && @src.match?(/\s/)
24
24
  add_text(result)
25
25
  return
26
26
  end
@@ -41,7 +41,11 @@ module Kramdown
41
41
  text = text[1..-1] if text[0..0] == ' '
42
42
  text = text[0..-2] if text[-1..-1] == ' '
43
43
  end
44
- @tree.children << Element.new(:codespan, text, nil, location: start_line_number)
44
+ @tree.children << Element.new(:codespan, text, nil, {
45
+ codespan_delimiter: result,
46
+ location: start_line_number
47
+ })
48
+
45
49
  else
46
50
  @src.revert_pos(saved_pos)
47
51
  add_text(result)
@@ -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)
@@ -69,6 +69,7 @@ module Kramdown
69
69
  eob_found = true
70
70
  break
71
71
  elsif @src.scan(list_start_re)
72
+ list.options[:first_list_marker] ||= @src[1].strip
72
73
  item = Element.new(:li, nil, nil, location: start_line_number)
73
74
  item.value, indentation, content_re, lazy_re, indent_re =
74
75
  parse_first_list_line(@src[1].length, @src[2])
@@ -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.2'
14
14
 
15
15
  end
data/man/man1/kramdown.1 CHANGED
@@ -118,6 +118,15 @@ 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
+ The value needs to be an array of option names\.
126
+ .P
127
+ Default: [template] Used by: HTML converter
128
+ .RE
129
+ .TP
121
130
  \fB\-\-header\-offset\fP \fIARG\fP
122
131
  Sets the output offset for headers
123
132
  .RS
data/test/test_files.rb CHANGED
@@ -21,16 +21,20 @@ begin
21
21
  end
22
22
 
23
23
  # custom formatter for tests
24
- class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class
24
+ module Rouge
25
+ module Formatters
26
+ class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class
25
27
 
26
- tag 'rouge_html_formatters'
28
+ tag 'rouge_html_formatters'
27
29
 
28
- def stream(tokens, &b)
29
- yield %(<div class="custom-class">)
30
- super
31
- yield %(</div>)
32
- end
30
+ def stream(tokens, &b)
31
+ yield %(<div class="custom-class">)
32
+ super
33
+ yield %(</div>)
34
+ end
33
35
 
36
+ end
37
+ end
34
38
  end
35
39
  rescue LoadError, SyntaxError, NameError
36
40
  end
@@ -180,6 +184,7 @@ class TestFiles < Minitest::Test
180
184
  'test/testcases/block/03_paragraph/standalone_image.text', # bc of standalone image
181
185
  'test/testcases/cjk-line-break.text',
182
186
  'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image
187
+ 'test/testcases/span/abbreviations/abbrev_in_html.text', # bc of invalid abbr tag in SVG
183
188
  ].compact
184
189
  Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file|
185
190
  next if EXCLUDE_TEXT_FILES.any? {|f| text_file =~ /#{f}$/ }
@@ -231,6 +236,7 @@ class TestFiles < Minitest::Test
231
236
  'test/testcases/block/15_math/gh_128.html', # bc of mathjax and HTML parser
232
237
  'test/testcases/span/04_footnote/backlink_inline.html', # bc of mathjax
233
238
  'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image
239
+ 'test/testcases/block/09_html/processing_instruction.html', # bc of PI
234
240
  ].compact
235
241
  Dir[File.dirname(__FILE__) + '/testcases/**/*.html'].each do |html_file|
236
242
  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
@@ -5,4 +5,9 @@
5
5
  <figcaption>standalone image</figcaption>
6
6
  </figure>
7
7
 
8
+ <figure id="block-id" class="block-class" block-key="block-value">
9
+ <img src="some.jpg" alt="standalone image" id="id" class="class" key="value" />
10
+ <figcaption>standalone image</figcaption>
11
+ </figure>
12
+
8
13
  <p>para</p>
@@ -3,4 +3,7 @@ para
3
3
 
4
4
  ![standalone image](some.jpg){:#id .class key="value" standalone}
5
5
 
6
+ ![standalone image](some.jpg){:#id .class key="value" standalone}
7
+ {:#block-id .block-class block-key="block-value"}
8
+
6
9
  para
@@ -6,6 +6,6 @@
6
6
  </code></pre>
7
7
  </div></div></div>
8
8
 
9
- <div class="language-php highlighter-rouge"><div class="custom-class"><div class="highlight"><pre class="highlight"><code><span class="nv">$foo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Bar</span><span class="p">;</span>
9
+ <div class="language-php highlighter-rouge"><div class="custom-class"><div class="highlight"><pre class="highlight"><code><span class="nv">$foo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Bar</span><span class="p">;</span>
10
10
  </code></pre>
11
11
  </div></div></div>
@@ -5,6 +5,6 @@
5
5
  </code></pre>
6
6
  </div></div>
7
7
 
8
- <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$foo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Bar</span><span class="p">;</span>
8
+ <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$foo</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Bar</span><span class="p">;</span>
9
9
  </code></pre>
10
10
  </div></div>
@@ -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>
@@ -0,0 +1,8 @@
1
+ <table>
2
+ <tr>
3
+ <th>test</th>
4
+ <th></th>
5
+ <td></td>
6
+ </tr>
7
+ </table>
8
+
@@ -0,0 +1,7 @@
1
+ <table>
2
+ <tr>
3
+ <th>test</th>
4
+ <th></th>
5
+ <td></td>
6
+ </tr>
7
+ </table>
@@ -10,7 +10,7 @@ some <span>*para*</span>
10
10
  <p>some <span><em>para</em></span></p>
11
11
  </div>
12
12
 
13
- <p>Some text<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote">10</a></sup>.</p>
13
+ <p>Some text<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote" rel="footnote">10</a></sup>.</p>
14
14
 
15
15
  <div class="footnotes" role="doc-endnotes">
16
16
  <ol start="10">
@@ -19,3 +19,5 @@ some <span>*para*</span>
19
19
  Some text[^ab].
20
20
 
21
21
  [^ab]: Some text.
22
+
23
+ {::options template="/etc/passwd" /}
@@ -1,5 +1,5 @@
1
1
 
2
- <p>Some text<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote">1</a></sup>.</p>
2
+ <p>Some text<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote" rel="footnote">1</a></sup>.</p>
3
3
 
4
4
  <div class="footnotes" role="doc-endnotes">
5
5
  <ol>
@@ -1,7 +1,7 @@
1
1
  <table>
2
2
  <tbody>
3
3
  <tr>
4
- <td>this is <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">1</a></sup></td>
4
+ <td>this is <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup></td>
5
5
  <td>a table</td>
6
6
  </tr>
7
7
  <tr>
@@ -2,7 +2,7 @@
2
2
  <li><a href="#header1-level-1" id="markdown-toc-header1-level-1">Header level 1</a></li>
3
3
  </ul>
4
4
 
5
- <h1 id="header1-level-1">Header<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">1</a></sup> level 1</h1>
5
+ <h1 id="header1-level-1">Header<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> level 1</h1>
6
6
 
7
7
  <div class="footnotes" role="doc-endnotes">
8
8
  <ol>
@@ -114,7 +114,7 @@ line breaks\.
114
114
  .P
115
115
  Abbreviations like MD can be used but the abbreviation title is ignored\.
116
116
  .P
117
- Math elements work \fB\el = 5\fP inline and in block form:
117
+ Math elements work \fB\elambda = 5\fP inline and in block form:
118
118
  .sp
119
119
  .RS 4
120
120
  .EX
@@ -80,6 +80,6 @@ ignored.
80
80
 
81
81
  *[MD]: Markdown
82
82
 
83
- Math elements work $$\l = 5$$ inline and in block form:
83
+ Math elements work $$\lambda = 5$$ inline and in block form:
84
84
 
85
85
  $$\lambda_5 = \alpha + 4$$
@@ -14,3 +14,7 @@ As `are` these!</p>
14
14
  <p>No <code>literal backtick</code>.</p>
15
15
 
16
16
  <p><code>something</code></p>
17
+
18
+ <p>` `</p>
19
+
20
+ <p>a ` `</p>
@@ -14,3 +14,7 @@ As \`are\` these!
14
14
  No `` literal backtick``.
15
15
 
16
16
  `something`
17
+
18
+ ` `
19
+
20
+ a ` `
@@ -1,4 +1,4 @@
1
- <p>This is <sup id="fnref:paragraph" role="doc-noteref"><a href="#fn:paragraph" class="footnote">1</a></sup><sup id="fnref:header" role="doc-noteref"><a href="#fn:header" class="footnote">2</a></sup><sup id="fnref:blockquote" role="doc-noteref"><a href="#fn:blockquote" class="footnote">3</a></sup><sup id="fnref:codeblock" role="doc-noteref"><a href="#fn:codeblock" class="footnote">4</a></sup><sup id="fnref:list" role="doc-noteref"><a href="#fn:list" class="footnote">5</a></sup><sup id="fnref:table" role="doc-noteref"><a href="#fn:table" class="footnote">6</a></sup><sup id="fnref:hrule" role="doc-noteref"><a href="#fn:hrule" class="footnote">7</a></sup><sup id="fnref:mathblock" role="doc-noteref"><a href="#fn:mathblock" class="footnote">8</a></sup><sup id="fnref:html" role="doc-noteref"><a href="#fn:html" class="footnote">9</a></sup></p>
1
+ <p>This is <sup id="fnref:paragraph" role="doc-noteref"><a href="#fn:paragraph" class="footnote" rel="footnote">1</a></sup><sup id="fnref:header" role="doc-noteref"><a href="#fn:header" class="footnote" rel="footnote">2</a></sup><sup id="fnref:blockquote" role="doc-noteref"><a href="#fn:blockquote" class="footnote" rel="footnote">3</a></sup><sup id="fnref:codeblock" role="doc-noteref"><a href="#fn:codeblock" class="footnote" rel="footnote">4</a></sup><sup id="fnref:list" role="doc-noteref"><a href="#fn:list" class="footnote" rel="footnote">5</a></sup><sup id="fnref:table" role="doc-noteref"><a href="#fn:table" class="footnote" rel="footnote">6</a></sup><sup id="fnref:hrule" role="doc-noteref"><a href="#fn:hrule" class="footnote" rel="footnote">7</a></sup><sup id="fnref:mathblock" role="doc-noteref"><a href="#fn:mathblock" class="footnote" rel="footnote">8</a></sup><sup id="fnref:html" role="doc-noteref"><a href="#fn:html" class="footnote" rel="footnote">9</a></sup></p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol>
@@ -1,4 +1,4 @@
1
- <p>Some footnote here<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote">1</a></sup></p>
1
+ <p>Some footnote here<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote" rel="footnote">1</a></sup></p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol>
@@ -1,4 +1,4 @@
1
- <p>This is a footnote<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote">35</a></sup>. And another<sup id="fnref:bc" role="doc-noteref"><a href="#fn:bc" class="footnote">36</a></sup>.</p>
1
+ <p>This is a footnote<sup id="fnref:ab" role="doc-noteref"><a href="#fn:ab" class="footnote" rel="footnote">35</a></sup>. And another<sup id="fnref:bc" role="doc-noteref"><a href="#fn:bc" class="footnote" rel="footnote">36</a></sup>.</p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol start="35">
@@ -1,4 +1,4 @@
1
- <p>This is a<sup id="fnref:adf123-ab" role="doc-noteref"><a href="#fn:adf123-ab" class="footnote">1</a></sup> footnote<sup id="fnref:adf123-ab:1" role="doc-noteref"><a href="#fn:adf123-ab" class="footnote">1</a></sup>. And another<sup id="fnref:adf123-bc" role="doc-noteref"><a href="#fn:adf123-bc" class="footnote">2</a></sup>.</p>
1
+ <p>This is a<sup id="fnref:adf123-ab" role="doc-noteref"><a href="#fn:adf123-ab" class="footnote" rel="footnote">1</a></sup> footnote<sup id="fnref:adf123-ab:1" role="doc-noteref"><a href="#fn:adf123-ab" class="footnote" rel="footnote">1</a></sup>. And another<sup id="fnref:adf123-bc" role="doc-noteref"><a href="#fn:adf123-bc" class="footnote" rel="footnote">2</a></sup>.</p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol>
@@ -1,11 +1,11 @@
1
- <p>Lorem ipsum<sup id="fnref:first" role="doc-noteref"><a href="#fn:first" class="footnote">1</a></sup> dolor sit amet.</p>
1
+ <p>Lorem ipsum<sup id="fnref:first" role="doc-noteref"><a href="#fn:first" class="footnote" rel="footnote">1</a></sup> dolor sit amet.</p>
2
2
 
3
- <p>Lorem ipsum<sup id="fnref:second" role="doc-noteref"><a href="#fn:second" class="footnote">2</a></sup> dolor sit amet.</p>
3
+ <p>Lorem ipsum<sup id="fnref:second" role="doc-noteref"><a href="#fn:second" class="footnote" rel="footnote">2</a></sup> dolor sit amet.</p>
4
4
 
5
5
  <div class="footnotes" role="doc-endnotes">
6
6
  <ol>
7
7
  <li id="fn:first" role="doc-endnote">
8
- <p>Consecutur adisping.<sup id="fnref:third" role="doc-noteref"><a href="#fn:third" class="footnote">3</a></sup> <a href="#fnref:first" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
8
+ <p>Consecutur adisping.<sup id="fnref:third" role="doc-noteref"><a href="#fn:third" class="footnote" rel="footnote">3</a></sup> <a href="#fnref:first" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
9
9
  </li>
10
10
  <li id="fn:second" role="doc-endnote">
11
11
  <p>Sed ut perspiciatis unde omnis. <a href="#fnref:second" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
@@ -1,18 +1,18 @@
1
- <p>This is some *ref.<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote">1</a></sup></p>
1
+ <p>This is some *ref.<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote" rel="footnote">1</a></sup></p>
2
2
 
3
3
  <blockquote>
4
- <p>a blockquote <sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote">2</a></sup></p>
4
+ <p>a blockquote <sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">2</a></sup></p>
5
5
  </blockquote>
6
6
 
7
7
  <ul>
8
- <li>and a list item <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">3</a></sup></li>
8
+ <li>and a list item <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">3</a></sup></li>
9
9
  </ul>
10
10
 
11
- <h1>And a header<sup id="fnref:now" role="doc-noteref"><a href="#fn:now" class="footnote">4</a></sup></h1>
11
+ <h1>And a header<sup id="fnref:now" role="doc-noteref"><a href="#fn:now" class="footnote" rel="footnote">4</a></sup></h1>
12
12
 
13
13
  <p>A marker without a definition [^without].</p>
14
14
 
15
- <p>A marker <sup id="fnref:empty" role="doc-noteref"><a href="#fn:empty" class="footnote">5</a></sup> used twice<sup id="fnref:fn:1" role="doc-noteref"><a href="#fn:fn" class="footnote">1</a></sup> and thrice<sup id="fnref:fn:2" role="doc-noteref"><a href="#fn:fn" class="footnote">1</a></sup>.</p>
15
+ <p>A marker <sup id="fnref:empty" role="doc-noteref"><a href="#fn:empty" class="footnote" rel="footnote">5</a></sup> used twice<sup id="fnref:fn:1" role="doc-noteref"><a href="#fn:fn" class="footnote" rel="footnote">1</a></sup> and thrice<sup id="fnref:fn:2" role="doc-noteref"><a href="#fn:fn" class="footnote" rel="footnote">1</a></sup>.</p>
16
16
 
17
17
  <div class="footnotes" role="doc-endnotes">
18
18
  <ol>
@@ -6,6 +6,6 @@
6
6
  </ol>
7
7
  </div>
8
8
 
9
- <p>Some para with a<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">1</a></sup> footnote.</p>
9
+ <p>Some para with a<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> footnote.</p>
10
10
 
11
11
  <p>And another para.</p>
@@ -1,5 +1,5 @@
1
1
  <h1>Something</h1>
2
- <p>something<sup id="fnref:note1" role="doc-noteref"><a href="#fn:note1" class="footnote">1</a></sup>.</p>
2
+ <p>something<sup id="fnref:note1" role="doc-noteref"><a href="#fn:note1" class="footnote" rel="footnote">1</a></sup>.</p>
3
3
 
4
4
  <h1>Footnotes</h1>
5
5
 
@@ -1,4 +1,4 @@
1
- <p>Some footnote here<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote">1</a></sup></p>
1
+ <p>Some footnote here<sup id="fnref:fn" role="doc-noteref"><a href="#fn:fn" class="footnote" rel="footnote">1</a></sup></p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol>
@@ -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
 
@@ -0,0 +1,9 @@
1
+ <p>This is <em>some <abbr title="This Escapes SVG Text.">TEST</abbr></em> to check.</p>
2
+
3
+ <svg width="100" height="30" viewBox="0 0 100 30" xmlns="http://www.w3.org/2000/svg">
4
+ <text x="20" y="20">This TEST fails.</text>
5
+ </svg>
6
+ <svg width="100" height="30" viewBox="0 0 100 30" xmlns="http://www.w3.org/2000/svg">
7
+ <text x="20" y="20">This <abbr title="This Escapes SVG Text.">TEST</abbr> fails.</text>
8
+ </svg>
9
+
@@ -0,0 +1,10 @@
1
+ This is <em>some TEST</em> to check.
2
+
3
+ <svg width="100" height="30" viewBox="0 0 100 30" xmlns="http://www.w3.org/2000/svg">
4
+ <text x="20" y="20">This TEST fails.</text>
5
+ </svg>
6
+ <svg width="100" height="30" viewBox="0 0 100 30" xmlns="http://www.w3.org/2000/svg">
7
+ <text x="20" y="20" markdown="span">This TEST fails.</text>
8
+ </svg>
9
+
10
+ *[TEST]: This Escapes SVG Text.
@@ -1,4 +1,4 @@
1
- <p>There is a <abbr title="Text File">TXT</abbr> file here. <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">1</a></sup></p>
1
+ <p>There is a <abbr title="Text File">TXT</abbr> file here. <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup></p>
2
2
 
3
3
  <div class="footnotes" role="doc-endnotes">
4
4
  <ol>
@@ -3,4 +3,4 @@ As well \&amp; as this. Some &#343; other
3
3
  values may &#xAF; may also show but
4
4
  not st. like &amp;#xYZ;.</p>
5
5
 
6
- <p>This is BS&amp;T; done!</p>
6
+ <p>This &lt;span&gt; is BS&amp;T; done!</p>
@@ -3,4 +3,4 @@ As well \& as this. Some &#343; other
3
3
  values may &#xAF; may also show but
4
4
  not st. like &#xYZ;.
5
5
 
6
- This is BS&T; done!
6
+ This &lt;span&gt; is BS&T; done!
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.2
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: 2022-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rexml
@@ -42,16 +42,22 @@ dependencies:
42
42
  name: rouge
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
45
48
  - - ">="
46
49
  - !ruby/object:Gem::Version
47
- version: '0'
50
+ version: 3.26.0
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.0'
52
58
  - - ">="
53
59
  - !ruby/object:Gem::Version
54
- version: '0'
60
+ version: 3.26.0
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: stringex
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -366,6 +372,8 @@ files:
366
372
  - test/testcases/block/09_html/simple.text
367
373
  - test/testcases/block/09_html/standalone_image_in_div.htmlinput
368
374
  - test/testcases/block/09_html/standalone_image_in_div.text
375
+ - test/testcases/block/09_html/table.kramdown
376
+ - test/testcases/block/09_html/table.text
369
377
  - test/testcases/block/09_html/textarea.html
370
378
  - test/testcases/block/09_html/textarea.text
371
379
  - test/testcases/block/09_html/xml.html
@@ -580,6 +588,8 @@ files:
580
588
  - test/testcases/span/abbreviations/abbrev.text
581
589
  - test/testcases/span/abbreviations/abbrev_defs.html
582
590
  - test/testcases/span/abbreviations/abbrev_defs.text
591
+ - test/testcases/span/abbreviations/abbrev_in_html.html
592
+ - test/testcases/span/abbreviations/abbrev_in_html.text
583
593
  - test/testcases/span/abbreviations/in_footnote.html
584
594
  - test/testcases/span/abbreviations/in_footnote.text
585
595
  - test/testcases/span/autolinks/url_links.html
@@ -651,7 +661,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
651
661
  - !ruby/object:Gem::Version
652
662
  version: '0'
653
663
  requirements: []
654
- rubygems_version: 3.0.3
664
+ rubygems_version: 3.2.32
655
665
  signing_key:
656
666
  specification_version: 4
657
667
  summary: kramdown is a fast, pure-Ruby Markdown-superset converter.