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
@@ -0,0 +1,34 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Audio < Base
4
+ def convert(node, state = {})
5
+ autoplay = node['autoplay']
6
+ loop_attr = node['loop']
7
+ controls = node['controls']
8
+ src = node['src']
9
+ id = node['id']
10
+ anchor = id ? "[[#{id}]]\n" : ""
11
+ title = extract_title(node)
12
+ title = ".#{title}\n" unless title.empty?
13
+ [anchor, title, "audio::", src, "[", options(node), "]"].join("")
14
+ end
15
+
16
+ def options(node)
17
+ autoplay = node['autoplay']
18
+ loop_attr = node['loop']
19
+ controls = node['controls']
20
+ ret = ""
21
+ if autoplay || loop_attr || controls
22
+ out = []
23
+ out << "autoplay" if autoplay
24
+ out << "loop" if loop_attr
25
+ out << "controls" if controls
26
+ ret = %{options="#{out.join(',')}"}
27
+ end
28
+ ret
29
+ end
30
+ end
31
+
32
+ register :audio, Audio.new
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Base
4
+ def treat_children(node, state)
5
+ node.children.inject('') do |memo, child|
6
+ memo << treat(child, state)
7
+ end
8
+ end
9
+
10
+ def treat(node, state)
11
+ ReverseAsciidoctor::Converters.lookup(node.name).convert(node, state)
12
+ end
13
+
14
+ def escape_keychars(string)
15
+ string.gsub(/(?<!\\)[*_]/, '*' => '\*', '_' => '\_')
16
+ end
17
+
18
+ def extract_title(node)
19
+ title = escape_keychars(node['title'].to_s)
20
+ title.empty? ? '' : %[ #{title}]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Blockquote < Base
4
+ def convert(node, state = {})
5
+ id = node['id']
6
+ anchor = id ? "[[#{id}]]\n" : ""
7
+ cite = node['cite']
8
+ attrs = cite ? "[quote, #{cite}]\n" : ""
9
+ content = treat_children(node, state).strip
10
+ content = ReverseAsciidoctor.cleaner.remove_newlines(content)
11
+ #"\n\n> " << content.lines.to_a.join('> ') << "\n\n"
12
+ "\n\n#{attrs}____\n" << content.lines.to_a.join('') << "\n____\n\n"
13
+ end
14
+ end
15
+
16
+ register :blockquote, Blockquote.new
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Br < Base
4
+ def convert(node, state = {})
5
+ " +\n"
6
+ end
7
+ end
8
+
9
+ register :br, Br.new
10
+ end
11
+ end
@@ -0,0 +1,77 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Bypass < Base
4
+ def convert(node, state = {})
5
+ treat_children(node, state)
6
+ end
7
+ end
8
+
9
+ register :document, Bypass.new
10
+ register :html, Bypass.new
11
+ register :body, Bypass.new
12
+ register :span, Bypass.new
13
+ register :thead, Bypass.new
14
+ register :tbody, Bypass.new
15
+ register :tfoot, Bypass.new
16
+ register :abbr, Bypass.new
17
+ register :acronym, Bypass.new
18
+ register :address, Bypass.new
19
+ register :applet, Bypass.new
20
+ register :map, Bypass.new
21
+ register :area, Bypass.new
22
+ register :bdi, Bypass.new
23
+ register :bdo, Bypass.new
24
+ register :big, Bypass.new
25
+ register :button, Bypass.new
26
+ register :canvas, Bypass.new
27
+ register :data, Bypass.new
28
+ register :datalist, Bypass.new
29
+ register :del, Bypass.new
30
+ register :ins, Bypass.new
31
+ register :dfn, Bypass.new
32
+ register :dialog, Bypass.new
33
+ register :embed, Bypass.new
34
+ register :fieldset, Bypass.new
35
+ register :font, Bypass.new
36
+ register :footer, Bypass.new
37
+ register :form, Bypass.new
38
+ register :frame, Bypass.new
39
+ register :frameset, Bypass.new
40
+ register :header, Bypass.new
41
+ register :iframe, Bypass.new
42
+ register :input, Bypass.new
43
+ register :label, Bypass.new
44
+ register :legend, Bypass.new
45
+ register :main, Bypass.new
46
+ register :menu, Bypass.new
47
+ register :menulist, Bypass.new
48
+ register :meter, Bypass.new
49
+ register :nav, Bypass.new
50
+ register :noframes, Bypass.new
51
+ register :noscript, Bypass.new
52
+ register :object, Bypass.new
53
+ register :optgroup, Bypass.new
54
+ register :option, Bypass.new
55
+ register :output, Bypass.new
56
+ register :param, Bypass.new
57
+ register :picture, Bypass.new
58
+ register :progress, Bypass.new
59
+ register :ruby, Bypass.new
60
+ register :rt, Bypass.new
61
+ register :rp, Bypass.new
62
+ register :s, Bypass.new
63
+ register :select, Bypass.new
64
+ register :small, Bypass.new
65
+ register :span, Bypass.new
66
+ register :strike, Bypass.new
67
+ register :details, Bypass.new
68
+ register :section, Bypass.new
69
+ register :summary, Bypass.new
70
+ register :svg, Bypass.new
71
+ register :template, Bypass.new
72
+ register :textarea, Bypass.new
73
+ register :track, Bypass.new
74
+ register :u, Bypass.new
75
+ register :wbr, Bypass.new
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Code < Base
4
+ def convert(node, state = {})
5
+ "`#{node.text}`"
6
+ end
7
+ end
8
+
9
+ register :code, Code.new
10
+ register :tt, Code.new
11
+ register :kbd, Code.new
12
+ register :samp, Code.new
13
+ register :var, Code.new
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Div < Base
4
+ def convert(node, state = {})
5
+ id = node['id']
6
+ anchor = id ? "[[#{id}]]\n" : ""
7
+ "\n#{anchor}" << treat_children(node, state) << "\n"
8
+ end
9
+ end
10
+
11
+ register :div, Div.new
12
+ register :article, Div.new
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Drop < Base
4
+ def convert(node, state = {})
5
+ ''
6
+ end
7
+ end
8
+
9
+ register :caption, Drop.new
10
+ register :figcaption, Drop.new
11
+ register :title, Drop.new
12
+ register :link, Drop.new
13
+ register :style, Drop.new
14
+ register :meta, Drop.new
15
+ register :script, Drop.new
16
+ register :comment, Drop.new
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Em < Base
4
+ def convert(node, state = {})
5
+ content = treat_children(node, state.merge(already_italic: true))
6
+ if content.strip.empty? || state[:already_italic]
7
+ content
8
+ else
9
+ "#{content[/^\s*/]}_#{content.strip}_#{content[/\s*$/]}"
10
+ end
11
+ end
12
+ end
13
+
14
+ register :em, Em.new
15
+ register :i, Em.new
16
+ register :cite, Em.new
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Figure < Base
4
+ def convert(node, state = {})
5
+ id = node['id']
6
+ anchor = id ? "[[#{id}]]\n" : ""
7
+ title = extract_title(node)
8
+ title = ".#{title}\n" unless title.empty?
9
+ "\n\n#{anchor}#{title}====\n" << treat_children(node, state).strip << "\n====\n\n"
10
+ end
11
+
12
+ def extract_title(node)
13
+ title = node.at("./figcaption")
14
+ return "" if title.nil?
15
+ treat_children(title, {})
16
+ end
17
+ end
18
+
19
+ register :figure, Figure.new
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class H < Base
4
+ def convert(node, state = {})
5
+ id = node['id']
6
+ anchor = id ? "[[#{id}]]\n" : ""
7
+ prefix = '=' * (node.name[/\d/].to_i + 1)
8
+ ["\n", anchor, prefix, ' ', treat_children(node, state), "\n"].join
9
+ end
10
+ end
11
+
12
+ register :h1, H.new
13
+ register :h2, H.new
14
+ register :h3, H.new
15
+ register :h4, H.new
16
+ register :h5, H.new
17
+ register :h6, H.new
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Head < Base
4
+ def convert(node, state = {})
5
+ title = extract_title(node)
6
+ "= #{title}\n:stem:\n\n"
7
+ end
8
+
9
+ def extract_title(node)
10
+ title = node.at("./title")
11
+ return "(???)" if title.nil?
12
+ title.text
13
+ end
14
+ end
15
+
16
+ register :head, Head.new
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Hr < Base
4
+ def convert(node, state = {})
5
+ "\n* * *\n"
6
+ end
7
+ end
8
+
9
+ register :hr, Hr.new
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Ignore < Base
4
+ def convert(node, state = {})
5
+ '' # noop
6
+ end
7
+ end
8
+
9
+ register :colgroup, Ignore.new
10
+ register :col, Ignore.new
11
+ end
12
+ end
@@ -0,0 +1,80 @@
1
+ require 'fileutils'
2
+
3
+ module ReverseAsciidoctor
4
+ module Converters
5
+ class Img < Base
6
+
7
+ def image_number
8
+ sprintf(
9
+ ReverseAsciidoctor.config.image_counter_pattern,
10
+ ReverseAsciidoctor.config.image_counter
11
+ )
12
+ end
13
+
14
+ def image_number_increment
15
+ ReverseAsciidoctor.config.image_counter += 1
16
+ end
17
+
18
+ def datauri2file(src)
19
+ %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ src
20
+
21
+ dest_dir = Pathname.new(ReverseAsciidoctor.config.destination).dirname
22
+ images_dir = dest_dir + 'images'
23
+ FileUtils.mkdir_p(images_dir)
24
+
25
+ ext = ""
26
+
27
+ if imgdata
28
+ file = Tempfile.new(["radoc", ".jpg"]) do |f|
29
+ f.binmode
30
+ f.write(Base64.strict_decode64(imgdata))
31
+ f.rewind
32
+ ext = MimeMagic.by_magic(f)
33
+ end
34
+
35
+ image_src_path = file.path
36
+ # puts "tempfile: #{file}"
37
+
38
+ else
39
+ ext = File.extname(src).strip.downcase[1..-1]
40
+ image_src_path = Pathname.new(ReverseAsciidoctor.config.sourcedir) + src
41
+
42
+ end
43
+
44
+ image_dest_path = images_dir + "#{image_number}.#{ext}"
45
+
46
+ # puts "image_dest_path: #{image_dest_path.to_s}"
47
+ # puts "image_src_path: #{image_src_path.to_s}"
48
+
49
+ FileUtils.cp(image_src_path, image_dest_path)
50
+ image_number_increment
51
+
52
+ image_dest_path.relative_path_from(dest_dir)
53
+ end
54
+
55
+ def convert(node, state = {})
56
+ alt = node['alt']
57
+ src = node['src']
58
+ id = node['id']
59
+ width = node['width']
60
+ height = node['height']
61
+ anchor = id ? "[[#{id}]]\n" : ""
62
+ title = extract_title(node)
63
+
64
+ if ReverseAsciidoctor.config.external_images
65
+ # puts "external image conversion #{id}, #{src}"
66
+ src = datauri2file(src)
67
+ end
68
+
69
+ title = ".#{title}\n" unless title.empty?
70
+ attrs = alt
71
+ attrs = "\"\"" if (width || height) && alt.nil?
72
+ attrs += ",#{width}" if width
73
+ attrs += ",#{height}" if width && height
74
+ [anchor, title, "image::", src, "[", attrs, "]"].join("")
75
+ end
76
+ end
77
+
78
+ register :img, Img.new
79
+ end
80
+ end
@@ -0,0 +1,24 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Li < Base
4
+ def convert(node, state = {})
5
+ id = node['id']
6
+ anchor = id ? "[[#{id}]]" : ""
7
+ content = treat_children(node, state)
8
+ prefix = prefix_for(node, state)
9
+ "#{prefix} #{anchor}#{content.chomp}\n"
10
+ end
11
+
12
+ def prefix_for(node, state)
13
+ length = state.fetch(:ol_count, 0)
14
+ if node.parent.name == 'ol'
15
+ "." * [length, 0].max
16
+ else
17
+ "*" * [length, 0].max
18
+ end
19
+ end
20
+ end
21
+
22
+ register :li, Li.new
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ module ReverseAsciidoctor
2
+ module Converters
3
+ class Mark < Base
4
+ def convert(node, state = {})
5
+ content = treat_children(node, state)
6
+ "#{content[/^\s*/]}##{content.strip}##{content[/\s*$/]}"
7
+ end
8
+ end
9
+
10
+ register :mark, Mark.new
11
+ end
12
+ end