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,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Config do
4
+ describe '#with' do
5
+ let(:config) { ReverseAsciidoctor.config }
6
+
7
+ it 'takes additional options into account' do
8
+ config.with(tag_border: :foobar) do
9
+ expect(ReverseAsciidoctor.config.tag_border).to eq :foobar
10
+ end
11
+ end
12
+
13
+ it 'returns the result of a given block' do
14
+ expect(config.with { :something }).to eq :something
15
+ end
16
+
17
+ it 'resets to original settings afterwards' do
18
+ config.tag_border = :foo
19
+ config.with(tag_border: :bar) do
20
+ expect(ReverseAsciidoctor.config.tag_border).to eq :bar
21
+ end
22
+ expect(ReverseAsciidoctor.config.tag_border).to eq :foo
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Aside do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Aside.new }
6
+
7
+ it 'converts aside' do
8
+ input = node_for("<aside><ul><li>foo</li></ul></aside>")
9
+ result = converter.convert(input)
10
+ expect(result).to eq "\n\n\*\*\*\*\n\n* foo\n\n\*\*\*\*\n\n"
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Audio do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Audio.new }
6
+
7
+ it 'converts audio with no attributes' do
8
+ node = node_for("<audio src='example.mp3'/>")
9
+ expect(converter.convert(node)).to include "audio::example.mp3[]"
10
+ end
11
+
12
+ it 'converts audio with full set of attributes' do
13
+ node = node_for("<audio id='A' src='example.mp3' loop='loop'/>")
14
+ expect(converter.convert(node)).to include "[[A]]\naudio::example.mp3[options=\"loop\"]"
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Blockquote do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Blockquote.new }
6
+
7
+ it 'converts nested elements as well' do
8
+ input = node_for("<blockquote><ul><li>foo</li></ul></blockquote>")
9
+ result = converter.convert(input)
10
+ expect(result).to eq "\n\n____\n* foo\n____\n\n"
11
+ end
12
+
13
+ it 'can deal with paragraphs inside' do
14
+ input = node_for("<blockquote><p>Some text.</p><p>Some more text.</p></blockquote>")
15
+ result = converter.convert(input)
16
+ expect(result).to eq "\n\n____\nSome text.\n\nSome more text.\n____\n\n"
17
+ end
18
+
19
+ it 'can deal with cite attribute' do
20
+ input = node_for("<blockquote cite='http://www.example.com'><p>Some text.</p><p>Some more text.</p></blockquote>")
21
+ result = converter.convert(input)
22
+ expect(result).to eq "\n\n[quote, http://www.example.com]\n____\nSome text.\n\nSome more text.\n____\n\n"
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Br do
4
+ let(:converter) { ReverseAsciidoctor::Converters::Br.new }
5
+
6
+ it 'just converts into two spaces and a newline' do
7
+ expect(converter.convert(:anything)).to eq " \+\n"
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Code do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Code.new }
6
+
7
+ it 'converts as backtick' do
8
+ node = node_for("<code>puts foo</code>")
9
+ expect(converter.convert(node)).to include "`puts foo`"
10
+ end
11
+
12
+ it 'converts as backtick' do
13
+ node = node_for("<tt>puts foo</tt>")
14
+ expect(converter.convert(node)).to include "`puts foo`"
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Code do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Div.new }
6
+
7
+ it 'converts div' do
8
+ node = node_for("<div>puts foo</div>")
9
+ expect(converter.convert(node)).to include "\nputs foo"
10
+ end
11
+
12
+ it 'converts div with anchor' do
13
+ node = node_for("<div id='A'>puts foo</div>")
14
+ expect(converter.convert(node)).to include "\n[[A]]\nputs foo"
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Figure do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Figure.new }
6
+
7
+ it 'converts figure' do
8
+ node = node_for("<figure id='A'><img src='example.jpg'/><figcaption>Figure <i>caption</i></figcaption></figure>")
9
+ expect(converter.convert(node)).to include "[[A]]\n.Figure _caption_\n====\nimage::example.jpg[]\n====\n"
10
+
11
+ end
12
+ end
13
+
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Img do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Img.new }
6
+
7
+ it 'converts image with no attributes' do
8
+ node = node_for("<img src='example.jpg'/>")
9
+ expect(converter.convert(node)).to include "image::example.jpg[]"
10
+ end
11
+
12
+ it 'converts image with full set of attributes' do
13
+ node = node_for("<img id='A' alt='Alt Text' src='example.jpg' width='30' height='40'/>")
14
+ expect(converter.convert(node)).to include "[[A]]\nimage::example.jpg[Alt Text,30,40]"
15
+ end
16
+
17
+ it 'converts image with alt text, no width and height' do
18
+ node = node_for("<img id='A' alt='Alt Text' src='example.jpg'/>")
19
+ expect(converter.convert(node)).to include "[[A]]\nimage::example.jpg[Alt Text]"
20
+ end
21
+
22
+ it 'converts image with width and height, no alt text' do
23
+ node = node_for("<img id='A' src='example.jpg' width='30' height='40'/>")
24
+ expect(converter.convert(node)).to include "[[A]]\nimage::example.jpg[\"\",30,40]"
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Li do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Li.new }
6
+
7
+ it 'does not fail without a valid parent context' do
8
+ input = node_for("<li>foo</li>")
9
+ result = converter.convert(input)
10
+ expect(result).to eq " foo\n"
11
+ end
12
+
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Mark do
4
+ let(:converter) { ReverseAsciidoctor::Converters::Mark.new }
5
+
6
+ it 'renders mark' do
7
+ input = node_for('<mark>A</mark>')
8
+ expect(converter.convert(input)).to eq '#A#'
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::P do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::P.new }
6
+
7
+ it 'converts p with anchor' do
8
+ node = node_for("<p id='A'>puts foo</p>")
9
+ expect(converter.convert(node)).to include "\n[[A]]\nputs foo"
10
+ end
11
+ end
12
+
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Pre do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Pre.new }
6
+
7
+ it 'converts as literal' do
8
+ node = node_for("<pre>puts foo</pre>")
9
+ expect(converter.convert(node)).to include "....\nputs foo\n....\n"
10
+ end
11
+
12
+ it 'converts as literal with anchor' do
13
+ node = node_for("<pre id='A'>puts foo</pre>")
14
+ expect(converter.convert(node)).to include "[[A]]\n....\nputs foo\n....\n"
15
+ end
16
+
17
+ it 'preserves new lines' do
18
+ node = node_for("<pre>foo\nbar</pre>")
19
+ expect(converter.convert(node)).to include "....\nfoo\nbar\n....\n"
20
+ end
21
+
22
+ it 'preserves xml' do
23
+ node = node_for("<pre><code>x</code><br/><p>hello</p></pre>")
24
+ expect(converter.convert(node)).to include "....\n<code>x</code><br><p>hello</p>\n....\n"
25
+ end
26
+
27
+ context 'syntax highlighting' do
28
+ it 'works for "highlight-lang" mechanism' do
29
+ div = node_for("<div class='highlight highlight-ruby'><pre>puts foo</pre></div>")
30
+ pre = div.children.first
31
+ expect(converter.convert(pre)).to include "[source,ruby]\n----\nputs foo\n----\n"
32
+ end
33
+
34
+ it 'works for the confluence mechanism' do
35
+ pre = node_for("<pre class='theme: Confluence; brush: html/xml; gutter: false'>puts foo</pre>")
36
+ expect(converter.convert(pre)).to include "[source,html/xml]\n----\nputs foo\n----\n"
37
+ end
38
+
39
+ it 'works for the confluence mechanism, with anchor' do
40
+ pre = node_for("<pre id = 'A' class='theme: Confluence; brush: html/xml; gutter: false'>puts foo</pre>")
41
+ expect(converter.convert(pre)).to include "[[A]]\n[source,html/xml]\n----\nputs foo\n----\n"
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Q do
4
+ let(:converter) { ReverseAsciidoctor::Converters::Q.new }
5
+
6
+ it 'renders q' do
7
+ input = node_for('<q>A</q>')
8
+ expect(converter.convert(input)).to eq '"A"'
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Strong do
4
+ let(:converter) { ReverseAsciidoctor::Converters::Strong.new }
5
+
6
+ it 'returns an empty string if the node is empty' do
7
+ input = node_for('<strong></strong>')
8
+ expect(converter.convert(input)).to eq ''
9
+ end
10
+
11
+ it 'returns just the content if the strong tag is nested in another strong' do
12
+ input = node_for('<strong><strong>foo</strong></strong>')
13
+ expect(converter.convert(input.children.first, already_strong: true)).to eq 'foo'
14
+ end
15
+
16
+ it 'moves border whitespaces outside of the delimiters tag' do
17
+ input = node_for("<strong> \n foo </strong>")
18
+ expect(converter.convert(input)).to eq " *foo* "
19
+ end
20
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Text do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Text.new }
6
+
7
+ it 'treats newline within text as a single whitespace' do
8
+ input = node_for("<p>foo\nbar</p>")
9
+ result = converter.convert(input)
10
+ expect(result).to eq 'foo bar'
11
+ end
12
+
13
+ it 'removes leading newlines' do
14
+ input = node_for("<p>\n\nfoo bar</p>")
15
+ result = converter.convert(input)
16
+ expect(result).to eq 'foo bar'
17
+ end
18
+
19
+ it 'removes trailing newlines' do
20
+ input = node_for("<p>foo bar\n\n</p>")
21
+ result = converter.convert(input)
22
+ expect(result).to eq 'foo bar'
23
+ end
24
+
25
+ it 'keeps nbsps' do
26
+ input = node_for("<p>foo\u00A0bar \u00A0</p>")
27
+ result = converter.convert(input)
28
+ expect(result).to eq "foo&nbsp;bar &nbsp;"
29
+ end
30
+
31
+ it 'keeps escaped HTML-ish characters' do
32
+ input = node_for("<p>&lt;foo&gt;</p>")
33
+ result = converter.convert(input)
34
+ expect(result).to eq '\<foo\>'
35
+ end
36
+
37
+ context 'within backticks' do
38
+ it "preserves single underscores" do
39
+ input = node_for("<p>`foo_bar`</p>")
40
+ result = converter.convert(input)
41
+ expect(result).to eq '`foo_bar`'
42
+ end
43
+
44
+ it "preserves multiple underscores" do
45
+ input = node_for("<p>`foo_bar __example__`</p>")
46
+ result = converter.convert(input)
47
+ expect(result).to eq '`foo_bar __example__`'
48
+ end
49
+
50
+ it "preserves single asterisks" do
51
+ input = node_for("<p>`def foo *args`</p>")
52
+ result = converter.convert(input)
53
+ expect(result).to eq '`def foo *args`'
54
+ end
55
+
56
+ it "preserves multiple asterisks" do
57
+ input = node_for("<p>`def foo 2***3`</p>")
58
+ result = converter.convert(input)
59
+ expect(result).to eq '`def foo 2***3`'
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters::Video do
4
+
5
+ let(:converter) { ReverseAsciidoctor::Converters::Video.new }
6
+
7
+ it 'converts audio with no attributes' do
8
+ node = node_for("<audio src='example.mp3'/>")
9
+ expect(converter.convert(node)).to include "video::example.mp3[]"
10
+ end
11
+
12
+ it 'converts audio with full set of attributes' do
13
+ node = node_for("<audio id='A' src='example.mp3' loop='loop'/>")
14
+ expect(converter.convert(node)).to include "[[A]]\nvideo::example.mp3[options=\"loop\"]"
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Converters do
4
+ before { ReverseAsciidoctor.config.unknown_tags = :raise }
5
+ let(:converters) { ReverseAsciidoctor::Converters }
6
+
7
+ describe '.register and .unregister' do
8
+ it 'adds a converter mapping to the list' do
9
+ expect { converters.lookup(:foo) }.to raise_error ReverseAsciidoctor::UnknownTagError
10
+
11
+ converters.register :foo, :foobar
12
+ expect(converters.lookup(:foo)).to eq :foobar
13
+
14
+ converters.unregister :foo
15
+ expect { converters.lookup(:foo) }.to raise_error ReverseAsciidoctor::UnknownTagError
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+ let(:input) { File.read('spec/assets/minimum.html') }
5
+ let(:document) { Nokogiri::HTML(input) }
6
+
7
+ it "parses nokogiri documents" do
8
+ expect { ReverseAsciidoctor.convert(document) }.not_to raise_error
9
+ end
10
+
11
+ it "parses nokogiri elements" do
12
+ expect { ReverseAsciidoctor.convert(document.root) }.not_to raise_error
13
+ end
14
+
15
+ it "parses string input" do
16
+ expect { ReverseAsciidoctor.convert(input) }.not_to raise_error
17
+ end
18
+
19
+ it "behaves in a sane way when root element is nil" do
20
+ expect(ReverseAsciidoctor.convert(nil)).to eq ''
21
+ end
22
+
23
+ describe '#config' do
24
+ it 'stores a given configuration option' do
25
+ ReverseAsciidoctor.config.tag_border = true
26
+ expect(ReverseAsciidoctor.config.tag_border).to eq true
27
+ end
28
+
29
+ it 'can be used as a block configurator as well' do
30
+ ReverseAsciidoctor.config do |config|
31
+ expect(config.tag_border).to eq " "
32
+ config.tag_border = true
33
+ end
34
+ expect(ReverseAsciidoctor.config.tag_border).to eq true
35
+ end
36
+ end
37
+ end