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,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