kramdown 2.3.0 → 2.4.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTERS +7 -1
  3. data/README.md +8 -2
  4. data/VERSION +1 -1
  5. data/lib/kramdown/converter/html.rb +11 -9
  6. data/lib/kramdown/converter/kramdown.rb +9 -4
  7. data/lib/kramdown/converter/latex.rb +1 -1
  8. data/lib/kramdown/converter/syntax_highlighter/rouge.rb +1 -1
  9. data/lib/kramdown/options.rb +18 -5
  10. data/lib/kramdown/parser/html.rb +8 -1
  11. data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -1
  12. data/lib/kramdown/parser/kramdown/codespan.rb +6 -2
  13. data/lib/kramdown/parser/kramdown/list.rb +1 -0
  14. data/lib/kramdown/version.rb +1 -1
  15. data/man/man1/kramdown.1 +10 -1
  16. data/test/test_files.rb +15 -7
  17. data/test/testcases/block/03_paragraph/standalone_image.html +5 -0
  18. data/test/testcases/block/03_paragraph/standalone_image.text +3 -0
  19. data/test/testcases/block/03_paragraph/to_kramdown.kramdown +7 -0
  20. data/test/testcases/block/03_paragraph/to_kramdown.text +5 -0
  21. data/test/testcases/block/06_codeblock/rouge/multiple.html +1 -1
  22. data/test/testcases/block/06_codeblock/rouge/simple.html +1 -1
  23. data/test/testcases/block/09_html/table.kramdown +8 -0
  24. data/test/testcases/block/09_html/table.text +7 -0
  25. data/test/testcases/block/12_extension/options.html +1 -1
  26. data/test/testcases/block/12_extension/options2.html +1 -1
  27. data/test/testcases/block/14_table/table_with_footnote.html +1 -1
  28. data/test/testcases/block/16_toc/toc_with_footnotes.html +1 -1
  29. data/test/testcases/man/example.man +1 -1
  30. data/test/testcases/man/example.text +1 -1
  31. data/test/testcases/span/03_codespan/normal.html +4 -0
  32. data/test/testcases/span/03_codespan/normal.text +4 -0
  33. data/test/testcases/span/04_footnote/backlink_inline.html +1 -1
  34. data/test/testcases/span/04_footnote/backlink_text.html +1 -1
  35. data/test/testcases/span/04_footnote/footnote_nr.html +1 -1
  36. data/test/testcases/span/04_footnote/footnote_prefix.html +1 -1
  37. data/test/testcases/span/04_footnote/inside_footnote.html +3 -3
  38. data/test/testcases/span/04_footnote/markers.html +5 -5
  39. data/test/testcases/span/04_footnote/placement.html +1 -1
  40. data/test/testcases/span/04_footnote/regexp_problem.html +1 -1
  41. data/test/testcases/span/04_footnote/without_backlink.html +1 -1
  42. data/test/testcases/span/abbreviations/abbrev_in_html.html +9 -0
  43. data/test/testcases/span/abbreviations/abbrev_in_html.text +10 -0
  44. data/test/testcases/span/abbreviations/in_footnote.html +1 -1
  45. data/test/testcases/span/text_substitutions/entities.html +1 -1
  46. data/test/testcases/span/text_substitutions/entities.text +1 -1
  47. metadata +17 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a893196013756c877e4baa3d62eb2d3b862684748ed4f329a9723779e30bbeb
4
- data.tar.gz: abfac14092805a87a5bdb0c7210ddb157b35a22391a8393a8401fdc547d2f902
3
+ metadata.gz: 3c41b216fbd6f50c68b10864bc3a98040f79641db9af8ced05eb43f7817335ad
4
+ data.tar.gz: ef3adb19cbfbe4586bf0ef4f14362ca843a7fe3331ff6dc990c270ff65cff000
5
5
  SHA512:
6
- metadata.gz: 2fdb47e22271964a0a5caef5dc9054a6a5d50cfd81c01665ddfe9aa8e66539ce97125019bea46700ff54227602ce45fd3af98bd48824fe3460aefd6ce6ec3828
7
- data.tar.gz: 9927a0d0fe778ac799dcd499727623c7bb35cc2a46a5745042c88d65685502d7bc04384c265155af214f046a2a27f72cf4b73b2d3ddba6a987de85939b6cfe56
6
+ metadata.gz: 483e269f858aadd6bf8e7bf2f49ec90ddfdcd9628aec17822eb7eefcfc21897eb19d258a84b6291611a38a5958a79013c2c656d35f7740b116923bd8624a2329
7
+ data.tar.gz: 5ffeef35cdfb994411414d62bd8b5fcf09fcea7d926069896248148575b88b4abbfdc1e5aab6da8dbe6f97c3e0a4921b391802e391ea3c76a646be7f64fbbbda
data/CONTRIBUTERS CHANGED
@@ -1,6 +1,6 @@
1
1
  Count Name
2
2
  ======= ====
3
- 943 Thomas Leitner <t_leitner@gmx.at>
3
+ 964 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>
@@ -11,6 +11,7 @@
11
11
  4 Arne Brasseur <arne@arnebrasseur.net>
12
12
  3 Henning Perl <perl@fast-sicher.de>
13
13
  3 gettalong <t_leitner@gmx.at>
14
+ 3 Carsten Bormann <cabo@tzi.org>
14
15
  3 Brandur <brandur@mutelight.org>
15
16
  3 Ben Armston <ben.armston@googlemail.com>
16
17
  3 Ashwin Maroli <ashmaroli@users.noreply.github.com>
@@ -28,12 +29,15 @@
28
29
  1 Trevor Wennblom <trevor@well.com>
29
30
  1 tomykaira <tomykaira@gmail.com>
30
31
  1 tom93 <tomlevy93@gmail.com>
32
+ 1 Tobin Yehle <tobinyehle@gmail.com>
33
+ 1 timcraft <mail@timcraft.com>
31
34
  1 Tim Blair <tim@bla.ir>
32
35
  1 Tim Besard <tim.besard@gmail.com>
33
36
  1 Tim Bates <tim@rumpuslabs.com>
34
37
  1 Sun Yaozhu <yzyzsun@gmail.com>
35
38
  1 Stephen <stephengroat@users.noreply.github.com>
36
39
  1 Stephen Crosby <stevecrozz@gmail.com>
40
+ 1 Stan Hu <stanhu@gmail.com>
37
41
  1 Simon Lydell <simon.lydell@gmail.com>
38
42
  1 Simon Coffey <simon.coffey@futurelearn.com>
39
43
  1 Shusaku NAKAZATO <cu393uc@gmail.com>
@@ -65,11 +69,13 @@
65
69
  1 Fangyi Zhou <me@fangyi.io>
66
70
  1 Diego Galeota <diegobg123@gmail.com>
67
71
  1 David Rodríguez <deivid.rodriguez@riseup.net>
72
+ 1 Daniel Bair <daniel@danielbair.com>
68
73
  1 Damien Pollet <damien.pollet@gmail.com>
69
74
  1 Christopher Jefferson <caj21@st-andrews.ac.uk>
70
75
  1 Cédric Boutillier <cedric.boutillier@gmail.com>
71
76
  1 Bob Lail <lail@squareup.com>
72
77
  1 Ashe Connor <ashe@kivikakk.ee>
78
+ 1 aschmitz <29508+aschmitz@users.noreply.github.com>
73
79
  1 Antoine Cotten <hello@acotten.com>
74
80
  1 Andrew <andrew.dale.wylie@gmail.com>
75
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.3.0
1
+ 2.4.0
@@ -88,7 +88,7 @@ module Kramdown
88
88
  inner(el, indent)
89
89
  elsif el.children.size == 1 && el.children.first.type == :img &&
90
90
  el.children.first.options[:ial]&.[](:refs)&.include?('standalone')
91
- convert_standalone_image(el.children.first, indent)
91
+ convert_standalone_image(el, indent)
92
92
  else
93
93
  format_as_block_html("p", el.attr, inner(el, indent), indent)
94
94
  end
@@ -97,12 +97,14 @@ module Kramdown
97
97
  # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img
98
98
  # element.
99
99
  def convert_standalone_image(el, indent)
100
- attr = el.attr.dup
101
- figure_attr = {}
102
- figure_attr['class'] = attr.delete('class') if attr.key?('class')
103
- figure_attr['id'] = attr.delete('id') if attr.key?('id')
104
- body = "#{' ' * (indent + @indent)}<img#{html_attributes(attr)} />\n" \
105
- "#{' ' * (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"
106
108
  format_as_indented_block_html("figure", figure_attr, body, indent)
107
109
  end
108
110
 
@@ -281,7 +283,7 @@ module Kramdown
281
283
  hl_opts = {}
282
284
  result = highlight_code(el.value, lang, :span, hl_opts)
283
285
  if result
284
- add_syntax_highlighter_to_class_attr(attr, hl_opts[:default_lang])
286
+ add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang])
285
287
  else
286
288
  result = escape_html(el.value)
287
289
  end
@@ -302,7 +304,7 @@ module Kramdown
302
304
  @footnotes_by_name[name] = @footnotes.last
303
305
  end
304
306
  "<sup id=\"fnref:#{name}#{repeat}\" role=\"doc-noteref\">" \
305
- "<a href=\"#fn:#{name}\" class=\"footnote\">" \
307
+ "<a href=\"#fn:#{name}\" class=\"footnote\" rel=\"footnote\">" \
306
308
  "#{number}</a></sup>"
307
309
  end
308
310
 
@@ -27,6 +27,8 @@ module Kramdown
27
27
  @footnotes = []
28
28
  @abbrevs = []
29
29
  @stack = []
30
+ @list_indent = @options[:list_indent]
31
+ @list_spacing = ' ' * (@list_indent - 2)
30
32
  end
31
33
 
32
34
  def convert(el, opts = {indent: 0})
@@ -77,7 +79,9 @@ module Kramdown
77
79
  else
78
80
  el.value.gsub(/\A\n/) do
79
81
  opts[:prev] && opts[:prev].type == :br ? '' : "\n"
80
- end.gsub(/\s+/, ' ').gsub(ESCAPED_CHAR_RE) { "\\#{$1 || $2}" }
82
+ end.gsub(/\s+/, ' ').gsub(ESCAPED_CHAR_RE) do
83
+ $1 || !opts[:prev] || opts[:prev].type == :br ? "\\#{$1 || $2}" : $&
84
+ end
81
85
  end
82
86
  end
83
87
 
@@ -87,6 +91,7 @@ module Kramdown
87
91
  first&.gsub!(/^(?:(#|>)|(\d+)\.|([+-]\s))/) { $1 || $3 ? "\\#{$1 || $3}" : "#{$2}\\." }
88
92
  second&.gsub!(/^([=-]+\s*?)$/, "\\\1")
89
93
  res = [first, second, *rest].compact.join("\n") + "\n"
94
+ res.gsub!(/^[ ]{0,3}:/, "\\:")
90
95
  if el.children.length == 1 && el.children.first.type == :math
91
96
  res = "\\#{res}"
92
97
  elsif res.start_with?('\$$') && res.end_with?("\\$$\n")
@@ -124,7 +129,7 @@ module Kramdown
124
129
 
125
130
  def convert_li(el, opts)
126
131
  sym, width = if @stack.last.type == :ul
127
- [+'* ', el.children.first && el.children.first.type == :codeblock ? 4 : 2]
132
+ ['* ' + @list_spacing, el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent]
128
133
  else
129
134
  ["#{opts[:index] + 1}.".ljust(4), 4]
130
135
  end
@@ -151,7 +156,7 @@ module Kramdown
151
156
  end
152
157
 
153
158
  def convert_dd(el, opts)
154
- sym, width = +": ", (el.children.first && el.children.first.type == :codeblock ? 4 : 2)
159
+ sym, width = ": " + @list_spacing, (el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent)
155
160
  if (ial = ial_for_element(el))
156
161
  sym << ial << " "
157
162
  end
@@ -182,7 +187,7 @@ module Kramdown
182
187
  result << inner(el, opts) << "\n"
183
188
  end
184
189
 
185
- HTML_TAGS_WITH_BODY = ['div', 'script', 'iframe', 'textarea']
190
+ HTML_TAGS_WITH_BODY = ['div', 'script', 'iframe', 'textarea', 'th', 'td']
186
191
 
187
192
  HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze
188
193
  private_constant :HTML_ELEMENT_TYPES
@@ -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]
@@ -70,7 +70,7 @@ module Kramdown::Converter::SyntaxHighlighter
70
70
  when Class
71
71
  formatter
72
72
  when /\A[[:upper:]][[:alnum:]_]*\z/
73
- ::Rouge::Formatters.const_get(formatter)
73
+ ::Rouge::Formatters.const_get(formatter, false)
74
74
  else
75
75
  # Available in Rouge 2.0 or later
76
76
  ::Rouge::Formatters::HTMLLegacy
@@ -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
@@ -592,13 +596,22 @@ module Kramdown
592
596
  define(:forbidden_inline_options, Object, %w[template], <<~EOF) do |val|
593
597
  Defines the options that may not be set using the {::options} extension
594
598
 
595
- Default: template
599
+ The value needs to be an array of option names.
600
+
601
+ Default: [template]
596
602
  Used by: HTML converter
597
603
  EOF
598
604
  val.map! {|item| item.kind_of?(String) ? str_to_sym(item) : item }
599
605
  simple_array_validator(val, :forbidden_inline_options)
600
606
  end
601
607
 
608
+ define(:list_indent, Integer, 2, <<~EOF)
609
+ Sets the number of spaces to use for list indentation
610
+
611
+ Default: 2
612
+ Used by: Kramdown converter
613
+ EOF
614
+
602
615
  end
603
616
 
604
617
  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)
@@ -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])
@@ -10,6 +10,6 @@
10
10
  module Kramdown
11
11
 
12
12
  # The kramdown version.
13
- VERSION = '2.3.0'
13
+ VERSION = '2.4.0'
14
14
 
15
15
  end
data/man/man1/kramdown.1 CHANGED
@@ -122,7 +122,9 @@ Default: \[u2018]\[u2019] Used by: HTML
122
122
  Defines the options that may not be set using the {::options} extension
123
123
  .RS
124
124
  .P
125
- Default: template Used by: HTML converter
125
+ The value needs to be an array of option names\.
126
+ .P
127
+ Default: [template] Used by: HTML converter
126
128
  .RE
127
129
  .TP
128
130
  \fB\-\-header\-offset\fP \fIARG\fP
@@ -172,6 +174,13 @@ If the value is a String, it has to contain a valid YAML hash and the hash has t
172
174
  Default: {} Used by: kramdown parser
173
175
  .RE
174
176
  .TP
177
+ \fB\-\-list\-indent\fP \fIARG\fP
178
+ Sets the number of spaces to use for list indentation
179
+ .RS
180
+ .P
181
+ Default: 2 Used by: Kramdown converter
182
+ .RE
183
+ .TP
175
184
  \fB\-\-math\-engine\fP \fIARG\fP
176
185
  Set the math engine
177
186
  .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}$/ }
@@ -192,6 +197,9 @@ class TestFiles < Minitest::Test
192
197
  kdtext = Kramdown::Document.new(File.read(text_file), options).to_kramdown
193
198
  html = Kramdown::Document.new(kdtext, options).to_html
194
199
  assert_equal(tidy_output(File.read(html_file)), tidy_output(html))
200
+ kdtext4 = Kramdown::Document.new(File.read(text_file), options.merge({list_indent: 4})).to_kramdown
201
+ html = Kramdown::Document.new(kdtext4, options).to_html
202
+ assert_equal(tidy_output(File.read(html_file)), tidy_output(html))
195
203
  end
196
204
  end
197
205
  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
@@ -0,0 +1,7 @@
1
+ aa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
2
+ \: No definiion list
3
+
4
+ a:
5
+
6
+ *a*:
7
+
@@ -0,0 +1,5 @@
1
+ aa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa : No definiion list
2
+
3
+ a:
4
+
5
+ *a*:
@@ -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>
@@ -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">
@@ -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>
@@ -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.3.0
4
+ version: 2.4.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-06-28 00:00:00.000000000 Z
11
+ date: 2022-04-25 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
@@ -164,6 +170,8 @@ files:
164
170
  - test/testcases/block/03_paragraph/one_para.text
165
171
  - test/testcases/block/03_paragraph/standalone_image.html
166
172
  - test/testcases/block/03_paragraph/standalone_image.text
173
+ - test/testcases/block/03_paragraph/to_kramdown.kramdown
174
+ - test/testcases/block/03_paragraph/to_kramdown.text
167
175
  - test/testcases/block/03_paragraph/two_para.html
168
176
  - test/testcases/block/03_paragraph/two_para.text
169
177
  - test/testcases/block/03_paragraph/with_html_to_native.html
@@ -366,6 +374,8 @@ files:
366
374
  - test/testcases/block/09_html/simple.text
367
375
  - test/testcases/block/09_html/standalone_image_in_div.htmlinput
368
376
  - test/testcases/block/09_html/standalone_image_in_div.text
377
+ - test/testcases/block/09_html/table.kramdown
378
+ - test/testcases/block/09_html/table.text
369
379
  - test/testcases/block/09_html/textarea.html
370
380
  - test/testcases/block/09_html/textarea.text
371
381
  - test/testcases/block/09_html/xml.html
@@ -580,6 +590,8 @@ files:
580
590
  - test/testcases/span/abbreviations/abbrev.text
581
591
  - test/testcases/span/abbreviations/abbrev_defs.html
582
592
  - test/testcases/span/abbreviations/abbrev_defs.text
593
+ - test/testcases/span/abbreviations/abbrev_in_html.html
594
+ - test/testcases/span/abbreviations/abbrev_in_html.text
583
595
  - test/testcases/span/abbreviations/in_footnote.html
584
596
  - test/testcases/span/abbreviations/in_footnote.text
585
597
  - test/testcases/span/autolinks/url_links.html
@@ -651,7 +663,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
651
663
  - !ruby/object:Gem::Version
652
664
  version: '0'
653
665
  requirements: []
654
- rubygems_version: 3.0.3
666
+ rubygems_version: 3.2.32
655
667
  signing_key:
656
668
  specification_version: 4
657
669
  summary: kramdown is a fast, pure-Ruby Markdown-superset converter.