kramdown 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +10 -1
- data/VERSION +1 -1
- data/bin/kramdown +15 -12
- data/lib/kramdown/converter/base.rb +2 -2
- data/lib/kramdown/converter/html.rb +22 -14
- data/lib/kramdown/converter/kramdown.rb +25 -20
- data/lib/kramdown/converter/latex.rb +11 -10
- data/lib/kramdown/converter/man.rb +3 -3
- data/lib/kramdown/converter/math_engine/mathjax.rb +1 -1
- data/lib/kramdown/converter/remove_html_tags.rb +5 -4
- data/lib/kramdown/document.rb +1 -1
- data/lib/kramdown/element.rb +1 -1
- data/lib/kramdown/options.rb +43 -15
- data/lib/kramdown/parser/base.rb +6 -0
- data/lib/kramdown/parser/html.rb +24 -18
- data/lib/kramdown/parser/kramdown/abbreviation.rb +4 -2
- data/lib/kramdown/parser/kramdown/codespan.rb +1 -1
- data/lib/kramdown/parser/kramdown/emphasis.rb +6 -1
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +1 -1
- data/lib/kramdown/parser/kramdown/extensions.rb +6 -6
- data/lib/kramdown/parser/kramdown/html.rb +26 -23
- data/lib/kramdown/parser/kramdown/html_entity.rb +1 -1
- data/lib/kramdown/parser/kramdown/link.rb +4 -4
- data/lib/kramdown/parser/kramdown/list.rb +19 -18
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +1 -1
- data/lib/kramdown/parser/kramdown.rb +5 -4
- data/lib/kramdown/utils/entities.rb +661 -5
- data/lib/kramdown/utils/html.rb +1 -1
- data/lib/kramdown/utils/unidecoder.rb +9 -13
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +18 -0
- data/test/test_files.rb +8 -0
- data/test/testcases/block/04_header/with_header_links.html +7 -0
- data/test/testcases/block/04_header/with_header_links.options +2 -0
- data/test/testcases/block/04_header/with_header_links.text +8 -0
- data/test/testcases/block/04_header/with_line_break.html +1 -0
- data/test/testcases/block/04_header/with_line_break.text +1 -0
- data/test/testcases/block/08_list/escaping.html +4 -0
- data/test/testcases/block/08_list/escaping.text +4 -0
- data/test/testcases/block/08_list/nested_compact.kramdown +7 -0
- data/test/testcases/block/08_list/nested_compact.text +6 -0
- data/test/testcases/block/08_list/special_cases.html +10 -0
- data/test/testcases/block/08_list/special_cases.text +9 -0
- data/test/testcases/block/09_html/cdata_section.html +10 -0
- data/test/testcases/block/09_html/cdata_section.text +10 -0
- data/test/testcases/block/09_html/html_to_native/table_simple.html +3 -0
- data/test/testcases/block/09_html/html_to_native/table_simple.text +3 -0
- data/test/testcases/block/12_extension/options.html +2 -2
- data/test/testcases/block/12_extension/options2.html +2 -2
- data/test/testcases/block/14_table/table_with_footnote.html +2 -2
- data/test/testcases/block/16_toc/toc_with_footnotes.html +2 -2
- data/test/testcases/span/02_emphasis/normal.html +6 -1
- data/test/testcases/span/02_emphasis/normal.text +5 -0
- data/test/testcases/span/04_footnote/backlink_inline.html +10 -10
- data/test/testcases/span/04_footnote/backlink_text.html +2 -2
- data/test/testcases/span/04_footnote/footnote_link_text.html +12 -0
- data/test/testcases/span/04_footnote/footnote_link_text.options +1 -0
- data/test/testcases/span/04_footnote/footnote_link_text.text +4 -0
- data/test/testcases/span/04_footnote/footnote_nr.html +3 -3
- data/test/testcases/span/04_footnote/footnote_prefix.html +3 -3
- data/test/testcases/span/04_footnote/inside_footnote.html +6 -6
- data/test/testcases/span/04_footnote/markers.html +10 -10
- data/test/testcases/span/04_footnote/placement.html +2 -2
- data/test/testcases/span/04_footnote/regexp_problem.html +2 -2
- data/test/testcases/span/04_footnote/without_backlink.html +2 -2
- data/test/testcases/span/abbreviations/abbrev.html +4 -0
- data/test/testcases/span/abbreviations/abbrev.text +7 -0
- data/test/testcases/span/abbreviations/in_footnote.html +2 -2
- metadata +21 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53bf662f86052a77c6c9867b0c4e6808c9cee58ce1ed2b5e77c74b9d015b8e73
|
4
|
+
data.tar.gz: 3f56c0fd6fb00b867ade3ce1df9ddda4380aa01307b37420fbc5a4f1330a8156
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 813301a1fe55b9eeb724fec2e482a694e74852d2509cd74e64cbc5f5df5122f77d63b317439c4184b9ebc7651584d5c777d58eb29183e07ab941d453c12a6ed4
|
7
|
+
data.tar.gz: 610257c36fc35ac7195114f1a5458d02939116696e799ab257a821a2ab5025ecf94470a4800cd767dfdc0730da0a0ec599276ac2ac745ef64b07d2bc4d20ba9b
|
data/CONTRIBUTERS
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Count Name
|
2
2
|
======= ====
|
3
|
-
|
3
|
+
986 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>
|
@@ -21,9 +21,11 @@
|
|
21
21
|
2 Nathanael Jones <nathanael.jones@gmail.com>
|
22
22
|
2 Max Meyer <dev@fedux.org>
|
23
23
|
2 Jo Hund <jhund@clearcove.ca>
|
24
|
+
2 Bryce Willey <Bryce.Steven.Willey@gmail.com>
|
24
25
|
2 Bran <m.versum@gmail.com>
|
25
26
|
1 winniehell <git@winniehell.de>
|
26
27
|
1 William <suttonwilliamd@gmail.com>
|
28
|
+
1 Virgil Ierubino <30758921+Convincible@users.noreply.github.com>
|
27
29
|
1 Uwe Kubosch <donv@users.noreply.github.com>
|
28
30
|
1 utenmiki <utenmiki@gmail.com>
|
29
31
|
1 Trevor Wennblom <trevor@well.com>
|
@@ -45,6 +47,8 @@
|
|
45
47
|
1 scherr <maximilianscherr@gmail.com>
|
46
48
|
1 Postmodern <postmodern.mod3@gmail.com>
|
47
49
|
1 Pete Michaud <michaudp@gmail.com>
|
50
|
+
1 Paul McMahon <paul@tokyodev.com>
|
51
|
+
1 Paul <2528280+psfrolov@users.noreply.github.com>
|
48
52
|
1 Noah Doersing <doersino@gmail.com>
|
49
53
|
1 myqlarson <myqlarson@gmail.com>
|
50
54
|
1 milo.simpson <milo.simpson@bazaarvoice.com>
|
@@ -59,9 +63,11 @@
|
|
59
63
|
1 Kir Kolyshkin <kolyshkin@gmail.com>
|
60
64
|
1 Jun Aruga <jaruga@redhat.com>
|
61
65
|
1 Jonathan Hooper <jonathan.hooper@gsa.gov>
|
66
|
+
1 John Haugeland <stonecypher@gmail.com>
|
62
67
|
1 John Croisant <jacius@gmail.com>
|
63
68
|
1 Joe Fiorini <joe@faithfulgeek.org>
|
64
69
|
1 Jens Kraemer <jk@jkraemer.net>
|
70
|
+
1 Jay Stramel <js@ionactual.com>
|
65
71
|
1 Hirofumi Wakasugi <baenej@gmail.com>
|
66
72
|
1 Hector Correa <hector@hectorcorrea.com>
|
67
73
|
1 Florian Klampfer <f.klampfer@gmail.com>
|
@@ -72,13 +78,16 @@
|
|
72
78
|
1 Daniel Bair <daniel@danielbair.com>
|
73
79
|
1 Damien Pollet <damien.pollet@gmail.com>
|
74
80
|
1 Christopher Jefferson <caj21@st-andrews.ac.uk>
|
81
|
+
1 Christian Boos <christian.boos@bct-technology.com>
|
75
82
|
1 Cédric Boutillier <cedric.boutillier@gmail.com>
|
76
83
|
1 Bob Lail <lail@squareup.com>
|
84
|
+
1 Ashesh Kumar Singh <user501254@gmail.com>
|
77
85
|
1 Ashe Connor <ashe@kivikakk.ee>
|
78
86
|
1 aschmitz <29508+aschmitz@users.noreply.github.com>
|
79
87
|
1 Antoine Cotten <hello@acotten.com>
|
80
88
|
1 Andrew <andrew.dale.wylie@gmail.com>
|
81
89
|
1 Alpha Chen <alpha.chen@gmail.com>
|
82
90
|
1 Alex Tomlins <alex.tomlins@digital.cabinet-office.gov.uk>
|
91
|
+
1 Alex Taylor <alex@alextaylor.ca>
|
83
92
|
1 Alexey Vasiliev <le0pard@users.noreply.github.com>
|
84
93
|
1 284km <k.furuhashi10@gmail.com>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.0
|
data/bin/kramdown
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# -*- coding: utf-8 -*-
|
2
|
+
# -*- coding: utf-8; frozen_string_literal: true -*-
|
3
3
|
#
|
4
4
|
#--
|
5
5
|
# Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
|
@@ -36,7 +36,7 @@ def add_kramdown_options(opts, parsed_options, banner: [], ignore: [])
|
|
36
36
|
opts.on("--#{no} ARG", type) {|v| parsed_options[n] = Kramdown::Options.parse(n, v) }
|
37
37
|
end
|
38
38
|
|
39
|
-
definition.desc.split(
|
39
|
+
definition.desc.split("\n").each do |line|
|
40
40
|
opts.separator opts.summary_indent + ' ' * 6 + line
|
41
41
|
end
|
42
42
|
opts.separator ''
|
@@ -78,14 +78,12 @@ OptionParser.new do |opts|
|
|
78
78
|
"prefix) separated", "by commas (e.g. parser-gfm,syntax-coderay)",
|
79
79
|
"Note: Use this option before other options!") do |exts|
|
80
80
|
exts.each do |ext|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
$stderr.puts "Couldn't load extension #{ext}, ignoring"
|
88
|
-
end
|
81
|
+
require "kramdown-#{ext}"
|
82
|
+
new_options = add_kramdown_options(opts, options, banner: ["#{ext} options:"],
|
83
|
+
ignore: defined_options)
|
84
|
+
defined_options.concat(new_options)
|
85
|
+
rescue LoadError
|
86
|
+
$stderr.puts "Couldn't load extension #{ext}, ignoring"
|
89
87
|
end
|
90
88
|
end
|
91
89
|
opts.separator ""
|
@@ -101,7 +99,7 @@ OptionParser.new do |opts|
|
|
101
99
|
exit
|
102
100
|
end
|
103
101
|
opts.on("-h", "--help", "Show the help") do
|
104
|
-
puts opts.summarize('', 5, 72)
|
102
|
+
puts opts.summarize(+'', 5, 72)
|
105
103
|
exit
|
106
104
|
end
|
107
105
|
|
@@ -111,7 +109,12 @@ end.parse!
|
|
111
109
|
|
112
110
|
begin
|
113
111
|
if config_file && File.exist?(config_file)
|
114
|
-
config_file_options =
|
112
|
+
config_file_options =
|
113
|
+
if YAML.method(:safe_load).parameters.include?(%i[key permitted_classes])
|
114
|
+
YAML.safe_load(File.read(config_file), permitted_classes: [Symbol])
|
115
|
+
else # compatibility with Psych < 3.1.0
|
116
|
+
YAML.safe_load(File.read(config_file), [Symbol])
|
117
|
+
end
|
115
118
|
case config_file_options
|
116
119
|
when nil # empty configuration file except perhaps YAML header and comments
|
117
120
|
# Nothing to do
|
@@ -137,7 +137,7 @@ module Kramdown
|
|
137
137
|
|
138
138
|
# Return the template specified by +template+.
|
139
139
|
def self.get_template(template) # :nodoc:
|
140
|
-
format_ext = '.' + ::Kramdown::Utils.snake_case(
|
140
|
+
format_ext = '.' + ::Kramdown::Utils.snake_case(name.split("::").last)
|
141
141
|
shipped = File.join(::Kramdown.data_dir, template + format_ext)
|
142
142
|
if File.exist?(template)
|
143
143
|
File.read(template)
|
@@ -146,7 +146,7 @@ module Kramdown
|
|
146
146
|
elsif File.exist?(shipped)
|
147
147
|
File.read(shipped)
|
148
148
|
elsif template.start_with?('string://')
|
149
|
-
template.
|
149
|
+
template.delete_prefix("string://")
|
150
150
|
else
|
151
151
|
raise "The specified template file #{template} does not exist"
|
152
152
|
end
|
@@ -100,8 +100,12 @@ module Kramdown
|
|
100
100
|
figure_attr = el.attr.dup
|
101
101
|
image_attr = el.children.first.attr.dup
|
102
102
|
|
103
|
-
|
104
|
-
|
103
|
+
if image_attr.key?('class') && !figure_attr.key?('class')
|
104
|
+
figure_attr['class'] = image_attr.delete('class')
|
105
|
+
end
|
106
|
+
if image_attr.key?('id') && !figure_attr.key?('id')
|
107
|
+
figure_attr['id'] = image_attr.delete('id')
|
108
|
+
end
|
105
109
|
|
106
110
|
body = "#{' ' * (indent + @indent)}<img#{html_attributes(image_attr)} />\n" \
|
107
111
|
"#{' ' * (indent + @indent)}<figcaption>#{image_attr['alt']}</figcaption>\n"
|
@@ -128,7 +132,7 @@ module Kramdown
|
|
128
132
|
when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>"
|
129
133
|
when " " then "<span class=\"ws-space#{suffix}\">⋅</span>"
|
130
134
|
end
|
131
|
-
end.join
|
135
|
+
end.join
|
132
136
|
end
|
133
137
|
end
|
134
138
|
code_attr = {}
|
@@ -147,6 +151,13 @@ module Kramdown
|
|
147
151
|
if @options[:auto_ids] && !attr['id']
|
148
152
|
attr['id'] = generate_id(el.options[:raw_text])
|
149
153
|
end
|
154
|
+
|
155
|
+
if @options[:header_links] && attr['id'].to_s.length > 0
|
156
|
+
link = Element.new(:a, nil, nil)
|
157
|
+
link.attr['href'] = "##{attr['id']}"
|
158
|
+
el.children.unshift(link)
|
159
|
+
end
|
160
|
+
|
150
161
|
@toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el)
|
151
162
|
level = output_header_level(el.options[:level])
|
152
163
|
format_as_block_html("h#{level}", attr, inner(el, indent), indent)
|
@@ -179,7 +190,7 @@ module Kramdown
|
|
179
190
|
output = ' ' * indent << "<#{el.type}" << html_attributes(el.attr) << ">"
|
180
191
|
res = inner(el, indent)
|
181
192
|
if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent])
|
182
|
-
output << res << (res
|
193
|
+
output << res << (res.match?(/\n\Z/) ? ' ' * indent : '')
|
183
194
|
else
|
184
195
|
output << "\n" << res << ' ' * indent
|
185
196
|
end
|
@@ -303,9 +314,10 @@ module Kramdown
|
|
303
314
|
@footnotes << [name, el.value, number, 0]
|
304
315
|
@footnotes_by_name[name] = @footnotes.last
|
305
316
|
end
|
306
|
-
|
307
|
-
|
308
|
-
"#{
|
317
|
+
formatted_link_text = sprintf(@options[:footnote_link_text], number)
|
318
|
+
"<sup id=\"fnref:#{name}#{repeat}\">" \
|
319
|
+
"<a href=\"#fn:#{name}\" class=\"footnote\" rel=\"footnote\" role=\"doc-noteref\">" \
|
320
|
+
"#{formatted_link_text}</a></sup>"
|
309
321
|
end
|
310
322
|
|
311
323
|
def convert_raw(el, _indent)
|
@@ -340,7 +352,7 @@ module Kramdown
|
|
340
352
|
if (result = @options[:typographic_symbols][el.value])
|
341
353
|
escape_html(result, :text)
|
342
354
|
else
|
343
|
-
TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e) }.join
|
355
|
+
TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e) }.join
|
344
356
|
end
|
345
357
|
end
|
346
358
|
|
@@ -378,11 +390,7 @@ module Kramdown
|
|
378
390
|
end
|
379
391
|
if @toc_code
|
380
392
|
toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {})
|
381
|
-
text =
|
382
|
-
convert(toc_tree, 0)
|
383
|
-
else
|
384
|
-
''
|
385
|
-
end
|
393
|
+
text = toc_tree.children.empty? ? '' : convert(toc_tree, 0)
|
386
394
|
result.sub!(/#{@toc_code.last}/, text.gsub(/\\/, "\\\\\\\\"))
|
387
395
|
end
|
388
396
|
result
|
@@ -492,7 +500,7 @@ module Kramdown
|
|
492
500
|
backlink_text = escape_html(@options[:footnote_backlink], :text)
|
493
501
|
while i < @footnotes.length
|
494
502
|
name, data, _, repeat = *@footnotes[i]
|
495
|
-
li = Element.new(:li, nil, 'id' => "fn:#{name}"
|
503
|
+
li = Element.new(:li, nil, 'id' => "fn:#{name}")
|
496
504
|
li.children = Marshal.load(Marshal.dump(data.children))
|
497
505
|
|
498
506
|
para = nil
|
@@ -45,7 +45,8 @@ module Kramdown
|
|
45
45
|
elsif el.block? &&
|
46
46
|
![:li, :dd, :dt, :td, :th, :tr, :thead, :tbody, :tfoot, :blank].include?(el.type) &&
|
47
47
|
(el.type != :html_element || @stack.last.type != :html_element) &&
|
48
|
-
(el.type != :p || !el.options[:transparent])
|
48
|
+
(el.type != :p || !el.options[:transparent]) &&
|
49
|
+
!([:ul, :dl, :ol].include?(el.type) && @stack.last.type == :li)
|
49
50
|
res << "\n"
|
50
51
|
end
|
51
52
|
res
|
@@ -71,27 +72,30 @@ module Kramdown
|
|
71
72
|
""
|
72
73
|
end
|
73
74
|
|
74
|
-
ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]
|
75
|
+
ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]{"'|])|^ {0,3}(:)/
|
75
76
|
|
76
77
|
def convert_text(el, opts)
|
77
|
-
if opts[:raw_text]
|
78
|
+
if opts[:raw_text] || (@stack.last.type == :html_element && @stack.last.options[:content_model] == :raw)
|
78
79
|
el.value
|
79
80
|
else
|
80
|
-
el.value.gsub(/\A\n/) do
|
81
|
+
result = el.value.gsub(/\A\n/) do
|
81
82
|
opts[:prev] && opts[:prev].type == :br ? '' : "\n"
|
82
|
-
end
|
83
|
+
end
|
84
|
+
result.gsub!(/\s+/, ' ') unless el.options[:cdata]
|
85
|
+
result.gsub!(ESCAPED_CHAR_RE) do
|
83
86
|
$1 || !opts[:prev] || opts[:prev].type == :br ? "\\#{$1 || $2}" : $&
|
84
87
|
end
|
88
|
+
result
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
88
92
|
def convert_p(el, opts)
|
89
93
|
w = @options[:line_width] - opts[:indent].to_s.to_i
|
90
94
|
first, second, *rest = inner(el, opts).strip.gsub(/(.{1,#{w}})( +|$\n?)/, "\\1\n").split(/\n/)
|
91
|
-
first&.gsub!(/^(?:(#|>)|(\d+)
|
95
|
+
first&.gsub!(/^(?:(#|>)|(\d+)\.(\s)|([+-]\s))/) { $1 || $4 ? "\\#{$1 || $4}" : "#{$2}\\.#{$3}" }
|
92
96
|
second&.gsub!(/^([=-]+\s*?)$/, "\\\1")
|
93
97
|
res = [first, second, *rest].compact.join("\n") + "\n"
|
94
|
-
res.gsub!(/^
|
98
|
+
res.gsub!(/^ {0,3}:/, "\\:")
|
95
99
|
if el.children.length == 1 && el.children.first.type == :math
|
96
100
|
res = "\\#{res}"
|
97
101
|
elsif res.start_with?('\$$') && res.end_with?("\\$$\n")
|
@@ -101,15 +105,16 @@ module Kramdown
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def convert_codeblock(el, _opts)
|
104
|
-
el.value.split(
|
108
|
+
el.value.split("\n").map {|l| l.empty? ? " " : " #{l}" }.join("\n") + "\n"
|
105
109
|
end
|
106
110
|
|
107
111
|
def convert_blockquote(el, opts)
|
108
112
|
opts[:indent] += 2
|
109
|
-
inner(el, opts).chomp.split(
|
113
|
+
inner(el, opts).chomp.split("\n").map {|l| "> #{l}" }.join("\n") << "\n"
|
110
114
|
end
|
111
115
|
|
112
116
|
def convert_header(el, opts)
|
117
|
+
opts[:in_header] = true
|
113
118
|
res = +''
|
114
119
|
res << "#{'#' * output_header_level(el.options[:level])} #{inner(el, opts)}"
|
115
120
|
res[-1, 1] = "\\#" if res[-1] == '#'
|
@@ -140,13 +145,13 @@ module Kramdown
|
|
140
145
|
opts[:indent] += width
|
141
146
|
text = inner(el, opts)
|
142
147
|
newlines = text.scan(/\n*\Z/).first
|
143
|
-
first, *last = text.split(
|
148
|
+
first, *last = text.split("\n")
|
144
149
|
last = last.map {|l| " " * width + l }.join("\n")
|
145
150
|
text = (first.nil? ? "\n" : first + (last.empty? ? "" : "\n") + last + newlines)
|
146
151
|
if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
|
147
152
|
res = +"#{sym}#{text}"
|
148
153
|
res << "^\n" if el.children.size == 1 && @stack.last.children.last == el &&
|
149
|
-
(@stack.last.children.any? {|c| c.children.first.type != :p } || @stack.last.children.size == 1)
|
154
|
+
(@stack.last.children.any? {|c| !c.children.first || c.children.first.type != :p } || @stack.last.children.size == 1)
|
150
155
|
res
|
151
156
|
elsif el.children.first && el.children.first.type == :codeblock
|
152
157
|
"#{sym}\n #{text}"
|
@@ -164,7 +169,7 @@ module Kramdown
|
|
164
169
|
opts[:indent] += width
|
165
170
|
text = inner(el, opts)
|
166
171
|
newlines = text.scan(/\n*\Z/).first
|
167
|
-
first, *last = text.split(
|
172
|
+
first, *last = text.split("\n")
|
168
173
|
last = last.map {|l| " " * width + l }.join("\n")
|
169
174
|
text = first.to_s + (last.empty? ? "" : "\n") + last + newlines
|
170
175
|
text.chomp! if text =~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dd
|
@@ -187,7 +192,7 @@ module Kramdown
|
|
187
192
|
result << inner(el, opts) << "\n"
|
188
193
|
end
|
189
194
|
|
190
|
-
HTML_TAGS_WITH_BODY = [
|
195
|
+
HTML_TAGS_WITH_BODY = %w[div script iframe textarea th td]
|
191
196
|
|
192
197
|
HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze
|
193
198
|
private_constant :HTML_ELEMENT_TYPES
|
@@ -243,7 +248,7 @@ module Kramdown
|
|
243
248
|
|
244
249
|
def convert_thead(el, opts)
|
245
250
|
rows = inner(el, opts)
|
246
|
-
if opts[:alignment].all?
|
251
|
+
if opts[:alignment].all?(:default)
|
247
252
|
"#{rows}|#{'-' * 10}\n"
|
248
253
|
else
|
249
254
|
"#{rows}| " + opts[:alignment].map do |a|
|
@@ -284,8 +289,8 @@ module Kramdown
|
|
284
289
|
end
|
285
290
|
end
|
286
291
|
|
287
|
-
def convert_br(_el,
|
288
|
-
" \n"
|
292
|
+
def convert_br(_el, opts)
|
293
|
+
opts[:in_header] ? "<br />" : " \n"
|
289
294
|
end
|
290
295
|
|
291
296
|
def convert_a(el, opts)
|
@@ -367,7 +372,7 @@ module Kramdown
|
|
367
372
|
end
|
368
373
|
|
369
374
|
def convert_smart_quote(el, _opts)
|
370
|
-
el.value.to_s
|
375
|
+
el.value.to_s.match?(/[rl]dquo/) ? "\"" : "'"
|
371
376
|
end
|
372
377
|
|
373
378
|
def convert_math(el, _opts)
|
@@ -400,7 +405,7 @@ module Kramdown
|
|
400
405
|
res = +''
|
401
406
|
@footnotes.each do |name, data|
|
402
407
|
res << "[^#{name}]:\n"
|
403
|
-
res << inner(data).chomp.split(
|
408
|
+
res << inner(data).chomp.split("\n").map {|l| " #{l}" }.join("\n") + "\n\n"
|
404
409
|
end
|
405
410
|
res
|
406
411
|
end
|
@@ -422,14 +427,14 @@ module Kramdown
|
|
422
427
|
next if el.type == :header && k == 'id' && !v.strip.empty?
|
423
428
|
if v.nil?
|
424
429
|
''
|
425
|
-
elsif k == 'class' && !v.empty? && !v.index(/[
|
430
|
+
elsif k == 'class' && !v.empty? && !v.index(/[.#]/)
|
426
431
|
" " + v.split(/\s+/).map {|w| ".#{w}" }.join(" ")
|
427
432
|
elsif k == 'id' && !v.strip.empty?
|
428
433
|
" ##{v}"
|
429
434
|
else
|
430
435
|
" #{k}=\"#{v}\""
|
431
436
|
end
|
432
|
-
end.compact.join
|
437
|
+
end.compact.join
|
433
438
|
res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
434
439
|
el.options.dig(:ial, :refs)&.include?('toc')
|
435
440
|
res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
@@ -59,7 +59,7 @@ module Kramdown
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def convert_blank(_el, opts)
|
62
|
-
opts[:result]
|
62
|
+
opts[:result].match?(/\n\n\Z|\A\Z/) ? "" : "\n"
|
63
63
|
end
|
64
64
|
|
65
65
|
def convert_text(el, _opts)
|
@@ -153,9 +153,10 @@ module Kramdown
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def convert_html_element(el, opts)
|
156
|
-
|
156
|
+
case el.value
|
157
|
+
when 'i', 'em'
|
157
158
|
"\\emph{#{inner(el, opts)}}"
|
158
|
-
|
159
|
+
when 'b', 'strong'
|
159
160
|
"\\textbf{#{inner(el, opts)}}"
|
160
161
|
else
|
161
162
|
warning("Can't convert HTML element")
|
@@ -164,7 +165,7 @@ module Kramdown
|
|
164
165
|
end
|
165
166
|
|
166
167
|
def convert_xml_comment(el, _opts)
|
167
|
-
el.value.split(
|
168
|
+
el.value.split("\n").map {|l| "% #{l}" }.join("\n") + "\n"
|
168
169
|
end
|
169
170
|
|
170
171
|
def convert_xml_pi(_el, _opts)
|
@@ -203,7 +204,7 @@ module Kramdown
|
|
203
204
|
end
|
204
205
|
|
205
206
|
def convert_comment(el, _opts)
|
206
|
-
el.value.split(
|
207
|
+
el.value.split("\n").map {|l| "% #{l}" }.join("\n") << "\n"
|
207
208
|
end
|
208
209
|
|
209
210
|
def convert_br(_el, opts)
|
@@ -224,7 +225,7 @@ module Kramdown
|
|
224
225
|
|
225
226
|
def convert_img(el, _opts)
|
226
227
|
line = el.options[:location]
|
227
|
-
if el.attr['src']
|
228
|
+
if el.attr['src'].match?(/^(https?|ftps?):\/\//)
|
228
229
|
warning("Cannot include non-local image#{line ? " (line #{line})" : ''}")
|
229
230
|
''
|
230
231
|
elsif !el.attr['src'].empty?
|
@@ -556,7 +557,7 @@ module Kramdown
|
|
556
557
|
def convert_math(el, _opts)
|
557
558
|
@data[:packages] += %w[amssymb amsmath amsthm amsfonts]
|
558
559
|
if el.options[:category] == :block
|
559
|
-
if el.value
|
560
|
+
if el.value.match?(/\A\s*\\begin\{/)
|
560
561
|
el.value
|
561
562
|
else
|
562
563
|
latex_environment('displaymath', el, el.value)
|
@@ -573,7 +574,7 @@ module Kramdown
|
|
573
574
|
|
574
575
|
# Normalize the abbreviation key so that it only contains allowed ASCII character
|
575
576
|
def normalize_abbreviation_key(key)
|
576
|
-
key.gsub(/\W/) {|m| m.
|
577
|
+
key.gsub(/\W/) {|m| m.unpack1('H*') }
|
577
578
|
end
|
578
579
|
|
579
580
|
# Wrap the +text+ inside a LaTeX environment of type +type+. The element +el+ is passed on to
|
@@ -597,7 +598,7 @@ module Kramdown
|
|
597
598
|
|
598
599
|
# Return a LaTeX comment containing all attributes as 'key="value"' pairs.
|
599
600
|
def attribute_list(el)
|
600
|
-
attrs = el.attr.map {|k, v| v.nil? ? '' : " #{k}=\"#{v}\"" }.compact.sort.join
|
601
|
+
attrs = el.attr.map {|k, v| v.nil? ? '' : " #{k}=\"#{v}\"" }.compact.sort.join
|
601
602
|
attrs = " % #{attrs}" unless attrs.empty?
|
602
603
|
attrs
|
603
604
|
end
|
@@ -611,7 +612,7 @@ module Kramdown
|
|
611
612
|
">" => "\\textgreater{}",
|
612
613
|
"[" => "{[}",
|
613
614
|
"]" => "{]}",
|
614
|
-
}.merge(Hash[*
|
615
|
+
}.merge(Hash[*"{}$%&_#".each_char.map {|c| [c, "\\#{c}"] }.flatten]) # :nodoc:
|
615
616
|
ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k, _v| k }) # :nodoc:
|
616
617
|
|
617
618
|
# Escape the special LaTeX characters in the string +str+.
|
@@ -17,7 +17,7 @@ module Kramdown
|
|
17
17
|
# man-pages(7) for information regarding the output.
|
18
18
|
class Man < Base
|
19
19
|
|
20
|
-
def convert(el, opts = {indent: 0, result: +''})
|
20
|
+
def convert(el, opts = {indent: 0, result: +''}) # :nodoc:
|
21
21
|
send("convert_#{el.type}", el, opts)
|
22
22
|
end
|
23
23
|
|
@@ -139,7 +139,7 @@ module Kramdown
|
|
139
139
|
def convert_table(el, opts)
|
140
140
|
opts[:alignment] = el.options[:alignment].map {|a| TABLE_CELL_ALIGNMENT[a] }
|
141
141
|
table_options = ["box"]
|
142
|
-
table_options << "center" if el.attr['class']
|
142
|
+
table_options << "center" if el.attr['class']&.match?(/\bcenter\b/)
|
143
143
|
opts[:result] << macro("TS") << "#{table_options.join(' ')} ;\n"
|
144
144
|
inner(el, opts)
|
145
145
|
opts[:result] << macro("TE") << macro("sp")
|
@@ -171,7 +171,7 @@ module Kramdown
|
|
171
171
|
result = opts[:result]
|
172
172
|
opts[:result] = +''
|
173
173
|
inner(el, opts)
|
174
|
-
if opts[:result]
|
174
|
+
if opts[:result].include?("\n")
|
175
175
|
warning("Table cells using links are not supported")
|
176
176
|
result << "\t"
|
177
177
|
else
|
@@ -17,7 +17,7 @@ module Kramdown::Converter::MathEngine
|
|
17
17
|
|
18
18
|
def self.call(converter, el, opts)
|
19
19
|
value = converter.escape_html(el.value)
|
20
|
-
result = el.options[:category] == :block ?
|
20
|
+
result = el.options[:category] == :block ? "\\[#{value}\\]\n" : "\\(#{value}\\)"
|
21
21
|
if el.attr.empty?
|
22
22
|
result
|
23
23
|
elsif el.options[:category] == :block
|
@@ -35,12 +35,13 @@ module Kramdown
|
|
35
35
|
children = el.children.dup
|
36
36
|
index = 0
|
37
37
|
while index < children.length
|
38
|
-
if
|
39
|
-
(children[index].type == :html_element &&
|
38
|
+
if children[index].type == :xml_pi ||
|
39
|
+
(children[index].type == :html_element && (children[index].value == 'style' ||
|
40
|
+
children[index].value == 'script'))
|
40
41
|
children[index..index] = []
|
41
42
|
elsif children[index].type == :html_element &&
|
42
|
-
|
43
|
-
|
43
|
+
((@options[:remove_block_html_tags] && children[index].options[:category] == :block) ||
|
44
|
+
(@options[:remove_span_html_tags] && children[index].options[:category] == :span))
|
44
45
|
children[index..index] = children[index].children
|
45
46
|
else
|
46
47
|
convert(children[index])
|
data/lib/kramdown/document.rb
CHANGED
data/lib/kramdown/element.rb
CHANGED