kramdown 2.1.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +19 -3
- data/README.md +8 -2
- data/VERSION +1 -1
- data/lib/kramdown/converter/base.rb +2 -1
- data/lib/kramdown/converter/html.rb +37 -30
- data/lib/kramdown/converter/kramdown.rb +20 -10
- data/lib/kramdown/converter/latex.rb +2 -2
- data/lib/kramdown/converter/math_engine/mathjax.rb +7 -33
- data/lib/kramdown/converter/syntax_highlighter/rouge.rb +17 -9
- data/lib/kramdown/converter/syntax_highlighter.rb +1 -1
- data/lib/kramdown/element.rb +24 -0
- data/lib/kramdown/options.rb +62 -12
- data/lib/kramdown/parser/base.rb +3 -1
- data/lib/kramdown/parser/html.rb +16 -9
- data/lib/kramdown/parser/kramdown/abbreviation.rb +1 -1
- data/lib/kramdown/parser/kramdown/autolink.rb +2 -2
- data/lib/kramdown/parser/kramdown/codespan.rb +18 -4
- data/lib/kramdown/parser/kramdown/emphasis.rb +1 -1
- data/lib/kramdown/parser/kramdown/extensions.rb +6 -0
- data/lib/kramdown/parser/kramdown/header.rb +3 -2
- data/lib/kramdown/parser/kramdown/html.rb +4 -10
- data/lib/kramdown/parser/kramdown/list.rb +37 -9
- data/lib/kramdown/parser/kramdown/math.rb +1 -1
- data/lib/kramdown/parser/kramdown/table.rb +2 -2
- data/lib/kramdown/parser/kramdown.rb +8 -1
- data/lib/kramdown/utils/html.rb +9 -0
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +23 -0
- data/test/test_files.rb +28 -18
- data/test/test_location.rb +2 -2
- data/test/test_string_scanner_kramdown.rb +1 -1
- data/test/testcases/block/03_paragraph/standalone_image.html +5 -0
- data/test/testcases/block/03_paragraph/standalone_image.text +3 -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/atx_header.html +6 -0
- data/test/testcases/block/04_header/atx_header.text +6 -0
- data/test/testcases/block/06_codeblock/rouge/multiple.html +1 -1
- data/test/testcases/block/06_codeblock/rouge/simple.html +1 -1
- data/test/testcases/block/09_html/processing_instruction.html +5 -6
- data/test/testcases/block/09_html/standalone_image_in_div.htmlinput +7 -0
- data/test/testcases/block/09_html/standalone_image_in_div.text +8 -0
- data/test/testcases/block/09_html/table.kramdown +8 -0
- data/test/testcases/block/09_html/table.text +7 -0
- data/test/testcases/block/12_extension/options.html +4 -4
- data/test/testcases/block/12_extension/options.text +2 -0
- data/test/testcases/block/12_extension/options2.html +4 -4
- data/test/testcases/block/14_table/table_with_footnote.html +4 -4
- data/test/testcases/block/15_math/gh_128.html +1 -2
- data/test/testcases/block/15_math/normal.html +16 -15
- data/test/testcases/block/16_toc/toc_with_footnotes.html +4 -4
- data/test/testcases/cjk-line-break.html +4 -0
- data/test/testcases/cjk-line-break.options +1 -0
- data/test/testcases/cjk-line-break.text +12 -0
- data/test/testcases/man/example.man +1 -1
- data/test/testcases/man/example.text +1 -1
- data/test/testcases/span/02_emphasis/normal.html +4 -0
- data/test/testcases/span/02_emphasis/normal.text +4 -0
- data/test/testcases/span/03_codespan/normal.html +4 -0
- data/test/testcases/span/03_codespan/normal.text +4 -0
- data/test/testcases/span/04_footnote/backlink_inline.html +21 -21
- data/test/testcases/span/04_footnote/backlink_text.html +4 -4
- data/test/testcases/span/04_footnote/footnote_nr.html +6 -6
- data/test/testcases/span/04_footnote/footnote_prefix.html +6 -6
- data/test/testcases/span/04_footnote/inside_footnote.html +9 -9
- data/test/testcases/span/04_footnote/markers.html +16 -16
- data/test/testcases/span/04_footnote/placement.html +4 -4
- data/test/testcases/span/04_footnote/regexp_problem.html +4 -4
- data/test/testcases/span/04_footnote/without_backlink.html +3 -3
- data/test/testcases/span/05_html/normal.html +1 -1
- data/test/testcases/span/abbreviations/abbrev_in_html.html +9 -0
- data/test/testcases/span/abbreviations/abbrev_in_html.text +10 -0
- data/test/testcases/span/abbreviations/in_footnote.html +4 -4
- data/test/testcases/span/math/normal.html +4 -4
- data/test/testcases/span/text_substitutions/entities.html +1 -1
- data/test/testcases/span/text_substitutions/entities.text +1 -1
- metadata +36 -15
- data/test/testcases/block/15_math/mathjax_preview.html +0 -4
- data/test/testcases/block/15_math/mathjax_preview.options +0 -2
- data/test/testcases/block/15_math/mathjax_preview.text +0 -5
- data/test/testcases/block/15_math/mathjax_preview_as_code.html +0 -4
- data/test/testcases/block/15_math/mathjax_preview_as_code.options +0 -3
- data/test/testcases/block/15_math/mathjax_preview_as_code.text +0 -5
- data/test/testcases/block/15_math/mathjax_preview_simple.html +0 -4
- data/test/testcases/block/15_math/mathjax_preview_simple.options +0 -2
- data/test/testcases/block/15_math/mathjax_preview_simple.text +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c41b216fbd6f50c68b10864bc3a98040f79641db9af8ced05eb43f7817335ad
|
4
|
+
data.tar.gz: ef3adb19cbfbe4586bf0ef4f14362ca843a7fe3331ff6dc990c270ff65cff000
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 483e269f858aadd6bf8e7bf2f49ec90ddfdcd9628aec17822eb7eefcfc21897eb19d258a84b6291611a38a5958a79013c2c656d35f7740b116923bd8624a2329
|
7
|
+
data.tar.gz: 5ffeef35cdfb994411414d62bd8b5fcf09fcea7d926069896248148575b88b4abbfdc1e5aab6da8dbe6f97c3e0a4921b391802e391ea3c76a646be7f64fbbbda
|
data/CONTRIBUTERS
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
Count Name
|
2
2
|
======= ====
|
3
|
-
|
3
|
+
964 Thomas Leitner <t_leitner@gmx.at>
|
4
|
+
18 Ashwin Maroli <ashmaroli@gmail.com>
|
4
5
|
7 Christian Cornelssen <ccorn@1tein.de>
|
5
6
|
6 Gioele Barabucci <gioele@svario.it>
|
7
|
+
5 Gleb Mazovetskiy <glex.spb@gmail.com>
|
6
8
|
4 Ted Pak <powerpak006@gmail.com>
|
7
9
|
4 Shuanglei Tao <tsl0922@gmail.com>
|
8
|
-
4 Gleb Mazovetskiy <glex.spb@gmail.com>
|
9
10
|
4 Dan Allen <dan.j.allen@gmail.com>
|
10
|
-
4 Ashwin Maroli <ashmaroli@gmail.com>
|
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>
|
17
|
+
3 Ashwin Maroli <ashmaroli@users.noreply.github.com>
|
16
18
|
3 Alex Marandon <contact@alexmarandon.com>
|
17
19
|
2 Tom Thorogood <me+github@tomthorogood.co.uk>
|
18
20
|
2 Parker Moore <parkrmoore@gmail.com>
|
@@ -26,20 +28,28 @@
|
|
26
28
|
1 utenmiki <utenmiki@gmail.com>
|
27
29
|
1 Trevor Wennblom <trevor@well.com>
|
28
30
|
1 tomykaira <tomykaira@gmail.com>
|
31
|
+
1 tom93 <tomlevy93@gmail.com>
|
32
|
+
1 Tobin Yehle <tobinyehle@gmail.com>
|
33
|
+
1 timcraft <mail@timcraft.com>
|
29
34
|
1 Tim Blair <tim@bla.ir>
|
30
35
|
1 Tim Besard <tim.besard@gmail.com>
|
31
36
|
1 Tim Bates <tim@rumpuslabs.com>
|
32
37
|
1 Sun Yaozhu <yzyzsun@gmail.com>
|
38
|
+
1 Stephen <stephengroat@users.noreply.github.com>
|
33
39
|
1 Stephen Crosby <stevecrozz@gmail.com>
|
40
|
+
1 Stan Hu <stanhu@gmail.com>
|
34
41
|
1 Simon Lydell <simon.lydell@gmail.com>
|
42
|
+
1 Simon Coffey <simon.coffey@futurelearn.com>
|
35
43
|
1 Shusaku NAKAZATO <cu393uc@gmail.com>
|
36
44
|
1 Sebastian Boehm <sebastian@sometimesfood.org>
|
37
45
|
1 scherr <maximilianscherr@gmail.com>
|
38
46
|
1 Postmodern <postmodern.mod3@gmail.com>
|
39
47
|
1 Pete Michaud <michaudp@gmail.com>
|
48
|
+
1 Noah Doersing <doersino@gmail.com>
|
40
49
|
1 myqlarson <myqlarson@gmail.com>
|
41
50
|
1 milo.simpson <milo.simpson@bazaarvoice.com>
|
42
51
|
1 Michal Till <michal.till@gmail.com>
|
52
|
+
1 Maxime Kjaer <maxime.kjaer@gmail.com>
|
43
53
|
1 Matt Hickford <matt.hickford@gmail.com>
|
44
54
|
1 Martyn Chamberlin <martyn@perfectioncoding.com>
|
45
55
|
1 Marek Tuchowski <marek@tuchowski.com.pl>
|
@@ -56,13 +66,19 @@
|
|
56
66
|
1 Hector Correa <hector@hectorcorrea.com>
|
57
67
|
1 Florian Klampfer <f.klampfer@gmail.com>
|
58
68
|
1 Floreal Morandat florealm@gmail.com <florealm@gmail.com>
|
69
|
+
1 Fangyi Zhou <me@fangyi.io>
|
59
70
|
1 Diego Galeota <diegobg123@gmail.com>
|
71
|
+
1 David Rodríguez <deivid.rodriguez@riseup.net>
|
72
|
+
1 Daniel Bair <daniel@danielbair.com>
|
60
73
|
1 Damien Pollet <damien.pollet@gmail.com>
|
61
74
|
1 Christopher Jefferson <caj21@st-andrews.ac.uk>
|
62
75
|
1 Cédric Boutillier <cedric.boutillier@gmail.com>
|
76
|
+
1 Bob Lail <lail@squareup.com>
|
63
77
|
1 Ashe Connor <ashe@kivikakk.ee>
|
78
|
+
1 aschmitz <29508+aschmitz@users.noreply.github.com>
|
64
79
|
1 Antoine Cotten <hello@acotten.com>
|
65
80
|
1 Andrew <andrew.dale.wylie@gmail.com>
|
66
81
|
1 Alpha Chen <alpha.chen@gmail.com>
|
67
82
|
1 Alex Tomlins <alex.tomlins@digital.cabinet-office.gov.uk>
|
68
83
|
1 Alexey Vasiliev <le0pard@users.noreply.github.com>
|
84
|
+
1 284km <k.furuhashi10@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
|
-
|
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.
|
1
|
+
2.4.0
|
@@ -106,7 +106,8 @@ module Kramdown
|
|
106
106
|
end
|
107
107
|
result = converter.convert(tree)
|
108
108
|
if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY
|
109
|
-
result.encode!(tree.options[:encoding]
|
109
|
+
result.encode!(tree.options[:encoding] ||
|
110
|
+
(raise ::Kramdown::Error, "Missing encoding option on root element"))
|
110
111
|
end
|
111
112
|
if !converter.options[:template].empty? && converter.apply_template_after?
|
112
113
|
result = apply_template(converter, result)
|
@@ -46,15 +46,16 @@ module Kramdown
|
|
46
46
|
@toc_code = nil
|
47
47
|
@indent = 2
|
48
48
|
@stack = []
|
49
|
-
end
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
# stash string representation of symbol to avoid allocations from multiple interpolations.
|
51
|
+
@highlighter_class = " highlighter-#{options[:syntax_highlighter]}"
|
52
|
+
@dispatcher = Hash.new {|h, k| h[k] = :"convert_#{k}" }
|
53
|
+
end
|
53
54
|
|
54
55
|
# Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of
|
55
56
|
# the element.
|
56
57
|
def convert(el, indent = -@indent)
|
57
|
-
send(
|
58
|
+
send(@dispatcher[el.type], el, indent)
|
58
59
|
end
|
59
60
|
|
60
61
|
# Return the converted content of the children of +el+ as a string. The parameter +indent+ has
|
@@ -67,7 +68,7 @@ module Kramdown
|
|
67
68
|
indent += @indent
|
68
69
|
@stack.push(el)
|
69
70
|
el.children.each do |inner_el|
|
70
|
-
result << send(
|
71
|
+
result << send(@dispatcher[inner_el.type], inner_el, indent)
|
71
72
|
end
|
72
73
|
@stack.pop
|
73
74
|
result
|
@@ -78,7 +79,8 @@ module Kramdown
|
|
78
79
|
end
|
79
80
|
|
80
81
|
def convert_text(el, _indent)
|
81
|
-
escape_html(el.value, :text)
|
82
|
+
escaped = escape_html(el.value, :text)
|
83
|
+
@options[:remove_line_breaks_for_cjk] ? fix_cjk_line_break(escaped) : escaped
|
82
84
|
end
|
83
85
|
|
84
86
|
def convert_p(el, indent)
|
@@ -86,21 +88,23 @@ module Kramdown
|
|
86
88
|
inner(el, indent)
|
87
89
|
elsif el.children.size == 1 && el.children.first.type == :img &&
|
88
90
|
el.children.first.options[:ial]&.[](:refs)&.include?('standalone')
|
89
|
-
convert_standalone_image(el
|
91
|
+
convert_standalone_image(el, indent)
|
90
92
|
else
|
91
|
-
format_as_block_html(
|
93
|
+
format_as_block_html("p", el.attr, inner(el, indent), indent)
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
97
|
# Helper method used by +convert_p+ to convert a paragraph that only contains a single :img
|
96
98
|
# element.
|
97
99
|
def convert_standalone_image(el, indent)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
figure_attr['
|
102
|
-
|
103
|
-
|
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"
|
104
108
|
format_as_indented_block_html("figure", figure_attr, body, indent)
|
105
109
|
end
|
106
110
|
|
@@ -135,7 +139,7 @@ module Kramdown
|
|
135
139
|
end
|
136
140
|
|
137
141
|
def convert_blockquote(el, indent)
|
138
|
-
format_as_indented_block_html(
|
142
|
+
format_as_indented_block_html("blockquote", el.attr, inner(el, indent), indent)
|
139
143
|
end
|
140
144
|
|
141
145
|
def convert_header(el, indent)
|
@@ -152,12 +156,15 @@ module Kramdown
|
|
152
156
|
"#{' ' * indent}<hr#{html_attributes(el.attr)} />\n"
|
153
157
|
end
|
154
158
|
|
159
|
+
ZERO_TO_ONETWENTYEIGHT = (0..128).to_a.freeze
|
160
|
+
private_constant :ZERO_TO_ONETWENTYEIGHT
|
161
|
+
|
155
162
|
def convert_ul(el, indent)
|
156
|
-
if !@toc_code &&
|
157
|
-
@toc_code = [el.type, el.attr,
|
163
|
+
if !@toc_code && el.options.dig(:ial, :refs)&.include?('toc')
|
164
|
+
@toc_code = [el.type, el.attr, ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join]
|
158
165
|
@toc_code.last
|
159
|
-
elsif !@footnote_location && el.options
|
160
|
-
@footnote_location =
|
166
|
+
elsif !@footnote_location && el.options.dig(:ial, :refs)&.include?('footnotes')
|
167
|
+
@footnote_location = ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join
|
161
168
|
else
|
162
169
|
format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
|
163
170
|
end
|
@@ -165,7 +172,7 @@ module Kramdown
|
|
165
172
|
alias convert_ol convert_ul
|
166
173
|
|
167
174
|
def convert_dl(el, indent)
|
168
|
-
format_as_indented_block_html(
|
175
|
+
format_as_indented_block_html("dl", el.attr, inner(el, indent), indent)
|
169
176
|
end
|
170
177
|
|
171
178
|
def convert_li(el, indent)
|
@@ -188,7 +195,7 @@ module Kramdown
|
|
188
195
|
break
|
189
196
|
end
|
190
197
|
end if !attr['id'] && @stack.last.options[:ial] && @stack.last.options[:ial][:refs]
|
191
|
-
format_as_block_html(
|
198
|
+
format_as_block_html("dt", attr, inner(el, indent), indent)
|
192
199
|
end
|
193
200
|
|
194
201
|
def convert_html_element(el, indent)
|
@@ -263,7 +270,7 @@ module Kramdown
|
|
263
270
|
end
|
264
271
|
|
265
272
|
def convert_a(el, indent)
|
266
|
-
format_as_span_html(
|
273
|
+
format_as_span_html("a", el.attr, inner(el, indent))
|
267
274
|
end
|
268
275
|
|
269
276
|
def convert_img(el, _indent)
|
@@ -276,7 +283,7 @@ module Kramdown
|
|
276
283
|
hl_opts = {}
|
277
284
|
result = highlight_code(el.value, lang, :span, hl_opts)
|
278
285
|
if result
|
279
|
-
add_syntax_highlighter_to_class_attr(attr, hl_opts[:default_lang])
|
286
|
+
add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang])
|
280
287
|
else
|
281
288
|
result = escape_html(el.value)
|
282
289
|
end
|
@@ -296,8 +303,8 @@ module Kramdown
|
|
296
303
|
@footnotes << [name, el.value, number, 0]
|
297
304
|
@footnotes_by_name[name] = @footnotes.last
|
298
305
|
end
|
299
|
-
"<sup id=\"fnref:#{name}#{repeat}\">" \
|
300
|
-
"<a href=\"#fn:#{name}\" class=\"footnote\">" \
|
306
|
+
"<sup id=\"fnref:#{name}#{repeat}\" role=\"doc-noteref\">" \
|
307
|
+
"<a href=\"#fn:#{name}\" class=\"footnote\" rel=\"footnote\">" \
|
301
308
|
"#{number}</a></sup>"
|
302
309
|
end
|
303
310
|
|
@@ -400,7 +407,7 @@ module Kramdown
|
|
400
407
|
# Add the syntax highlighter name to the 'class' attribute of the given attribute hash. And
|
401
408
|
# overwrites or add a "language-LANG" part using the +lang+ parameter if +lang+ is not nil.
|
402
409
|
def add_syntax_highlighter_to_class_attr(attr, lang = nil)
|
403
|
-
(attr['class'] = (attr['class'] || '') +
|
410
|
+
(attr['class'] = (attr['class'] || '') + @highlighter_class).lstrip!
|
404
411
|
attr['class'].sub!(/\blanguage-\S+|(^)/) { "language-#{lang}#{$1 ? ' ' : ''}" } if lang
|
405
412
|
end
|
406
413
|
|
@@ -475,9 +482,9 @@ module Kramdown
|
|
475
482
|
result
|
476
483
|
end
|
477
484
|
|
478
|
-
FOOTNOTE_BACKLINK_FMT = "%s<a href=\"#fnref:%s\" class=\"reversefootnote\">%s</a>"
|
485
|
+
FOOTNOTE_BACKLINK_FMT = "%s<a href=\"#fnref:%s\" class=\"reversefootnote\" role=\"doc-backlink\">%s</a>"
|
479
486
|
|
480
|
-
# Return
|
487
|
+
# Return an HTML ordered list with the footnote content for the used footnotes.
|
481
488
|
def footnote_content
|
482
489
|
ol = Element.new(:ol)
|
483
490
|
ol.attr['start'] = @footnote_start if @footnote_start != 1
|
@@ -485,7 +492,7 @@ module Kramdown
|
|
485
492
|
backlink_text = escape_html(@options[:footnote_backlink], :text)
|
486
493
|
while i < @footnotes.length
|
487
494
|
name, data, _, repeat = *@footnotes[i]
|
488
|
-
li = Element.new(:li, nil, 'id' => "fn:#{name}")
|
495
|
+
li = Element.new(:li, nil, 'id' => "fn:#{name}", 'role' => 'doc-endnote')
|
489
496
|
li.children = Marshal.load(Marshal.dump(data.children))
|
490
497
|
|
491
498
|
para = nil
|
@@ -520,7 +527,7 @@ module Kramdown
|
|
520
527
|
if ol.children.empty?
|
521
528
|
''
|
522
529
|
else
|
523
|
-
format_as_indented_block_html('div', {class: "footnotes"}, convert(ol, 2), 0)
|
530
|
+
format_as_indented_block_html('div', {class: "footnotes", role: "doc-endnotes"}, convert(ol, 2), 0)
|
524
531
|
end
|
525
532
|
end
|
526
533
|
|
@@ -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})
|
@@ -34,13 +36,13 @@ module Kramdown
|
|
34
36
|
res = res.dup if res.frozen?
|
35
37
|
if ![:html_element, :li, :dt, :dd, :td].include?(el.type) && (ial = ial_for_element(el))
|
36
38
|
res << ial
|
37
|
-
res << "\n\n" if
|
39
|
+
res << "\n\n" if el.block?
|
38
40
|
elsif [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] &&
|
39
41
|
([el.type, :codeblock].include?(opts[:next].type) ||
|
40
42
|
(opts[:next].type == :blank && opts[:nnext] &&
|
41
43
|
[el.type, :codeblock].include?(opts[:nnext].type)))
|
42
44
|
res << "^\n\n"
|
43
|
-
elsif
|
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
48
|
(el.type != :p || !el.options[:transparent])
|
@@ -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)
|
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
|
-
[
|
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 =
|
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,12 +187,17 @@ 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']
|
191
|
+
|
192
|
+
HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze
|
193
|
+
private_constant :HTML_ELEMENT_TYPES
|
186
194
|
|
187
195
|
def convert_html_element(el, opts)
|
188
196
|
markdown_attr = el.options[:category] == :block && el.children.any? do |c|
|
189
|
-
c.type != :html_element &&
|
190
|
-
|
197
|
+
c.type != :html_element &&
|
198
|
+
(c.type != :p || !c.options[:transparent] ||
|
199
|
+
c.children.any? {|t| !HTML_ELEMENT_TYPES.member?(t.type) }) &&
|
200
|
+
c.block?
|
191
201
|
end
|
192
202
|
opts[:force_raw_text] = true if %w[script pre code].include?(el.value)
|
193
203
|
opts[:raw_text] = opts[:force_raw_text] || opts[:block_raw_text] || \
|
@@ -421,9 +431,9 @@ module Kramdown
|
|
421
431
|
end
|
422
432
|
end.compact.join('')
|
423
433
|
res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
424
|
-
|
434
|
+
el.options.dig(:ial, :refs)&.include?('toc')
|
425
435
|
res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) &&
|
426
|
-
|
436
|
+
el.options.dig(:ial, :refs)&.include?('footnotes')
|
427
437
|
if el.type == :dl && el.options[:ial] && el.options[:ial][:refs]
|
428
438
|
auto_ids = el.options[:ial][:refs].select {|ref| ref.start_with?('auto_ids') }.join(" ")
|
429
439
|
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] &&
|
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] = "
|
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]
|
@@ -16,40 +16,14 @@ module Kramdown::Converter::MathEngine
|
|
16
16
|
module Mathjax
|
17
17
|
|
18
18
|
def self.call(converter, el, opts)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
attr = {type: "math/tex#{type == :block ? '; mode=display' : ''}"}
|
26
|
-
preview << if type == :block
|
27
|
-
converter.format_as_block_html('script', attr, text, opts[:indent])
|
28
|
-
else
|
29
|
-
converter.format_as_span_html('script', attr, text)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.preview_string(converter, el, opts)
|
34
|
-
preview = converter.options[:math_engine_opts][:preview]
|
35
|
-
return '' unless preview
|
36
|
-
|
37
|
-
preview = (preview == true ? converter.escape_html(el.value) : preview.to_s)
|
38
|
-
|
39
|
-
preview_as_code = converter.options[:math_engine_opts][:preview_as_code]
|
40
|
-
|
41
|
-
if el.options[:category] == :block
|
42
|
-
if preview_as_code
|
43
|
-
converter.format_as_block_html('pre', {'class' => 'MathJax_Preview'},
|
44
|
-
converter.format_as_span_html('code', {}, preview),
|
45
|
-
opts[:indent])
|
46
|
-
else
|
47
|
-
converter.format_as_block_html('div', {'class' => 'MathJax_Preview'}, preview,
|
48
|
-
opts[:indent])
|
49
|
-
end
|
19
|
+
value = converter.escape_html(el.value)
|
20
|
+
result = el.options[:category] == :block ? "\\[#{value}\\]\n" : "\\(#{value}\\)"
|
21
|
+
if el.attr.empty?
|
22
|
+
result
|
23
|
+
elsif el.options[:category] == :block
|
24
|
+
converter.format_as_block_html('div', el.attr, result, opts[:indent])
|
50
25
|
else
|
51
|
-
converter.format_as_span_html(
|
52
|
-
{'class' => 'MathJax_Preview'}, preview)
|
26
|
+
converter.format_as_span_html('span', el.attr, "$#{el.value}$")
|
53
27
|
end
|
54
28
|
end
|
55
29
|
|
@@ -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
|
-
|
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
|
@@ -42,7 +42,7 @@ module Kramdown
|
|
42
42
|
#
|
43
43
|
# == Special Implementation Details
|
44
44
|
#
|
45
|
-
# HTML converter:: If the syntax highlighter is used with
|
45
|
+
# HTML converter:: If the syntax highlighter is used with an HTML converter, it should return
|
46
46
|
# :block type text correctly wrapped (i.e. normally inside a pre-tag, but may
|
47
47
|
# also be a table-tag or just a div-tag) but :span type text *without* a
|
48
48
|
# code-tag!
|
data/lib/kramdown/element.rb
CHANGED
@@ -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
|
@@ -522,6 +530,22 @@ module Kramdown
|
|
522
530
|
CATEGORY[el.type] || el.options[:category]
|
523
531
|
end
|
524
532
|
|
533
|
+
# syntactic sugar to simplify calls such as +Kramdown::Element.category(el) == :block+ with
|
534
|
+
# +el.block?+.
|
535
|
+
#
|
536
|
+
# Returns boolean true or false.
|
537
|
+
def block?
|
538
|
+
(CATEGORY[type] || options[:category]) == :block
|
539
|
+
end
|
540
|
+
|
541
|
+
# syntactic sugar to simplify calls such as +Kramdown::Element.category(el) == :span+ with
|
542
|
+
# +el.span?+.
|
543
|
+
#
|
544
|
+
# Returns boolean true or false.
|
545
|
+
def span?
|
546
|
+
(CATEGORY[type] || options[:category]) == :span
|
547
|
+
end
|
548
|
+
|
525
549
|
end
|
526
550
|
|
527
551
|
end
|