reverse_asciidoctor 0.1.0

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