kramdown 2.3.2 → 2.5.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.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +11 -2
- data/VERSION +1 -1
- data/bin/kramdown +15 -12
- data/lib/kramdown/converter/base.rb +2 -2
- data/lib/kramdown/converter/html.rb +23 -15
- data/lib/kramdown/converter/kramdown.rb +31 -21
- 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 +50 -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 +25 -0
- data/test/test_files.rb +11 -0
- data/test/testcases/block/03_paragraph/to_kramdown.kramdown +7 -0
- data/test/testcases/block/03_paragraph/to_kramdown.text +5 -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 +23 -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>
|
@@ -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>
|
@@ -20,10 +21,11 @@
|
|
20
21
|
2 Nathanael Jones <nathanael.jones@gmail.com>
|
21
22
|
2 Max Meyer <dev@fedux.org>
|
22
23
|
2 Jo Hund <jhund@clearcove.ca>
|
23
|
-
2
|
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
|
@@ -283,7 +294,7 @@ module Kramdown
|
|
283
294
|
hl_opts = {}
|
284
295
|
result = highlight_code(el.value, lang, :span, hl_opts)
|
285
296
|
if result
|
286
|
-
add_syntax_highlighter_to_class_attr(attr, hl_opts[:default_lang])
|
297
|
+
add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang])
|
287
298
|
else
|
288
299
|
result = escape_html(el.value)
|
289
300
|
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
|
@@ -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})
|
@@ -43,7 +45,8 @@ module Kramdown
|
|
43
45
|
elsif el.block? &&
|
44
46
|
![:li, :dd, :dt, :td, :th, :tr, :thead, :tbody, :tfoot, :blank].include?(el.type) &&
|
45
47
|
(el.type != :html_element || @stack.last.type != :html_element) &&
|
46
|
-
(el.type != :p || !el.options[:transparent])
|
48
|
+
(el.type != :p || !el.options[:transparent]) &&
|
49
|
+
!([:ul, :dl, :ol].include?(el.type) && @stack.last.type == :li)
|
47
50
|
res << "\n"
|
48
51
|
end
|
49
52
|
res
|
@@ -69,24 +72,30 @@ module Kramdown
|
|
69
72
|
""
|
70
73
|
end
|
71
74
|
|
72
|
-
ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]
|
75
|
+
ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]{"'|])|^ {0,3}(:)/
|
73
76
|
|
74
77
|
def convert_text(el, opts)
|
75
|
-
if opts[:raw_text]
|
78
|
+
if opts[:raw_text] || (@stack.last.type == :html_element && @stack.last.options[:content_model] == :raw)
|
76
79
|
el.value
|
77
80
|
else
|
78
|
-
el.value.gsub(/\A\n/) do
|
81
|
+
result = el.value.gsub(/\A\n/) do
|
79
82
|
opts[:prev] && opts[:prev].type == :br ? '' : "\n"
|
80
|
-
end
|
83
|
+
end
|
84
|
+
result.gsub!(/\s+/, ' ') unless el.options[:cdata]
|
85
|
+
result.gsub!(ESCAPED_CHAR_RE) do
|
86
|
+
$1 || !opts[:prev] || opts[:prev].type == :br ? "\\#{$1 || $2}" : $&
|
87
|
+
end
|
88
|
+
result
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
84
92
|
def convert_p(el, opts)
|
85
93
|
w = @options[:line_width] - opts[:indent].to_s.to_i
|
86
94
|
first, second, *rest = inner(el, opts).strip.gsub(/(.{1,#{w}})( +|$\n?)/, "\\1\n").split(/\n/)
|
87
|
-
first&.gsub!(/^(?:(#|>)|(\d+)
|
95
|
+
first&.gsub!(/^(?:(#|>)|(\d+)\.(\s)|([+-]\s))/) { $1 || $4 ? "\\#{$1 || $4}" : "#{$2}\\.#{$3}" }
|
88
96
|
second&.gsub!(/^([=-]+\s*?)$/, "\\\1")
|
89
97
|
res = [first, second, *rest].compact.join("\n") + "\n"
|
98
|
+
res.gsub!(/^ {0,3}:/, "\\:")
|
90
99
|
if el.children.length == 1 && el.children.first.type == :math
|
91
100
|
res = "\\#{res}"
|
92
101
|
elsif res.start_with?('\$$') && res.end_with?("\\$$\n")
|
@@ -96,15 +105,16 @@ module Kramdown
|
|
96
105
|
end
|
97
106
|
|
98
107
|
def convert_codeblock(el, _opts)
|
99
|
-
el.value.split(
|
108
|
+
el.value.split("\n").map {|l| l.empty? ? " " : " #{l}" }.join("\n") + "\n"
|
100
109
|
end
|
101
110
|
|
102
111
|
def convert_blockquote(el, opts)
|
103
112
|
opts[:indent] += 2
|
104
|
-
inner(el, opts).chomp.split(
|
113
|
+
inner(el, opts).chomp.split("\n").map {|l| "> #{l}" }.join("\n") << "\n"
|
105
114
|
end
|
106
115
|
|
107
116
|
def convert_header(el, opts)
|
117
|
+
opts[:in_header] = true
|
108
118
|
res = +''
|
109
119
|
res << "#{'#' * output_header_level(el.options[:level])} #{inner(el, opts)}"
|
110
120
|
res[-1, 1] = "\\#" if res[-1] == '#'
|
@@ -124,7 +134,7 @@ module Kramdown
|
|
124
134
|
|
125
135
|
def convert_li(el, opts)
|
126
136
|
sym, width = if @stack.last.type == :ul
|
127
|
-
[
|
137
|
+
['* ' + @list_spacing, el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent]
|
128
138
|
else
|
129
139
|
["#{opts[:index] + 1}.".ljust(4), 4]
|
130
140
|
end
|
@@ -135,13 +145,13 @@ module Kramdown
|
|
135
145
|
opts[:indent] += width
|
136
146
|
text = inner(el, opts)
|
137
147
|
newlines = text.scan(/\n*\Z/).first
|
138
|
-
first, *last = text.split(
|
148
|
+
first, *last = text.split("\n")
|
139
149
|
last = last.map {|l| " " * width + l }.join("\n")
|
140
150
|
text = (first.nil? ? "\n" : first + (last.empty? ? "" : "\n") + last + newlines)
|
141
151
|
if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
|
142
152
|
res = +"#{sym}#{text}"
|
143
153
|
res << "^\n" if el.children.size == 1 && @stack.last.children.last == el &&
|
144
|
-
(@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)
|
145
155
|
res
|
146
156
|
elsif el.children.first && el.children.first.type == :codeblock
|
147
157
|
"#{sym}\n #{text}"
|
@@ -151,7 +161,7 @@ module Kramdown
|
|
151
161
|
end
|
152
162
|
|
153
163
|
def convert_dd(el, opts)
|
154
|
-
sym, width =
|
164
|
+
sym, width = ": " + @list_spacing, (el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent)
|
155
165
|
if (ial = ial_for_element(el))
|
156
166
|
sym << ial << " "
|
157
167
|
end
|
@@ -159,7 +169,7 @@ module Kramdown
|
|
159
169
|
opts[:indent] += width
|
160
170
|
text = inner(el, opts)
|
161
171
|
newlines = text.scan(/\n*\Z/).first
|
162
|
-
first, *last = text.split(
|
172
|
+
first, *last = text.split("\n")
|
163
173
|
last = last.map {|l| " " * width + l }.join("\n")
|
164
174
|
text = first.to_s + (last.empty? ? "" : "\n") + last + newlines
|
165
175
|
text.chomp! if text =~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dd
|
@@ -182,7 +192,7 @@ module Kramdown
|
|
182
192
|
result << inner(el, opts) << "\n"
|
183
193
|
end
|
184
194
|
|
185
|
-
HTML_TAGS_WITH_BODY = [
|
195
|
+
HTML_TAGS_WITH_BODY = %w[div script iframe textarea th td]
|
186
196
|
|
187
197
|
HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze
|
188
198
|
private_constant :HTML_ELEMENT_TYPES
|
@@ -238,7 +248,7 @@ module Kramdown
|
|
238
248
|
|
239
249
|
def convert_thead(el, opts)
|
240
250
|
rows = inner(el, opts)
|
241
|
-
if opts[:alignment].all?
|
251
|
+
if opts[:alignment].all?(:default)
|
242
252
|
"#{rows}|#{'-' * 10}\n"
|
243
253
|
else
|
244
254
|
"#{rows}| " + opts[:alignment].map do |a|
|
@@ -279,8 +289,8 @@ module Kramdown
|
|
279
289
|
end
|
280
290
|
end
|
281
291
|
|
282
|
-
def convert_br(_el,
|
283
|
-
" \n"
|
292
|
+
def convert_br(_el, opts)
|
293
|
+
opts[:in_header] ? "<br />" : " \n"
|
284
294
|
end
|
285
295
|
|
286
296
|
def convert_a(el, opts)
|
@@ -362,7 +372,7 @@ module Kramdown
|
|
362
372
|
end
|
363
373
|
|
364
374
|
def convert_smart_quote(el, _opts)
|
365
|
-
el.value.to_s
|
375
|
+
el.value.to_s.match?(/[rl]dquo/) ? "\"" : "'"
|
366
376
|
end
|
367
377
|
|
368
378
|
def convert_math(el, _opts)
|
@@ -395,7 +405,7 @@ module Kramdown
|
|
395
405
|
res = +''
|
396
406
|
@footnotes.each do |name, data|
|
397
407
|
res << "[^#{name}]:\n"
|
398
|
-
res << inner(data).chomp.split(
|
408
|
+
res << inner(data).chomp.split("\n").map {|l| " #{l}" }.join("\n") + "\n\n"
|
399
409
|
end
|
400
410
|
res
|
401
411
|
end
|
@@ -417,14 +427,14 @@ module Kramdown
|
|
417
427
|
next if el.type == :header && k == 'id' && !v.strip.empty?
|
418
428
|
if v.nil?
|
419
429
|
''
|
420
|
-
elsif k == 'class' && !v.empty? && !v.index(/[
|
430
|
+
elsif k == 'class' && !v.empty? && !v.index(/[.#]/)
|
421
431
|
" " + v.split(/\s+/).map {|w| ".#{w}" }.join(" ")
|
422
432
|
elsif k == 'id' && !v.strip.empty?
|
423
433
|
" ##{v}"
|
424
434
|
else
|
425
435
|
" #{k}=\"#{v}\""
|
426
436
|
end
|
427
|
-
end.compact.join
|
437
|
+
end.compact.join
|
428
438
|
res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
429
439
|
el.options.dig(:ial, :refs)&.include?('toc')
|
430
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