reverse_adoc 0.2.3
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 +7 -0
- data/.github/workflows/macos.yml +27 -0
- data/.github/workflows/ubuntu.yml +27 -0
- data/.github/workflows/windows.yml +30 -0
- data/.hound.yml +3 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +25 -0
- data/README.adoc +290 -0
- data/Rakefile +14 -0
- data/bin/reverse_adoc +67 -0
- data/bin/w2a +85 -0
- data/lib/reverse_asciidoctor.rb +70 -0
- data/lib/reverse_asciidoctor/cleaner.rb +90 -0
- data/lib/reverse_asciidoctor/config.rb +53 -0
- data/lib/reverse_asciidoctor/converters.rb +33 -0
- data/lib/reverse_asciidoctor/converters/a.rb +38 -0
- data/lib/reverse_asciidoctor/converters/aside.rb +14 -0
- data/lib/reverse_asciidoctor/converters/audio.rb +34 -0
- data/lib/reverse_asciidoctor/converters/base.rb +24 -0
- data/lib/reverse_asciidoctor/converters/blockquote.rb +18 -0
- data/lib/reverse_asciidoctor/converters/br.rb +11 -0
- data/lib/reverse_asciidoctor/converters/bypass.rb +77 -0
- data/lib/reverse_asciidoctor/converters/code.rb +15 -0
- data/lib/reverse_asciidoctor/converters/div.rb +14 -0
- data/lib/reverse_asciidoctor/converters/drop.rb +18 -0
- data/lib/reverse_asciidoctor/converters/em.rb +18 -0
- data/lib/reverse_asciidoctor/converters/figure.rb +21 -0
- data/lib/reverse_asciidoctor/converters/h.rb +19 -0
- data/lib/reverse_asciidoctor/converters/head.rb +18 -0
- data/lib/reverse_asciidoctor/converters/hr.rb +11 -0
- data/lib/reverse_asciidoctor/converters/ignore.rb +12 -0
- data/lib/reverse_asciidoctor/converters/img.rb +80 -0
- data/lib/reverse_asciidoctor/converters/li.rb +24 -0
- data/lib/reverse_asciidoctor/converters/mark.rb +12 -0
- data/lib/reverse_asciidoctor/converters/math.rb +20 -0
- data/lib/reverse_asciidoctor/converters/ol.rb +46 -0
- data/lib/reverse_asciidoctor/converters/p.rb +17 -0
- data/lib/reverse_asciidoctor/converters/pass_through.rb +9 -0
- data/lib/reverse_asciidoctor/converters/pre.rb +38 -0
- data/lib/reverse_asciidoctor/converters/q.rb +12 -0
- data/lib/reverse_asciidoctor/converters/strong.rb +17 -0
- data/lib/reverse_asciidoctor/converters/sub.rb +12 -0
- data/lib/reverse_asciidoctor/converters/sup.rb +12 -0
- data/lib/reverse_asciidoctor/converters/table.rb +64 -0
- data/lib/reverse_asciidoctor/converters/td.rb +67 -0
- data/lib/reverse_asciidoctor/converters/text.rb +65 -0
- data/lib/reverse_asciidoctor/converters/th.rb +16 -0
- data/lib/reverse_asciidoctor/converters/tr.rb +22 -0
- data/lib/reverse_asciidoctor/converters/video.rb +36 -0
- data/lib/reverse_asciidoctor/errors.rb +10 -0
- data/lib/reverse_asciidoctor/version.rb +3 -0
- data/reverse_adoc.gemspec +35 -0
- data/spec/assets/anchors.html +22 -0
- data/spec/assets/basic.html +58 -0
- data/spec/assets/code.html +22 -0
- data/spec/assets/escapables.html +15 -0
- data/spec/assets/from_the_wild.html +23 -0
- data/spec/assets/full_example.html +49 -0
- data/spec/assets/html_fragment.html +3 -0
- data/spec/assets/lists.html +137 -0
- data/spec/assets/minimum.html +4 -0
- data/spec/assets/paragraphs.html +24 -0
- data/spec/assets/quotation.html +12 -0
- data/spec/assets/tables.html +99 -0
- data/spec/assets/unknown_tags.html +9 -0
- data/spec/components/anchors_spec.rb +21 -0
- data/spec/components/basic_spec.rb +49 -0
- data/spec/components/code_spec.rb +28 -0
- data/spec/components/escapables_spec.rb +23 -0
- data/spec/components/from_the_wild_spec.rb +17 -0
- data/spec/components/html_fragment_spec.rb +11 -0
- data/spec/components/lists_spec.rb +86 -0
- data/spec/components/paragraphs_spec.rb +15 -0
- data/spec/components/quotation_spec.rb +12 -0
- data/spec/components/tables_spec.rb +31 -0
- data/spec/components/unknown_tags_spec.rb +39 -0
- data/spec/lib/reverse_asciidoctor/cleaner_spec.rb +157 -0
- data/spec/lib/reverse_asciidoctor/config_spec.rb +26 -0
- data/spec/lib/reverse_asciidoctor/converters/aside_spec.rb +12 -0
- data/spec/lib/reverse_asciidoctor/converters/audio_spec.rb +18 -0
- data/spec/lib/reverse_asciidoctor/converters/blockquote_spec.rb +24 -0
- data/spec/lib/reverse_asciidoctor/converters/br_spec.rb +9 -0
- data/spec/lib/reverse_asciidoctor/converters/code_spec.rb +18 -0
- data/spec/lib/reverse_asciidoctor/converters/div_spec.rb +18 -0
- data/spec/lib/reverse_asciidoctor/converters/figure_spec.rb +13 -0
- data/spec/lib/reverse_asciidoctor/converters/img_spec.rb +28 -0
- data/spec/lib/reverse_asciidoctor/converters/li_spec.rb +13 -0
- data/spec/lib/reverse_asciidoctor/converters/mark_spec.rb +10 -0
- data/spec/lib/reverse_asciidoctor/converters/p_spec.rb +12 -0
- data/spec/lib/reverse_asciidoctor/converters/pre_spec.rb +45 -0
- data/spec/lib/reverse_asciidoctor/converters/q_spec.rb +10 -0
- data/spec/lib/reverse_asciidoctor/converters/strong_spec.rb +20 -0
- data/spec/lib/reverse_asciidoctor/converters/text_spec.rb +62 -0
- data/spec/lib/reverse_asciidoctor/converters/video_spec.rb +18 -0
- data/spec/lib/reverse_asciidoctor/converters_spec.rb +19 -0
- data/spec/lib/reverse_asciidoctor_spec.rb +37 -0
- data/spec/spec_helper.rb +21 -0
- metadata +299 -0
data/bin/reverse_adoc
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Usage: reverse_asciidoctor [FILE]...
|
|
3
|
+
# Usage: cat FILE | reverse_asciidoctor
|
|
4
|
+
require 'reverse_asciidoctor'
|
|
5
|
+
require 'optparse'
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
|
|
8
|
+
OptionParser.new do |opts|
|
|
9
|
+
opts.banner = "Usage: reverse_adoc [options] <file>"
|
|
10
|
+
opts.on('-m', '--mathml2asciimath', 'Convert MathML to AsciiMath') do |v|
|
|
11
|
+
ReverseAsciidoctor.config.mathml2asciimath = true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
opts.on('-oFILENAME', '--output=FILENAME', 'Output file to write to') do |v|
|
|
15
|
+
ReverseAsciidoctor.config.destination = File.expand_path(v)
|
|
16
|
+
# puts "output goes to #{ReverseAsciidoctor.config.destination}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
opts.on('-e', '--external-images', 'Export images if data URI') do |v|
|
|
20
|
+
ReverseAsciidoctor.config.external_images = true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
opts.on('-u', '--unknown_tags [pass_through, drop, bypass, raise]', 'Unknown tag handling (default: pass_through)') do |v|
|
|
24
|
+
ReverseAsciidoctor.config.unknown_tags = v
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
opts.on('-v', '--version', 'Version information') do |v|
|
|
28
|
+
puts "reverse_adoc: v#{ReverseAsciidoctor::VERSION}"
|
|
29
|
+
exit
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
opts.on("-h", "--help", "Prints this help") do
|
|
33
|
+
puts opts
|
|
34
|
+
exit
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end.parse!
|
|
38
|
+
|
|
39
|
+
if filename = ARGV.pop
|
|
40
|
+
input_content = IO.read(filename)
|
|
41
|
+
ReverseAsciidoctor.config.sourcedir = File.dirname(File.expand_path(filename))
|
|
42
|
+
else
|
|
43
|
+
if ReverseAsciidoctor.config.external_images
|
|
44
|
+
raise "The -e | --external-images feature cannot be used with STDIN input. Exiting."
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
input_content = ARGF.read
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if ReverseAsciidoctor.config.external_images && ReverseAsciidoctor.config.destination.nil?
|
|
51
|
+
raise "The -e | --external-images feature must be used with -o | --output. Exiting."
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Read from STDIN
|
|
55
|
+
adoc_content = ReverseAsciidoctor.convert(input_content)
|
|
56
|
+
|
|
57
|
+
# Print to STDOUT
|
|
58
|
+
unless ReverseAsciidoctor.config.destination
|
|
59
|
+
puts adoc_content
|
|
60
|
+
exit
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Write output to ReverseAsciidoctor.config.destination
|
|
64
|
+
FileUtils.mkdir_p(File.dirname(ReverseAsciidoctor.config.destination))
|
|
65
|
+
File.open(ReverseAsciidoctor.config.destination, "w") do |file|
|
|
66
|
+
file.write(adoc_content)
|
|
67
|
+
end
|
data/bin/w2a
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'word-to-markdown'
|
|
5
|
+
require 'optparse'
|
|
6
|
+
require 'reverse_asciidoctor'
|
|
7
|
+
|
|
8
|
+
def scrub_whitespace(string)
|
|
9
|
+
string = string.dup
|
|
10
|
+
string.gsub!(' ', ' ') # HTML encoded spaces
|
|
11
|
+
string.sub!(/\A[[:space:]]+/, '') # document leading whitespace
|
|
12
|
+
string.sub!(/[[:space:]]+\z/, '') # document trailing whitespace
|
|
13
|
+
string.gsub!(/([ ]+)$/, '') # line trailing whitespace
|
|
14
|
+
string.gsub!(/\n\n\n\n/, "\n\n") # Quadruple line breaks
|
|
15
|
+
string.delete!(' ') # Unicode non-breaking spaces, injected as tabs
|
|
16
|
+
# following added by me
|
|
17
|
+
string.gsub!(%r{<h[1-9][^>]*></h1>}, " ") # I don't know why Libre Office is inserting them, but they need to go
|
|
18
|
+
string.gsub!(%r{<h1[^>]* style="vertical-align: super;[^>]*>([^<]+)</h1>},
|
|
19
|
+
"<sup>\\1</sup>") # I absolutely don't know why Libre Office is rendering superscripts as h1
|
|
20
|
+
string
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
ARGV.push('-h') if ARGV.empty?
|
|
24
|
+
|
|
25
|
+
OptionParser.new do |opts|
|
|
26
|
+
opts.banner = "Usage: w2a [options] <file>"
|
|
27
|
+
opts.on('-m', '--mathml2asciimath', 'Convert MathML to AsciiMath') do |v|
|
|
28
|
+
ReverseAsciidoctor.config.mathml2asciimath = true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
opts.on('-oFILENAME', '--output=FILENAME', 'Output file to write to') do |v|
|
|
32
|
+
ReverseAsciidoctor.config.destination = File.expand_path(v)
|
|
33
|
+
# puts "output goes to #{ReverseAsciidoctor.config.destination}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
opts.on('-e', '--external-images', 'Export images if data URI') do |v|
|
|
37
|
+
ReverseAsciidoctor.config.external_images = true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
opts.on('-v', '--version', 'Version information') do |v|
|
|
41
|
+
puts "reverse_adoc: v#{ReverseAsciidoctor::VERSION}"
|
|
42
|
+
puts "[dependency] WordToMarkdown: v#{WordToMarkdown::VERSION}"
|
|
43
|
+
unless Gem.win_platform?
|
|
44
|
+
puts "[dependency] LibreOffice: v#{WordToMarkdown.soffice.version}"
|
|
45
|
+
else
|
|
46
|
+
puts "[dependency] LibreOffice: version not available on Windows"
|
|
47
|
+
end
|
|
48
|
+
exit
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
opts.on("-h", "--help", "Prints this help") do
|
|
52
|
+
puts opts
|
|
53
|
+
exit
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end.parse!
|
|
57
|
+
|
|
58
|
+
filename = ARGV.pop
|
|
59
|
+
raise "Please provide an input file to process. Exiting." unless filename
|
|
60
|
+
|
|
61
|
+
if ReverseAsciidoctor.config.external_images && ReverseAsciidoctor.config.destination.nil?
|
|
62
|
+
raise "The -e | --external-images feature must be used with -o | --output. Exiting."
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
ReverseAsciidoctor.config.sourcedir = Dir.mktmpdir
|
|
66
|
+
# puts "ReverseAsciidoctor.config.sourcedir #{ReverseAsciidoctor.config.sourcedir}"
|
|
67
|
+
|
|
68
|
+
doc = WordToMarkdown.new(filename, ReverseAsciidoctor.config.sourcedir)
|
|
69
|
+
adoc_content = ReverseAsciidoctor.convert(
|
|
70
|
+
scrub_whitespace(doc.document.html),
|
|
71
|
+
WordToMarkdown::REVERSE_MARKDOWN_OPTIONS
|
|
72
|
+
)
|
|
73
|
+
# puts scrub_whitespace(doc.document.html)
|
|
74
|
+
|
|
75
|
+
# Print to STDOUT
|
|
76
|
+
unless ReverseAsciidoctor.config.destination
|
|
77
|
+
puts adoc_content
|
|
78
|
+
exit
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Write output to ReverseAsciidoctor.config.destination
|
|
82
|
+
FileUtils.mkdir_p(File.dirname(ReverseAsciidoctor.config.destination))
|
|
83
|
+
File.open(ReverseAsciidoctor.config.destination, "w") do |file|
|
|
84
|
+
file.write(adoc_content)
|
|
85
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
require 'nokogiri'
|
|
3
|
+
require 'reverse_asciidoctor/version'
|
|
4
|
+
require 'reverse_asciidoctor/errors'
|
|
5
|
+
require 'reverse_asciidoctor/cleaner'
|
|
6
|
+
require 'reverse_asciidoctor/config'
|
|
7
|
+
require 'reverse_asciidoctor/converters'
|
|
8
|
+
require 'reverse_asciidoctor/converters/base'
|
|
9
|
+
require 'reverse_asciidoctor/converters/a'
|
|
10
|
+
require 'reverse_asciidoctor/converters/aside'
|
|
11
|
+
require 'reverse_asciidoctor/converters/audio'
|
|
12
|
+
require 'reverse_asciidoctor/converters/blockquote'
|
|
13
|
+
require 'reverse_asciidoctor/converters/br'
|
|
14
|
+
require 'reverse_asciidoctor/converters/bypass'
|
|
15
|
+
require 'reverse_asciidoctor/converters/code'
|
|
16
|
+
require 'reverse_asciidoctor/converters/div'
|
|
17
|
+
require 'reverse_asciidoctor/converters/drop'
|
|
18
|
+
require 'reverse_asciidoctor/converters/em'
|
|
19
|
+
require 'reverse_asciidoctor/converters/figure'
|
|
20
|
+
require 'reverse_asciidoctor/converters/h'
|
|
21
|
+
require 'reverse_asciidoctor/converters/head'
|
|
22
|
+
require 'reverse_asciidoctor/converters/hr'
|
|
23
|
+
require 'reverse_asciidoctor/converters/ignore'
|
|
24
|
+
require 'reverse_asciidoctor/converters/img'
|
|
25
|
+
require 'reverse_asciidoctor/converters/mark'
|
|
26
|
+
require 'reverse_asciidoctor/converters/li'
|
|
27
|
+
require 'reverse_asciidoctor/converters/ol'
|
|
28
|
+
require 'reverse_asciidoctor/converters/p'
|
|
29
|
+
require 'reverse_asciidoctor/converters/pass_through'
|
|
30
|
+
require 'reverse_asciidoctor/converters/pre'
|
|
31
|
+
require 'reverse_asciidoctor/converters/q'
|
|
32
|
+
require 'reverse_asciidoctor/converters/strong'
|
|
33
|
+
require 'reverse_asciidoctor/converters/sup'
|
|
34
|
+
require 'reverse_asciidoctor/converters/sub'
|
|
35
|
+
require 'reverse_asciidoctor/converters/table'
|
|
36
|
+
require 'reverse_asciidoctor/converters/td'
|
|
37
|
+
require 'reverse_asciidoctor/converters/th'
|
|
38
|
+
require 'reverse_asciidoctor/converters/text'
|
|
39
|
+
require 'reverse_asciidoctor/converters/tr'
|
|
40
|
+
require 'reverse_asciidoctor/converters/video'
|
|
41
|
+
require 'reverse_asciidoctor/converters/math'
|
|
42
|
+
|
|
43
|
+
module ReverseAsciidoctor
|
|
44
|
+
|
|
45
|
+
def self.convert(input, options = {})
|
|
46
|
+
root = case input
|
|
47
|
+
when String then Nokogiri::HTML(input).root
|
|
48
|
+
when Nokogiri::XML::Document then input.root
|
|
49
|
+
when Nokogiri::XML::Node then input
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
root or return ''
|
|
53
|
+
|
|
54
|
+
config.with(options) do
|
|
55
|
+
result = ReverseAsciidoctor::Converters.lookup(root.name).convert(root)
|
|
56
|
+
cleaner.tidy(result)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.config
|
|
61
|
+
@config ||= Config.new
|
|
62
|
+
yield @config if block_given?
|
|
63
|
+
@config
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.cleaner
|
|
67
|
+
@cleaner ||= Cleaner.new
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module ReverseAsciidoctor
|
|
2
|
+
class Cleaner
|
|
3
|
+
|
|
4
|
+
def tidy(string)
|
|
5
|
+
result = remove_inner_whitespaces(string)
|
|
6
|
+
result = remove_newlines(result)
|
|
7
|
+
result = remove_leading_newlines(result)
|
|
8
|
+
result = clean_tag_borders(result)
|
|
9
|
+
clean_punctuation_characters(result)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def remove_newlines(string)
|
|
13
|
+
string.gsub(/\n{3,}/, "\n\n")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def remove_leading_newlines(string)
|
|
17
|
+
string.gsub(/\A\n+/, '')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def remove_inner_whitespaces(string)
|
|
21
|
+
unless string.nil?
|
|
22
|
+
string.gsub!(/\n stem:\[/, "\nstem:[")
|
|
23
|
+
string.gsub!(/(stem:\[([^\]]|\\\])*\])\n(?=\S)/, "\\1 ")
|
|
24
|
+
string.gsub!(/(stem:\[([^\]]|\\\])*\])\s+(?=[\^-])/, "\\1")
|
|
25
|
+
end
|
|
26
|
+
string.each_line.inject("") do |memo, line|
|
|
27
|
+
memo + preserve_border_whitespaces(line) do
|
|
28
|
+
line.strip.gsub(/[ \t]{2,}/, ' ')
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Find non-asterisk content that is enclosed by two or
|
|
34
|
+
# more asterisks. Ensure that only one whitespace occurs
|
|
35
|
+
# in the border area.
|
|
36
|
+
# Same for underscores and brackets.
|
|
37
|
+
def clean_tag_borders(string)
|
|
38
|
+
result = string.gsub(/\s?\*{2,}.*?\*{2,}\s?/) do |match|
|
|
39
|
+
preserve_border_whitespaces(match, default_border: ReverseAsciidoctor.config.tag_border) do
|
|
40
|
+
match.strip.sub('** ', '**').sub(' **', '**')
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
result = result.gsub(/\s?\_{2,}.*?\_{2,}\s?/) do |match|
|
|
45
|
+
preserve_border_whitespaces(match, default_border: ReverseAsciidoctor.config.tag_border) do
|
|
46
|
+
match.strip.sub('__ ', '__').sub(' __', '__')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
result = result.gsub(/\s?~{2,}.*?~{2,}\s?/) do |match|
|
|
51
|
+
preserve_border_whitespaces(match, default_border: ReverseAsciidoctor.config.tag_border) do
|
|
52
|
+
match.strip.sub('~~ ', '~~').sub(' ~~', '~~')
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
result.gsub(/\s?\[.*?\]\s?/) do |match|
|
|
57
|
+
preserve_border_whitespaces(match) do
|
|
58
|
+
match.strip.sub('[ ', '[').sub(' ]', ']')
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def clean_punctuation_characters(string)
|
|
64
|
+
string.gsub(/(\*\*|~~|__)\s([\.!\?'"])/, "\\1".strip + "\\2")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def preserve_border_whitespaces(string, options = {}, &block)
|
|
70
|
+
return string if string =~ /\A\s*\Z/
|
|
71
|
+
default_border = options.fetch(:default_border, '')
|
|
72
|
+
# If the string contains part of a link so the characters [,],(,)
|
|
73
|
+
# then don't add any extra spaces
|
|
74
|
+
default_border = '' if string =~ /[\[\(\]\)]/
|
|
75
|
+
string_start = present_or_default(string[/\A\s*/], default_border)
|
|
76
|
+
string_end = present_or_default(string[/\s*\Z/], default_border)
|
|
77
|
+
result = yield
|
|
78
|
+
string_start + result + string_end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def present_or_default(string, default)
|
|
82
|
+
if string.nil? || string.empty?
|
|
83
|
+
default
|
|
84
|
+
else
|
|
85
|
+
string
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'tmpdir'
|
|
2
|
+
|
|
3
|
+
module ReverseAsciidoctor
|
|
4
|
+
class Config
|
|
5
|
+
attr_accessor :unknown_tags, :tag_border, :mathml2asciimath, :external_images,
|
|
6
|
+
:destination, :sourcedir, :image_counter, :image_counter_pattern
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@unknown_tags = :pass_through
|
|
10
|
+
@mathml2asciimath = false
|
|
11
|
+
@external_images = false
|
|
12
|
+
|
|
13
|
+
# Destination to save file and images
|
|
14
|
+
@destination = nil
|
|
15
|
+
|
|
16
|
+
# Source of HTML
|
|
17
|
+
# @sourcedir = nil
|
|
18
|
+
|
|
19
|
+
# Image counter, assuming there are max 999 images
|
|
20
|
+
@image_counter = 1
|
|
21
|
+
# pad with 0s
|
|
22
|
+
@image_counter_pattern = '%03d'
|
|
23
|
+
|
|
24
|
+
@em_delimiter = '_'.freeze
|
|
25
|
+
@strong_delimiter = '*'.freeze
|
|
26
|
+
@inline_options = {}
|
|
27
|
+
@tag_border = ' '.freeze
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def with(options = {})
|
|
31
|
+
@inline_options = options
|
|
32
|
+
result = yield
|
|
33
|
+
@inline_options = {}
|
|
34
|
+
result
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def unknown_tags
|
|
38
|
+
@inline_options[:unknown_tags] || @unknown_tags
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def mathml2asciimath
|
|
42
|
+
@inline_options[:mathml2asciimath] || @mathml2asciimath
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def external_images
|
|
46
|
+
@inline_options[:external_images] || @external_images
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def tag_border
|
|
50
|
+
@inline_options[:tag_border] || @tag_border
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module ReverseAsciidoctor
|
|
2
|
+
module Converters
|
|
3
|
+
def self.register(tag_name, converter)
|
|
4
|
+
@@converters ||= {}
|
|
5
|
+
@@converters[tag_name.to_sym] = converter
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.unregister(tag_name)
|
|
9
|
+
@@converters.delete(tag_name.to_sym)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.lookup(tag_name)
|
|
13
|
+
@@converters[tag_name.to_sym] or default_converter(tag_name)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def self.default_converter(tag_name)
|
|
19
|
+
case ReverseAsciidoctor.config.unknown_tags.to_sym
|
|
20
|
+
when :pass_through
|
|
21
|
+
ReverseAsciidoctor::Converters::PassThrough.new
|
|
22
|
+
when :drop
|
|
23
|
+
ReverseAsciidoctor::Converters::Drop.new
|
|
24
|
+
when :bypass
|
|
25
|
+
ReverseAsciidoctor::Converters::Bypass.new
|
|
26
|
+
when :raise
|
|
27
|
+
raise UnknownTagError, "unknown tag: #{tag_name}"
|
|
28
|
+
else
|
|
29
|
+
raise InvalidConfigurationError, "unknown value #{ReverseAsciidoctor.config.unknown_tags.inspect} for ReverseAsciidoctor.config.unknown_tags"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
|
|
3
|
+
module ReverseAsciidoctor
|
|
4
|
+
module Converters
|
|
5
|
+
class A < Base
|
|
6
|
+
def convert(node, state = {})
|
|
7
|
+
name = treat_children(node, state)
|
|
8
|
+
href = node['href']
|
|
9
|
+
title = extract_title(node)
|
|
10
|
+
id = node['id'] || node['name']
|
|
11
|
+
|
|
12
|
+
if !id.nil? && !id.empty?
|
|
13
|
+
"[[#{id}]]"
|
|
14
|
+
elsif href.to_s.start_with?('#')
|
|
15
|
+
href = href.sub(/^#/, "")
|
|
16
|
+
if name.empty?
|
|
17
|
+
"<<#{href}>>"
|
|
18
|
+
else
|
|
19
|
+
"<<#{href},#{name}>>"
|
|
20
|
+
end
|
|
21
|
+
elsif href.to_s.empty?
|
|
22
|
+
name
|
|
23
|
+
else
|
|
24
|
+
name = title if name.empty?
|
|
25
|
+
href = "link:#{href}" unless href.to_s =~ URI::DEFAULT_PARSER.make_regexp
|
|
26
|
+
link = "#{href}[#{name}]"
|
|
27
|
+
link.prepend(' ')
|
|
28
|
+
link
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
register :a, A.new
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module ReverseAsciidoctor
|
|
2
|
+
module Converters
|
|
3
|
+
class Aside < Base
|
|
4
|
+
def convert(node, state = {})
|
|
5
|
+
id = node['id']
|
|
6
|
+
anchor = id ? "[[#{id}]]\n" : ""
|
|
7
|
+
content = treat_children(node, state).strip
|
|
8
|
+
"\n\n****\n" << treat_children(node, state) << "\n****\n\n"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
register :aside, Aside.new
|
|
13
|
+
end
|
|
14
|
+
end
|