kramdown-asciidoc 1.0.0.alpha.10 → 1.0.0.alpha.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +19 -0
- data/README.adoc +4 -1
- data/lib/kramdown-asciidoc/api.rb +27 -0
- data/lib/kramdown-asciidoc/cli.rb +14 -22
- data/lib/kramdown-asciidoc/converter.rb +62 -33
- data/lib/kramdown-asciidoc/kramdown_ext/parser/html.rb +9 -0
- data/lib/kramdown-asciidoc/version.rb +1 -1
- data/lib/kramdown-asciidoc/writer.rb +3 -3
- data/lib/kramdown-asciidoc.rb +3 -9
- data/spec/api_spec.rb +63 -0
- data/spec/cli_spec.rb +1 -2
- data/spec/converter_spec.rb +5 -5
- data/spec/scenario_spec.rb +1 -1
- data/spec/scenarios/blockquote/attribution-separated.md +1 -0
- data/spec/scenarios/blockquote/{with-attribution.adoc → attribution.adoc} +0 -0
- data/spec/scenarios/blockquote/{with-attribution.md → attribution.md} +0 -0
- data/spec/scenarios/codeblock/{fenced/with-command-prompt.adoc → command-prompt.adoc} +0 -0
- data/spec/scenarios/codeblock/{with-command-prompt.md → command-prompt.md} +0 -0
- data/spec/scenarios/codeblock/{with-command-prompt.adoc → fenced/command-prompt.adoc} +0 -0
- data/spec/scenarios/codeblock/fenced/{with-command-prompt.md → command-prompt.md} +0 -0
- data/spec/scenarios/codeblock/fenced/{with-language.adoc → language.adoc} +0 -0
- data/spec/scenarios/codeblock/fenced/{with-language.md → language.md} +0 -0
- data/spec/scenarios/codeblock/fenced/{with-non-contiguous-command-prompts.adoc → non-contiguous-command-prompts.adoc} +0 -0
- data/spec/scenarios/codeblock/fenced/{with-non-contiguous-command-prompts.md → non-contiguous-command-prompts.md} +0 -0
- data/spec/scenarios/codeblock/{with-non-contiguous-command-prompts.adoc → non-contiguous-command-prompts.adoc} +0 -0
- data/spec/scenarios/codeblock/{with-non-contiguous-command-prompts.md → non-contiguous-command-prompts.md} +0 -0
- data/spec/scenarios/codespan/caret.adoc +1 -0
- data/spec/scenarios/codespan/caret.md +1 -0
- data/spec/scenarios/codespan/possessive.adoc +3 -0
- data/spec/scenarios/codespan/possessive.md +3 -0
- data/spec/scenarios/codespan/quoted.adoc +1 -0
- data/spec/scenarios/codespan/quoted.md +1 -0
- data/spec/scenarios/codespan/smart-quotes.adoc +1 -0
- data/spec/scenarios/codespan/smart-quotes.md +1 -0
- data/spec/scenarios/codespan/unconstrained.adoc +1 -0
- data/spec/scenarios/codespan/unconstrained.md +1 -0
- data/spec/scenarios/heading/auto-id-prefix.adoc +11 -0
- data/spec/scenarios/heading/auto-id-prefix.md +7 -0
- data/spec/scenarios/heading/auto-id-prefix.opts +2 -0
- data/spec/scenarios/heading/auto-ids.adoc +1 -1
- data/spec/scenarios/heading/auto-ids.md +1 -1
- data/spec/scenarios/heading/{with-formatting.adoc → formatting.adoc} +0 -0
- data/spec/scenarios/heading/{with-formatting.md → formatting.md} +0 -0
- data/spec/scenarios/heading/{with-anchor.adoc → leading-anchor.adoc} +0 -0
- data/spec/scenarios/heading/leading-anchor.md +1 -0
- data/spec/scenarios/heading/surrounding-anchor.adoc +2 -0
- data/spec/scenarios/heading/{with-anchor.md → surrounding-anchor.md} +0 -0
- data/spec/scenarios/html_element/div-mixed.adoc +1 -0
- data/spec/scenarios/html_element/div-mixed.md +4 -0
- data/spec/scenarios/html_element/div-text-only.adoc +1 -0
- data/spec/scenarios/html_element/div-text-only.md +1 -0
- data/spec/scenarios/html_element/mark.adoc +1 -0
- data/spec/scenarios/html_element/mark.md +1 -0
- data/spec/scenarios/html_element/span.adoc +3 -0
- data/spec/scenarios/html_element/span.md +3 -0
- data/spec/scenarios/html_element/unrecognized-admonition.adoc +5 -0
- data/spec/scenarios/html_element/unrecognized-admonition.md +5 -0
- data/spec/scenarios/p/admonition/label-only.adoc +1 -0
- data/spec/scenarios/p/admonition/label-only.md +1 -0
- data/spec/scenarios/table/{with-header.adoc → header.adoc} +0 -0
- data/spec/scenarios/table/{with-header.md → header.md} +0 -0
- data/spec/scenarios/table/{without-header.adoc → no-header.adoc} +0 -0
- data/spec/scenarios/table/{without-header.md → no-header.md} +0 -0
- data/spec/scenarios/wrap/ventilate-with-comments.adoc +5 -0
- data/spec/scenarios/wrap/ventilate-with-comments.md +5 -0
- data/spec/scenarios/wrap/ventilate-with-comments.opts +1 -0
- data/spec/scenarios/xml_comment/above-block.adoc +7 -0
- data/spec/scenarios/xml_comment/above-block.md +5 -0
- data/spec/scenarios/xml_comment/line-empty.adoc +7 -0
- data/spec/scenarios/xml_comment/line-empty.md +9 -0
- data/spec/scenarios/xml_comment/multiline-span.adoc +4 -0
- data/spec/scenarios/xml_comment/multiline-span.md +4 -0
- data/spec/scenarios/xml_comment/p-separator.adoc +5 -0
- data/spec/scenarios/xml_comment/p-separator.md +5 -0
- data/spec/scenarios/xml_comment/surrounded-by-spaces.adoc +3 -0
- data/spec/scenarios/xml_comment/surrounded-by-spaces.md +1 -0
- data/spec/spec_helper.rb +1 -0
- metadata +118 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8a8579b7930fcfba55c49f569adfffcf2f0d4f98d324e5a928493dca246e78e
|
4
|
+
data.tar.gz: dca656316d4e76d2ea0169b9568ab5f54cab4a8add284f6ca24c0ff141e4918f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c77f10db21bbace2285b3ad00b04cdf4a45306d681739d36395a35d89b78fb5b512eb678afc9a07c965d219cddf7895a314b76e9a97d45971102b25bc976556b
|
7
|
+
data.tar.gz: c4938413fa37f131723e5d08ff44a0cc42c61c0586227a2f984a1c82818d34de62de8d08cf755aef6acf5719728e6de12d6162b5965e7eea2d939de0e78b7c97
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,25 @@
|
|
5
5
|
This document provides a high-level view of the changes to {project-name} by release.
|
6
6
|
For a detailed view of what has changed, refer to the {uri-repo}/commits/master[commit history] on GitHub.
|
7
7
|
|
8
|
+
== 1.0.0.alpha.11 (2018-08-02) - @mojavelinux
|
9
|
+
|
10
|
+
=== Added
|
11
|
+
|
12
|
+
* add a public API (Kramdoc.convert and Kramdoc.convert_file) for converting input strings and paths, respectively (#31)
|
13
|
+
* update CLI to use public API (#31)
|
14
|
+
* run test suite on Windows using AppVeyor (#32)
|
15
|
+
* don't crash when empty comment occurs under primary text of list item
|
16
|
+
* convert phrase enclosed in <span> (#36)
|
17
|
+
* convert phrase enclosed in <mark>
|
18
|
+
* convert a bare <div> to a paragraph
|
19
|
+
* remove leading space from text if at beginning of line
|
20
|
+
|
21
|
+
=== Changed
|
22
|
+
|
23
|
+
* add code role to codespan if enclosed in quotes (required for AsciiDoc to parse properly) (#29)
|
24
|
+
* use unconstrained codespan if bounded on either side by a smart quote
|
25
|
+
* ignore auto-generated ID if heading has an explicit inline anchor
|
26
|
+
|
8
27
|
== 1.0.0.alpha.10 (2018-07-16) - @mojavelinux
|
9
28
|
|
10
29
|
=== Added
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= {project-name} (Markdown to AsciiDoc)
|
2
2
|
Dan Allen <https://github.com/mojavelinux>
|
3
|
-
v1.0.0.alpha.
|
3
|
+
v1.0.0.alpha.11, 2018-08-02
|
4
4
|
// Aliases:
|
5
5
|
:project-name: Kramdown AsciiDoc
|
6
6
|
:project-handle: kramdown-asciidoc
|
@@ -25,6 +25,8 @@ endif::[]
|
|
25
25
|
:uri-kramdown: https://kramdown.gettalong.org
|
26
26
|
:uri-rvm: https://rvm.io
|
27
27
|
:uri-rvm-install: https://rvm.io/rvm/install
|
28
|
+
:uri-ci-appveyor: https://ci.appveyor.com/project/asciidoctor/kramdown-asciidoc
|
29
|
+
:img-ci-appveyor: https://ci.appveyor.com/api/projects/status/2pwvdbcoeux1ifb5/branch/master?svg=true
|
28
30
|
:uri-ci-travis: https://travis-ci.org/asciidoctor/kramdown-asciidoc
|
29
31
|
:uri-ci-travis-img: https://img.shields.io/travis/asciidoctor/kramdown-asciidoc/master.svg
|
30
32
|
:uri-gem: https://rubygems.org/gems/kramdown-asciidoc
|
@@ -33,6 +35,7 @@ endif::[]
|
|
33
35
|
ifdef::status[]
|
34
36
|
image:{uri-gem-img}[Gem Version,link={uri-gem}]
|
35
37
|
image:{uri-ci-travis-img}[Build Status (Travis CI),link={uri-ci-travis}]
|
38
|
+
image:{img-ci-appveyor}[Build Status (AppVeyor),link={uri-ci-appveyor}]
|
36
39
|
endif::[]
|
37
40
|
|
38
41
|
{uri-repo}[{project-name}] (gem: *{project-handle}*) is a {uri-kramdown}[kramdown] extension for converting Markdown documents to {uri-asciidoc}[AsciiDoc].
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kramdown; module AsciiDoc
|
2
|
+
LF = ?\n
|
3
|
+
|
4
|
+
def self.convert markdown, opts = {}
|
5
|
+
markdown = markdown.rstrip
|
6
|
+
markdown = markdown.slice 1, markdown.length while markdown.start_with? LF
|
7
|
+
attributes = (opts[:attributes] ||= {})
|
8
|
+
markdown = ::Kramdown::AsciiDoc.extract_front_matter markdown, attributes
|
9
|
+
markdown = ::Kramdown::AsciiDoc.replace_toc markdown, attributes
|
10
|
+
asciidoc = (::Kramdown::Document.new markdown, (::Kramdown::AsciiDoc::DEFAULT_PARSER_OPTS.merge opts)).to_asciidoc
|
11
|
+
asciidoc += LF unless asciidoc.empty?
|
12
|
+
if (to = opts[:to])
|
13
|
+
(to.respond_to? :write) ? (to.write asciidoc) : (::IO.write to, asciidoc)
|
14
|
+
nil
|
15
|
+
else
|
16
|
+
asciidoc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.convert_file markdown_file, opts = {}
|
21
|
+
markdown = ::IO.read markdown_file, mode: 'r:UTF-8', newline: :universal
|
22
|
+
(output_file = (::Pathname.new markdown_file).sub_ext '.adoc').dirname.mkpath
|
23
|
+
convert markdown, (opts.merge to: output_file)
|
24
|
+
end
|
25
|
+
end; end
|
26
|
+
|
27
|
+
Kramdoc = Kramdown::AsciiDoc
|
@@ -62,12 +62,12 @@ module Kramdown; module AsciiDoc
|
|
62
62
|
end
|
63
63
|
|
64
64
|
opts.on '-h', '--help', 'Display this help text and exit' do
|
65
|
-
$stdout.
|
65
|
+
$stdout.write opts.help
|
66
66
|
return 0
|
67
67
|
end
|
68
68
|
|
69
69
|
opts.on '-v', '--version', %(Display version information and exit) do
|
70
|
-
$stdout.
|
70
|
+
$stdout.write %(#{opts.program_name} #{VERSION}\n)
|
71
71
|
return 0
|
72
72
|
end
|
73
73
|
end
|
@@ -76,7 +76,7 @@ module Kramdown; module AsciiDoc
|
|
76
76
|
|
77
77
|
if args.empty?
|
78
78
|
opt_parser.warn 'Please specify a Markdown file to convert.'
|
79
|
-
$stdout.
|
79
|
+
$stdout.write opt_parser.help
|
80
80
|
return 1
|
81
81
|
end
|
82
82
|
|
@@ -85,12 +85,12 @@ module Kramdown; module AsciiDoc
|
|
85
85
|
[0, options]
|
86
86
|
else
|
87
87
|
opt_parser.warn %(extra arguments detected (unparsed arguments: #{(args.drop 1).join ' '}))
|
88
|
-
$stdout.
|
88
|
+
$stdout.write opt_parser.help
|
89
89
|
[1, options]
|
90
90
|
end
|
91
91
|
rescue ::OptionParser::InvalidOption
|
92
|
-
$stderr.
|
93
|
-
$stdout.
|
92
|
+
$stderr.write %(#{opt_parser.program_name}: #{$!.message}\n)
|
93
|
+
$stdout.write opt_parser.help
|
94
94
|
return 1
|
95
95
|
end
|
96
96
|
|
@@ -99,33 +99,25 @@ module Kramdown; module AsciiDoc
|
|
99
99
|
return code unless code == 0 && options
|
100
100
|
if (input_file = options.delete :input_file) == '-'
|
101
101
|
pipe_in = true
|
102
|
-
markdown = $stdin.read
|
102
|
+
markdown = $stdin.read
|
103
103
|
else
|
104
|
-
markdown =
|
104
|
+
markdown = ::IO.read input_file, mode: 'r:UTF-8', newline: :universal
|
105
105
|
end
|
106
106
|
if (output_file = options.delete :output_file)
|
107
107
|
if output_file == '-'
|
108
108
|
pipe_out = true
|
109
109
|
else
|
110
|
-
(::Pathname.new output_file).dirname.mkpath
|
110
|
+
(output_file = ::Pathname.new output_file).dirname.mkpath
|
111
111
|
end
|
112
112
|
else
|
113
|
-
output_file = (
|
113
|
+
output_file = (::Pathname.new input_file).sub_ext '.adoc'
|
114
114
|
end
|
115
|
-
if !
|
116
|
-
$stderr.
|
115
|
+
if !pipe_in && !pipe_out && (::File.expand_path input_file) == output_file.expand_path.to_s
|
116
|
+
$stderr.write %(kramdoc: input and output file cannot be the same: #{input_file}\n)
|
117
117
|
return 1
|
118
118
|
end
|
119
|
-
|
120
|
-
|
121
|
-
markdown = ::Kramdown::AsciiDoc.extract_front_matter markdown, attributes
|
122
|
-
markdown = ::Kramdown::AsciiDoc.replace_toc markdown, attributes
|
123
|
-
doc = ::Kramdown::Document.new markdown, (::Kramdown::AsciiDoc::DEFAULT_PARSER_OPTS.merge options)
|
124
|
-
if pipe_out
|
125
|
-
$stdout.puts doc.to_asciidoc
|
126
|
-
else
|
127
|
-
::IO.write output_file, doc.to_asciidoc
|
128
|
-
end
|
119
|
+
# QUESTION should we set :from option?
|
120
|
+
::Kramdoc.convert markdown, (options.merge to: (pipe_out ? $stdout : output_file))
|
129
121
|
0
|
130
122
|
end
|
131
123
|
end
|
@@ -142,12 +142,13 @@ module Kramdown; module AsciiDoc
|
|
142
142
|
end
|
143
143
|
style << 'discrete'
|
144
144
|
end
|
145
|
-
if (
|
146
|
-
style << %(##{id})
|
147
|
-
elsif (child_i = el.children[0] || VoidElement).type == :html_element && child_i.value == 'a' && (id = child_i.attr['id'])
|
145
|
+
if (child_i = to_element el.children[0]).type == :html_element && child_i.value == 'a' && (id = child_i.attr['id'])
|
148
146
|
el = clone el, children: child_i.children + (el.children.drop 1)
|
149
147
|
style << %(##{id})
|
150
|
-
elsif (
|
148
|
+
elsif (id = el.attr['id'])
|
149
|
+
style << %(##{id})
|
150
|
+
end
|
151
|
+
if (role = el.attr['class'])
|
151
152
|
style << %(.#{role.tr ' ', '.'})
|
152
153
|
end
|
153
154
|
lines = []
|
@@ -184,7 +185,7 @@ module Kramdown; module AsciiDoc
|
|
184
185
|
# NOTE detect formatted admonition marker (e.g., *Note:* ...)
|
185
186
|
elsif (child_i.type == :strong || child_i.type == :em) &&
|
186
187
|
(marker_el = child_i.children[0]) && ((marker = ADMON_FORMATTED_MARKERS[marker_el.value]) ||
|
187
|
-
((marker = ADMON_LABELS[marker_el.value]) && (child_ii = children[1]
|
188
|
+
((marker = ADMON_LABELS[marker_el.value]) && (child_ii = to_element children[1]).type == :text &&
|
188
189
|
((child_ii_text = child_ii.value).start_with? ': ')))
|
189
190
|
children = children.drop 1
|
190
191
|
children[0] = clone child_ii, value: (child_ii_text.slice 1, child_ii_text.length) if child_ii
|
@@ -209,7 +210,8 @@ module Kramdown; module AsciiDoc
|
|
209
210
|
if contents.size > 1 && (contents[-1].start_with? '-- ')
|
210
211
|
attribution = (attribution_line = contents.pop).slice 3, attribution_line.length
|
211
212
|
writer.add_line %([,#{attribution}])
|
212
|
-
|
213
|
+
# NOTE there will be at least one non-blank line, but coerce .to_s just to be safe
|
214
|
+
contents.pop while contents[-1].to_s.empty?
|
213
215
|
end
|
214
216
|
# Q: should writer handle delimited block nesting?
|
215
217
|
delimiter = depth > 0 ? ('____' + '__' * depth) : '_'
|
@@ -250,7 +252,7 @@ module Kramdown; module AsciiDoc
|
|
250
252
|
end
|
251
253
|
|
252
254
|
def convert_img el, opts
|
253
|
-
if
|
255
|
+
if (parent = opts[:parent]).type == :p && parent.children.size == 1
|
254
256
|
style = []
|
255
257
|
if (id = el.attr['id'])
|
256
258
|
style << %(##{id})
|
@@ -318,8 +320,9 @@ module Kramdown; module AsciiDoc
|
|
318
320
|
primary_lines.unshift %(#{indent > 0 ? ' ' * indent : ''}#{marker * level} #{primary_lines.shift})
|
319
321
|
writer.add_lines primary_lines
|
320
322
|
unless remaining.empty?
|
321
|
-
|
322
|
-
|
323
|
+
if remaining.find {|n| (type = n.type) == :blank ? nil : ((BLOCK_TYPES.include? type) ? true : break) }
|
324
|
+
el.options[:compound] = true
|
325
|
+
end
|
323
326
|
traverse remaining, (opts.merge parent: el)
|
324
327
|
end
|
325
328
|
end
|
@@ -348,8 +351,9 @@ module Kramdown; module AsciiDoc
|
|
348
351
|
end
|
349
352
|
end
|
350
353
|
unless remaining.empty?
|
351
|
-
|
352
|
-
|
354
|
+
if remaining.find {|n| (type = n.type) == :blank ? nil : ((BLOCK_TYPES.include? type) ? true : break) }
|
355
|
+
el.options[:compound] = true
|
356
|
+
end
|
353
357
|
traverse remaining, (opts.merge parent: el)
|
354
358
|
end
|
355
359
|
end
|
@@ -425,7 +429,21 @@ module Kramdown; module AsciiDoc
|
|
425
429
|
end
|
426
430
|
|
427
431
|
def convert_codespan el, opts
|
428
|
-
mark =
|
432
|
+
attrlist, mark = '', '`'
|
433
|
+
if unconstrained? (prev_el = opts[:prev]), (next_el = opts[:next])
|
434
|
+
mark = '``'
|
435
|
+
elsif next_el
|
436
|
+
case next_el.type
|
437
|
+
when :smart_quote
|
438
|
+
if prev_el && prev_el.type == :smart_quote
|
439
|
+
attrlist, mark = '[.code]', '``'
|
440
|
+
else
|
441
|
+
mark = '``'
|
442
|
+
end
|
443
|
+
when :text
|
444
|
+
mark = '``' if (next_el.value.chr == ?') || (prev_el && prev_el.type == :smart_quote)
|
445
|
+
end
|
446
|
+
end
|
429
447
|
text = el.value
|
430
448
|
pass = (replaceable? text) ? :shorthand : nil
|
431
449
|
pass = :macro if text.include? '++'
|
@@ -434,13 +452,13 @@ module Kramdown; module AsciiDoc
|
|
434
452
|
elsif pass == :macro
|
435
453
|
opts[:writer].append %(#{mark}pass:c[#{text}]#{mark})
|
436
454
|
else
|
437
|
-
opts[:writer].append %(#{mark}#{text}#{mark})
|
455
|
+
opts[:writer].append %(#{attrlist}#{mark}#{text}#{mark})
|
438
456
|
end
|
439
457
|
end
|
440
458
|
|
441
459
|
def convert_em el, opts
|
442
460
|
composed_text = compose_text el
|
443
|
-
mark = (unconstrained? opts[:prev], opts[:next]
|
461
|
+
mark = (unconstrained? opts[:prev], opts[:next]) ? '__' : '_'
|
444
462
|
opts[:writer].append %(#{mark}#{composed_text}#{mark})
|
445
463
|
end
|
446
464
|
|
@@ -449,25 +467,21 @@ module Kramdown; module AsciiDoc
|
|
449
467
|
@attributes['experimental'] = ''
|
450
468
|
opts[:writer].append %(menu:#{$1}[#{$2}])
|
451
469
|
else
|
452
|
-
mark = (unconstrained? opts[:prev], opts[:next]
|
470
|
+
mark = (unconstrained? opts[:prev], opts[:next]) ? '**' : '*'
|
453
471
|
opts[:writer].append %(#{mark}#{composed_text}#{mark})
|
454
472
|
end
|
455
473
|
end
|
456
474
|
|
457
|
-
def unconstrained? prev_el, next_el
|
458
|
-
(next_char_word? next_el
|
475
|
+
def unconstrained? prev_el, next_el
|
476
|
+
(next_char_word? next_el) || (prev_char_wordish? prev_el)
|
459
477
|
end
|
460
478
|
|
461
479
|
def prev_char_wordish? prev_el
|
462
480
|
prev_el && (prev_el.type == :entity || (prev_el.type == :text && (WordishRx.match? prev_el.value[-1])))
|
463
481
|
end
|
464
482
|
|
465
|
-
def next_char_word? next_el
|
466
|
-
|
467
|
-
(WordRx.match? (next_ch = next_el.value.chr)) || (enclosure == :codespan && next_ch == ?')
|
468
|
-
elsif enclosure == :codespan && next_el.type == :smart_quote
|
469
|
-
true
|
470
|
-
end if next_el
|
483
|
+
def next_char_word? next_el
|
484
|
+
next_el && next_el.type == :text && (WordRx.match? next_el.value.chr)
|
471
485
|
end
|
472
486
|
|
473
487
|
def convert_text el, opts
|
@@ -476,7 +490,11 @@ module Kramdown; module AsciiDoc
|
|
476
490
|
@attributes['pp'] = '{plus}{plus}'
|
477
491
|
text = text.gsub '++', '{pp}'
|
478
492
|
end
|
479
|
-
opts[:writer].
|
493
|
+
if (current_line = (writer = opts[:writer]).current_line).to_s.empty?
|
494
|
+
writer.append text.lstrip
|
495
|
+
else
|
496
|
+
writer.append text
|
497
|
+
end
|
480
498
|
end
|
481
499
|
|
482
500
|
def replaceable? text
|
@@ -503,7 +521,7 @@ module Kramdown; module AsciiDoc
|
|
503
521
|
writer.append %(#{(writer.current_line.end_with? ' ') ? '' : ' '}+)
|
504
522
|
end
|
505
523
|
if el.options[:html_tag]
|
506
|
-
writer.add_blank_line unless (next_el = opts[:next]
|
524
|
+
writer.add_blank_line unless (next_el = to_element opts[:next]).type == :text && (next_el.value.start_with? LF)
|
507
525
|
end
|
508
526
|
end
|
509
527
|
|
@@ -522,29 +540,36 @@ module Kramdown; module AsciiDoc
|
|
522
540
|
|
523
541
|
def convert_html_element el, opts
|
524
542
|
if (tag = el.value) == 'div' && (child_i = el.children[0]) && child_i.options[:transparent] && (child_i_i = child_i.children[0])
|
525
|
-
if child_i_i.
|
526
|
-
|
527
|
-
return
|
528
|
-
elsif child_i_i.value == 'span' && ((role = el.attr['class'] || '').start_with? 'note') && child_i_i.attr['class'] == 'notetitle'
|
529
|
-
marker = ADMON_FORMATTED_MARKERS[(child_i_i.children[0] || VoidElement).value] || 'Note'
|
543
|
+
if child_i_i.value == 'span' && ((role = el.attr['class'].to_s).start_with? 'note') && child_i_i.attr['class'] == 'notetitle'
|
544
|
+
marker = ADMON_FORMATTED_MARKERS[(to_element child_i_i.children[0]).value] || 'Note'
|
530
545
|
lines = compose_text (child_i.children.drop 1), parent: child_i, strip: true, split: true, wrap: @wrap
|
531
546
|
lines.unshift %(#{ADMON_TYPE_MAP[marker]}: #{lines.shift})
|
532
547
|
opts[:writer].start_block
|
533
548
|
opts[:writer].add_lines lines
|
534
549
|
return
|
550
|
+
else
|
551
|
+
return convert_p child_i, (opts.merge parent: el, index: 0)
|
535
552
|
end
|
536
553
|
end
|
537
554
|
|
538
555
|
contents = compose_text el, (opts.merge strip: el.options[:category] == :block)
|
539
|
-
attrs = (attrs = el.attr).empty? ? '' : attrs.map {|k, v| %( #{k}="#{v}") }.join
|
540
556
|
case tag
|
541
557
|
when 'del'
|
542
558
|
opts[:writer].append %([.line-through]##{contents}#)
|
559
|
+
when 'mark'
|
560
|
+
opts[:writer].append %(##{contents}#)
|
561
|
+
when 'span'
|
562
|
+
if (role = el.attr['class'])
|
563
|
+
opts[:writer].append %([.#{role.tr ' ', '.'}]##{contents}#)
|
564
|
+
else
|
565
|
+
opts[:writer].append contents
|
566
|
+
end
|
543
567
|
when 'sup'
|
544
568
|
opts[:writer].append %(^#{contents}^)
|
545
569
|
when 'sub'
|
546
570
|
opts[:writer].append %(~#{contents}~)
|
547
571
|
else
|
572
|
+
attrs = (attrs = el.attr).empty? ? '' : attrs.map {|k, v| %( #{k}="#{v}") }.join
|
548
573
|
opts[:writer].append %(+++<#{tag}#{attrs}>+++#{contents}+++</#{tag}>+++)
|
549
574
|
end
|
550
575
|
end
|
@@ -566,7 +591,7 @@ module Kramdown; module AsciiDoc
|
|
566
591
|
else
|
567
592
|
writer.add_line %(// #{lines[0]})
|
568
593
|
end
|
569
|
-
|
594
|
+
elsif !lines.empty?
|
570
595
|
if (current_line = writer.current_line) && !(current_line.end_with? LF)
|
571
596
|
start_new_line = true
|
572
597
|
writer.replace_line current_line.rstrip if current_line.end_with? ' '
|
@@ -583,7 +608,7 @@ module Kramdown; module AsciiDoc
|
|
583
608
|
end
|
584
609
|
|
585
610
|
def extract_prologue el, opts
|
586
|
-
if (child_i = (children = el.children)[0]
|
611
|
+
if (child_i = to_element (children = el.children)[0]).type == :xml_comment
|
587
612
|
(prologue_el = el.dup).children = children.take_while {|child| child.type == :xml_comment || child.type == :blank }
|
588
613
|
(el = el.dup).children = children.drop prologue_el.children.size
|
589
614
|
traverse prologue_el, (opts.merge writer: (prologue_writer = Writer.new))
|
@@ -600,6 +625,10 @@ module Kramdown; module AsciiDoc
|
|
600
625
|
el
|
601
626
|
end
|
602
627
|
|
628
|
+
def to_element el
|
629
|
+
el || VoidElement
|
630
|
+
end
|
631
|
+
|
603
632
|
def traverse el, opts
|
604
633
|
if ::Array === el
|
605
634
|
nodes = el
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Kramdown::Parser::Html::ElementConverter
|
2
|
+
# Overload convert_br to add the :html_tag option to indicate this br element originates from an HTML tag
|
3
|
+
def convert_br el
|
4
|
+
el.options.replace location: el.options[:location], html_tag: true
|
5
|
+
el.type = el.value.to_sym
|
6
|
+
el.value = nil
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
end
|
@@ -60,7 +60,7 @@ module Kramdown; module AsciiDoc
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# Q: perhaps do_in_list that takes a block?
|
63
|
-
def start_list compound, kin
|
63
|
+
def start_list compound, kin
|
64
64
|
# Q: can this be further optimized?
|
65
65
|
@body << '' if in_list? ? compound : !empty?
|
66
66
|
@block_separator << '+'
|
@@ -68,7 +68,7 @@ module Kramdown; module AsciiDoc
|
|
68
68
|
nil
|
69
69
|
end
|
70
70
|
|
71
|
-
def end_list kin
|
71
|
+
def end_list kin
|
72
72
|
@block_separator.pop
|
73
73
|
@list_level[kin] -= 1
|
74
74
|
nil
|
@@ -125,7 +125,7 @@ module Kramdown; module AsciiDoc
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def to_s
|
128
|
-
(
|
128
|
+
(@header.empty? ? @body : (@header + (@body.empty? ? [] : [''] + @body))).join LF
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end; end
|
data/lib/kramdown-asciidoc.rb
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
require 'kramdown'
|
2
|
+
require_relative 'kramdown-asciidoc/kramdown_ext/parser/html'
|
2
3
|
require_relative 'kramdown-asciidoc/core_ext/regexp/is_match'
|
4
|
+
require_relative 'kramdown-asciidoc/api'
|
3
5
|
require_relative 'kramdown-asciidoc/converter'
|
4
6
|
require_relative 'kramdown-asciidoc/writer'
|
7
|
+
autoload :Pathname, 'pathname'
|
5
8
|
autoload :YAML, 'yaml'
|
6
|
-
|
7
|
-
class Kramdown::Parser::Html::ElementConverter
|
8
|
-
def convert_br el
|
9
|
-
el.options.replace location: el.options[:location], html_tag: true
|
10
|
-
el.type = el.value.to_sym
|
11
|
-
el.value = nil
|
12
|
-
nil
|
13
|
-
end
|
14
|
-
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Kramdown::AsciiDoc do
|
4
|
+
context '#convert' do
|
5
|
+
it 'converts Markdown to AsciiDoc' do
|
6
|
+
input = <<~EOS
|
7
|
+
---
|
8
|
+
title: Document Title
|
9
|
+
---
|
10
|
+
|
11
|
+
Body content.
|
12
|
+
EOS
|
13
|
+
|
14
|
+
expected = <<~EOS
|
15
|
+
= Document Title
|
16
|
+
|
17
|
+
Body content.
|
18
|
+
EOS
|
19
|
+
|
20
|
+
(expect subject.convert input).to eql expected
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'writes AsciiDoc to filename specified in :to option' do
|
24
|
+
the_output_file = output_file 'convert-api.adoc'
|
25
|
+
(expect subject.convert 'Converted using the API', to: the_output_file).to be_nil
|
26
|
+
(expect (IO.read the_output_file)).to eql %(Converted using the API\n)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'writes AsciiDoc to IO object specified in :to option' do
|
30
|
+
old_stdout, $stdout = $stdout, StringIO.new
|
31
|
+
begin
|
32
|
+
(expect subject.convert 'text', to: $stdout).to be_nil
|
33
|
+
(expect $stdout.string).to eql %(text\n)
|
34
|
+
ensure
|
35
|
+
$stdout = old_stdout
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'adds line feed (EOL) to end of output document if non-empty' do
|
40
|
+
(expect subject.convert 'paragraph').to end_with ?\n
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not add line feed (EOL) to end of output document if empty' do
|
44
|
+
(expect subject.convert '').to be_empty
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context '#convert_file' do
|
49
|
+
it 'converts Markdown file to AsciiDoc file' do
|
50
|
+
the_source_file = output_file 'convert-file-api.md'
|
51
|
+
the_output_file = output_file 'convert-file-api.adoc'
|
52
|
+
IO.write the_source_file, 'Converted using the API'
|
53
|
+
(expect subject.convert_file the_source_file).to be_nil
|
54
|
+
(expect (IO.read the_output_file)).to eql %(Converted using the API\n)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Kramdoc do
|
60
|
+
it 'supports Kramdoc as an alias for Kramdown::AsciiDoc' do
|
61
|
+
(expect Kramdoc).to eql Kramdown::AsciiDoc
|
62
|
+
end
|
63
|
+
end
|
data/spec/cli_spec.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
require 'kramdown-asciidoc/cli'
|
3
|
-
require 'stringio'
|
4
3
|
|
5
4
|
describe Kramdown::AsciiDoc::Cli do
|
6
5
|
subject { Kramdown::AsciiDoc::Cli }
|
@@ -211,7 +210,7 @@ describe Kramdown::AsciiDoc::Cli do
|
|
211
210
|
[#_heading-2]
|
212
211
|
== Heading 2
|
213
212
|
|
214
|
-
[#
|
213
|
+
[#explicit-id]
|
215
214
|
=== Heading 3
|
216
215
|
|
217
216
|
[#_back-to-heading-2]
|
data/spec/converter_spec.rb
CHANGED
@@ -9,9 +9,9 @@ describe Kramdown::AsciiDoc::Converter do
|
|
9
9
|
context '#convert' do
|
10
10
|
let (:input) { %(# Document Title\n\nBody text.) }
|
11
11
|
|
12
|
-
it '
|
13
|
-
(expect converter.convert root).
|
14
|
-
(expect doc.to_asciidoc).
|
12
|
+
it 'does not add line feed (EOL) to end of output document' do
|
13
|
+
(expect converter.convert root).not_to end_with ?\n
|
14
|
+
(expect doc.to_asciidoc).not_to end_with ?\n
|
15
15
|
end
|
16
16
|
|
17
17
|
# Q: can we find a scenario that covers this?
|
@@ -154,7 +154,7 @@ describe Kramdown::AsciiDoc::Converter do
|
|
154
154
|
When using this technology, anything is possible.
|
155
155
|
EOS
|
156
156
|
|
157
|
-
expected = <<~EOS
|
157
|
+
expected = <<~EOS.chomp
|
158
158
|
= Introduction
|
159
159
|
:description: An introduction to this amazing technology.
|
160
160
|
|
@@ -177,7 +177,7 @@ describe Kramdown::AsciiDoc::Converter do
|
|
177
177
|
When using this technology, anything is possible.
|
178
178
|
EOS
|
179
179
|
|
180
|
-
expected = <<~EOS
|
180
|
+
expected = <<~EOS.chomp
|
181
181
|
= Introduction
|
182
182
|
:description: An introduction to this amazing technology.
|
183
183
|
|
data/spec/scenario_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe 'scenario' do
|
|
15
15
|
context %(for #{scenario_name}) do
|
16
16
|
let(:input) { IO.read input_filename, mode: 'r:UTF-8', newline: :universal }
|
17
17
|
let(:extra_options) { options }
|
18
|
-
let(:expected) { IO.read output_filename, mode: 'r:UTF-8', newline: :universal }
|
18
|
+
let(:expected) { (IO.read output_filename, mode: 'r:UTF-8', newline: :universal).chomp }
|
19
19
|
it 'converts Markdown to AsciiDoc' do
|
20
20
|
(expect doc.to_asciidoc).to eql expected
|
21
21
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
`^` is often used for superscript
|
@@ -0,0 +1 @@
|
|
1
|
+
`^` is often used for superscript
|
@@ -0,0 +1 @@
|
|
1
|
+
use "[.code]``short``" as the attribute value
|
@@ -0,0 +1 @@
|
|
1
|
+
use "`short`" as the attribute value
|
@@ -0,0 +1 @@
|
|
1
|
+
assign the value "[.code]``short``" to the attribute
|
@@ -0,0 +1 @@
|
|
1
|
+
assign the value "`short`" to the attribute
|