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.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/macos.yml +27 -0
  3. data/.github/workflows/ubuntu.yml +27 -0
  4. data/.github/workflows/windows.yml +30 -0
  5. data/.hound.yml +3 -0
  6. data/.rubocop.yml +10 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +25 -0
  9. data/README.adoc +290 -0
  10. data/Rakefile +14 -0
  11. data/bin/reverse_adoc +67 -0
  12. data/bin/w2a +85 -0
  13. data/lib/reverse_asciidoctor.rb +70 -0
  14. data/lib/reverse_asciidoctor/cleaner.rb +90 -0
  15. data/lib/reverse_asciidoctor/config.rb +53 -0
  16. data/lib/reverse_asciidoctor/converters.rb +33 -0
  17. data/lib/reverse_asciidoctor/converters/a.rb +38 -0
  18. data/lib/reverse_asciidoctor/converters/aside.rb +14 -0
  19. data/lib/reverse_asciidoctor/converters/audio.rb +34 -0
  20. data/lib/reverse_asciidoctor/converters/base.rb +24 -0
  21. data/lib/reverse_asciidoctor/converters/blockquote.rb +18 -0
  22. data/lib/reverse_asciidoctor/converters/br.rb +11 -0
  23. data/lib/reverse_asciidoctor/converters/bypass.rb +77 -0
  24. data/lib/reverse_asciidoctor/converters/code.rb +15 -0
  25. data/lib/reverse_asciidoctor/converters/div.rb +14 -0
  26. data/lib/reverse_asciidoctor/converters/drop.rb +18 -0
  27. data/lib/reverse_asciidoctor/converters/em.rb +18 -0
  28. data/lib/reverse_asciidoctor/converters/figure.rb +21 -0
  29. data/lib/reverse_asciidoctor/converters/h.rb +19 -0
  30. data/lib/reverse_asciidoctor/converters/head.rb +18 -0
  31. data/lib/reverse_asciidoctor/converters/hr.rb +11 -0
  32. data/lib/reverse_asciidoctor/converters/ignore.rb +12 -0
  33. data/lib/reverse_asciidoctor/converters/img.rb +80 -0
  34. data/lib/reverse_asciidoctor/converters/li.rb +24 -0
  35. data/lib/reverse_asciidoctor/converters/mark.rb +12 -0
  36. data/lib/reverse_asciidoctor/converters/math.rb +20 -0
  37. data/lib/reverse_asciidoctor/converters/ol.rb +46 -0
  38. data/lib/reverse_asciidoctor/converters/p.rb +17 -0
  39. data/lib/reverse_asciidoctor/converters/pass_through.rb +9 -0
  40. data/lib/reverse_asciidoctor/converters/pre.rb +38 -0
  41. data/lib/reverse_asciidoctor/converters/q.rb +12 -0
  42. data/lib/reverse_asciidoctor/converters/strong.rb +17 -0
  43. data/lib/reverse_asciidoctor/converters/sub.rb +12 -0
  44. data/lib/reverse_asciidoctor/converters/sup.rb +12 -0
  45. data/lib/reverse_asciidoctor/converters/table.rb +64 -0
  46. data/lib/reverse_asciidoctor/converters/td.rb +67 -0
  47. data/lib/reverse_asciidoctor/converters/text.rb +65 -0
  48. data/lib/reverse_asciidoctor/converters/th.rb +16 -0
  49. data/lib/reverse_asciidoctor/converters/tr.rb +22 -0
  50. data/lib/reverse_asciidoctor/converters/video.rb +36 -0
  51. data/lib/reverse_asciidoctor/errors.rb +10 -0
  52. data/lib/reverse_asciidoctor/version.rb +3 -0
  53. data/reverse_adoc.gemspec +35 -0
  54. data/spec/assets/anchors.html +22 -0
  55. data/spec/assets/basic.html +58 -0
  56. data/spec/assets/code.html +22 -0
  57. data/spec/assets/escapables.html +15 -0
  58. data/spec/assets/from_the_wild.html +23 -0
  59. data/spec/assets/full_example.html +49 -0
  60. data/spec/assets/html_fragment.html +3 -0
  61. data/spec/assets/lists.html +137 -0
  62. data/spec/assets/minimum.html +4 -0
  63. data/spec/assets/paragraphs.html +24 -0
  64. data/spec/assets/quotation.html +12 -0
  65. data/spec/assets/tables.html +99 -0
  66. data/spec/assets/unknown_tags.html +9 -0
  67. data/spec/components/anchors_spec.rb +21 -0
  68. data/spec/components/basic_spec.rb +49 -0
  69. data/spec/components/code_spec.rb +28 -0
  70. data/spec/components/escapables_spec.rb +23 -0
  71. data/spec/components/from_the_wild_spec.rb +17 -0
  72. data/spec/components/html_fragment_spec.rb +11 -0
  73. data/spec/components/lists_spec.rb +86 -0
  74. data/spec/components/paragraphs_spec.rb +15 -0
  75. data/spec/components/quotation_spec.rb +12 -0
  76. data/spec/components/tables_spec.rb +31 -0
  77. data/spec/components/unknown_tags_spec.rb +39 -0
  78. data/spec/lib/reverse_asciidoctor/cleaner_spec.rb +157 -0
  79. data/spec/lib/reverse_asciidoctor/config_spec.rb +26 -0
  80. data/spec/lib/reverse_asciidoctor/converters/aside_spec.rb +12 -0
  81. data/spec/lib/reverse_asciidoctor/converters/audio_spec.rb +18 -0
  82. data/spec/lib/reverse_asciidoctor/converters/blockquote_spec.rb +24 -0
  83. data/spec/lib/reverse_asciidoctor/converters/br_spec.rb +9 -0
  84. data/spec/lib/reverse_asciidoctor/converters/code_spec.rb +18 -0
  85. data/spec/lib/reverse_asciidoctor/converters/div_spec.rb +18 -0
  86. data/spec/lib/reverse_asciidoctor/converters/figure_spec.rb +13 -0
  87. data/spec/lib/reverse_asciidoctor/converters/img_spec.rb +28 -0
  88. data/spec/lib/reverse_asciidoctor/converters/li_spec.rb +13 -0
  89. data/spec/lib/reverse_asciidoctor/converters/mark_spec.rb +10 -0
  90. data/spec/lib/reverse_asciidoctor/converters/p_spec.rb +12 -0
  91. data/spec/lib/reverse_asciidoctor/converters/pre_spec.rb +45 -0
  92. data/spec/lib/reverse_asciidoctor/converters/q_spec.rb +10 -0
  93. data/spec/lib/reverse_asciidoctor/converters/strong_spec.rb +20 -0
  94. data/spec/lib/reverse_asciidoctor/converters/text_spec.rb +62 -0
  95. data/spec/lib/reverse_asciidoctor/converters/video_spec.rb +18 -0
  96. data/spec/lib/reverse_asciidoctor/converters_spec.rb +19 -0
  97. data/spec/lib/reverse_asciidoctor_spec.rb +37 -0
  98. data/spec/spec_helper.rb +21 -0
  99. 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!('&nbsp;', ' ') # 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