reverse_adoc 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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