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,9 @@
1
+ <html>
2
+ <body>
3
+ <p>
4
+ <foo>
5
+ <bar>Foo with bar</bar>
6
+ </foo>
7
+ </p>
8
+ </body>
9
+ </html>
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/anchors.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to include 'http://foobar.com[Foobar]' }
10
+ it { is_expected.to include 'http://foobar.com[Fubar]' }
11
+ it { is_expected.to include 'http://foobar.com[f\*\*\*\*\* up beyond all redemption]' }
12
+ it { is_expected.to include 'http://strong.foobar.com[*Strong foobar*]' }
13
+
14
+ it { is_expected.to include 'There should be space before but not after the anchor ( http://foobar.com[stripped]).' }
15
+
16
+ it { is_expected.to include ' do not ignore link:foo.html[] anchor tags with no link text ' }
17
+ it { is_expected.to include ' link <<content,internal jumplinks>> with anchors ' }
18
+ it { is_expected.to include ' link <<content2>>internal jumplinks without anchors ' }
19
+ it { is_expected.to include ' treat [[content]] as bookmarks ' }
20
+
21
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/basic.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to match /plain text ?\n/ }
10
+ it { is_expected.to match /\n== h1\n/ }
11
+ it { is_expected.to match /\n\[\[A]\]\n== h1 with anchor\n/ }
12
+ it { is_expected.to match /\n=== h2\n/ }
13
+ it { is_expected.to match /\n==== h3\n/ }
14
+ it { is_expected.to match /\n===== h4\n/ }
15
+ it { is_expected.to match /\n====== h5\n/ }
16
+ it { is_expected.to match /\n======= h6\n/ }
17
+
18
+ it { is_expected.to match /_em tag content_/ }
19
+ it { is_expected.to match /before and after empty em tags/ }
20
+ it { is_expected.to match /before and after em tags containing whitespace/ }
21
+ it { is_expected.to match /_double em tags_/ }
22
+ it { is_expected.to match /_double em tags in p tag_/ }
23
+ it { is_expected.to match /a _em with leading and trailing_ whitespace/ }
24
+ it { is_expected.to match /a _em with extra leading and trailing_ whitespace/ }
25
+
26
+ it { is_expected.to match /\*strong tag content\*/ }
27
+ it { is_expected.to match /before and after empty strong tags/ }
28
+ it { is_expected.to match /before and after strong tags containing whitespace/ }
29
+ it { is_expected.to match /\*double strong tags\*/ }
30
+ it { is_expected.to match /\*double strong tags in p tag\*/ }
31
+ it { is_expected.to match /before \*double strong tags containing whitespace\* after/ }
32
+ it { is_expected.to match /a \*strong with leading and trailing\* whitespace/ }
33
+ it { is_expected.to match /a \*strong with extra leading and trailing\* whitespace/ }
34
+
35
+ it { is_expected.to match /H~2~O/ }
36
+ it { is_expected.to match /A\^2\^B/ }
37
+
38
+ it { is_expected.to match /_i tag content_/ }
39
+ it { is_expected.to match /\*b tag content\*/ }
40
+
41
+ it { is_expected.to match /br tags become double space followed by newline \+\n/ }
42
+ #it { should match /br tags XXX \n/ }
43
+
44
+ it { is_expected.to match /before hr \n\* \* \*\n after hr/ }
45
+
46
+ it { is_expected.to match /section 1\n ?\nsection 2/ }
47
+
48
+ it { is_expected.to match /ignore abbr/ }
49
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/code.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to match /inline `code` block/ }
10
+ it { is_expected.to match /\n<code>var this\;\nthis\.is/ }
11
+ it { is_expected.to match /block"\)\nconsole/ }
12
+
13
+ context "with github style code blocks" do
14
+ subject { ReverseAsciidoctor.convert(input) }
15
+ it { is_expected.to match /inline `code` block/ }
16
+ it { is_expected.to match /\n\.\.\.\.\n<code>var this\;\nthis/ }
17
+ it { is_expected.to match /it is"\) ?\n <\/code>\n\.\.\.\./ }
18
+ end
19
+
20
+ context "code with indentation" do
21
+ subject { ReverseAsciidoctor.convert(input) }
22
+ it { is_expected.to match(/^<code>tell application "Foo"\n/) }
23
+ it { is_expected.to match(/^ beep\n/) }
24
+ it { is_expected.to match(/^end tell\n/) }
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/escapables.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ context "multiple asterisks" do
10
+ it { is_expected.to include ' \*\*two asterisks\*\* ' }
11
+ it { is_expected.to include ' \*\*\*three asterisks\*\*\* ' }
12
+ end
13
+
14
+ context "multiple underscores" do
15
+ it { is_expected.to include ' \_\_two underscores\_\_ ' }
16
+ it { is_expected.to include ' \_\_\_three underscores\_\_\_ ' }
17
+ end
18
+
19
+ context "underscores within words in code blocks" do
20
+ it { is_expected.to include "....\n<code>var theoretical_max_infin = 1.0;</code>\n....\n" }
21
+ end
22
+
23
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/from_the_wild.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it "should make sense of strong-crazy markup (as seen in the wild)" do
10
+ expect(subject).to include "*. +\n \\*\\*\\* intentcast* : logo design *+*\n"
11
+ end
12
+
13
+ it "should not over escape * or _" do
14
+ expect(subject).to include 'link:example.com/foo_bar[image::example.com/foo_bar.png[] I\_AM\_HELPFUL]'
15
+ end
16
+
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/html_fragment.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to eq("naked text 1\n\nparagraph text\n\nnaked text 2") }
10
+ end
11
+
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/lists.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to match /\n\* unordered list entry\n/ }
10
+ it { is_expected.to match /\n\* unordered list entry 2\n/ }
11
+ it { is_expected.to match /\n. ordered list entry\n/ }
12
+ it { is_expected.to match /\n. ordered list entry 2\n/ }
13
+ it { is_expected.to match /\n. list entry 1st hierarchy\n/ }
14
+ it { is_expected.to match /\n\*\* nested unsorted list entry\n/ }
15
+ it { is_expected.to match /\n\.\.\. deep nested list entry\n/ }
16
+
17
+ context "list anchors" do
18
+ it { is_expected.to match /\n\[\[1\]\]\n\. arabic1\n/ }
19
+ it { is_expected.to match /\n\[\[A\]\]\n\* upperalpha1\n/ }
20
+ end
21
+
22
+ context "list styles" do
23
+ it { is_expected.to match /\n\[arabic\]\n\. arabic\n/ }
24
+ it { is_expected.to match /\n\[loweralpha\]\n\. loweralpha\n/ }
25
+ it { is_expected.to match /\n\[upperalpha\]\n\. upperalpha\n/ }
26
+ it { is_expected.to match /\n\[lowerroman\]\n\. lowerroman\n/ }
27
+ it { is_expected.to match /\n\[upperroman\]\n\. upperroman\n/ }
28
+ it { is_expected.to match /\n\[type=disc\]\n\* disc\n/ }
29
+ end
30
+
31
+ context "list start, reversed" do
32
+ it { is_expected.to match /\n\[start=3\]\n\. another ordered list entry\n/ }
33
+ it { is_expected.to match /\n\[%reversed\]\n\. a reversed ordered list entry\n/ }
34
+ end
35
+
36
+ context "nested list with no whitespace" do
37
+ it { is_expected.to match /\n\* item a\n/ }
38
+ it { is_expected.to match /\n\* item b\n/ }
39
+ it { is_expected.to match /\n\*\* item bb\n/ }
40
+ it { is_expected.to match /\n\*\* item bc\n/ }
41
+ end
42
+
43
+ context "nested list with lots of whitespace" do
44
+ it { is_expected.to match /\n\* item wa \n/ }
45
+ it { is_expected.to match /\n\* item wb \n/ }
46
+ it { is_expected.to match /\n\*\* item wbb \n/ }
47
+ it { is_expected.to match /\n\*\* item wbc \n/ }
48
+ end
49
+
50
+ context "lists containing links" do
51
+ it { is_expected.to match /\n\* link:Basic_concepts\[1 Basic concepts\]\n/ }
52
+ it { is_expected.to match /\n\* link:History_of_the_idea\[2 History of the idea\]\n/ }
53
+ it { is_expected.to match /\n\* link:Intelligence_explosion\[3 Intelligence explosion\]\n/ }
54
+ end
55
+
56
+ context "lists containing embedded <p> tags" do
57
+ xit { is_expected.to match /\n\* I want to have a party at my house!\n/ }
58
+ end
59
+
60
+ context "list item containing multiple <p> tags" do
61
+ xit { is_expected.to match /\n\* li 1, p 1\n\n\* li 1, p 2\n/ }
62
+ end
63
+
64
+ context 'it produces correct numbering' do
65
+ it { is_expected.to include "\. one" }
66
+ it { is_expected.to include "\.\. one one" }
67
+ it { is_expected.to include "\.\. one two" }
68
+ it { is_expected.to include "\. two" }
69
+ it { is_expected.to include "\.\. two one" }
70
+ it { is_expected.to include "\.\.\. two one one" }
71
+ it { is_expected.to include "\.\.\. two one two" }
72
+ it { is_expected.to include "\.\. two two" }
73
+ it { is_expected.to include "\. three" }
74
+ end
75
+
76
+ context "properly embeds a nested list between adjacent list items" do
77
+ it { is_expected.to match /\n\* alpha\n/ }
78
+ it { is_expected.to match /\n\* bravo/ }
79
+ it { is_expected.to match /\n\*\* bravo alpha\n/ }
80
+ it { is_expected.to match /\n\*\* bravo bravo/ }
81
+ it { is_expected.to match /\n\*\*\* bravo bravo alpha/ }
82
+ it { is_expected.to match /\n\* charlie\n/ }
83
+ it { is_expected.to match /\n\* delta\n/ }
84
+ end
85
+
86
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/paragraphs.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.not_to start_with "\n\n" }
10
+ it { is_expected.to start_with "First content\n\nSecond content\n\n" }
11
+ it { is_expected.to include "\n\n_Complex_\n\n\.\.\.\.\n\n <code>Content</code>\n" }
12
+ it { is_expected.to include "*Trailing whitespace:*" }
13
+ it { is_expected.to include "*Trailing non-breaking space:&nbsp;*" }
14
+ it { is_expected.to include "*_Combination:&nbsp;_*" }
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/quotation.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to match /\n <code>Block of code<\/code>$/ }
10
+ it { is_expected.to include "\n____\nFirst quoted paragraph\n\nSecond quoted paragraph\n____\n" }
11
+
12
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/tables.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ subject { ReverseAsciidoctor.convert(input) }
8
+
9
+ it { is_expected.to match /\[\[A\]\]\n\|===\n\| \[\[C\]\]header 1 \| header 2 \| header 3\n\n/ }
10
+ it { is_expected.to match /\nh\| \[\[D\]\]data 1-1 \| data 2-1 \| data 3-1\n/ }
11
+ it { is_expected.to match /\nh\| data 1-2 \| data 2-2 \| data 3-2\n/ }
12
+
13
+ it { is_expected.to match /\n\| _header oblique_ \| \*header bold\* \| `header code`\n\n/ }
14
+ it { is_expected.to match /\n\| _data oblique_ \| \*data bold\* \| `data code`\n/ }
15
+
16
+ it { is_expected.to match /\n\.2\+\| rowspan 2\n/ }
17
+ it { is_expected.to match /\n2\+| colspan 2\n/ }
18
+ it { is_expected.to match /\n2\.2\+| colrowspan 2\n/ }
19
+
20
+ it { is_expected.to match /<\| horizontal left / }
21
+ it { is_expected.to match /\^\| horizontal center / }
22
+ it { is_expected.to match />\| horizontal right\n/ }
23
+ it { is_expected.to match /\^\.\^\| center middle\n/ }
24
+
25
+ it { is_expected.to match /\n\.Table _caption_\n\|===\n/ }
26
+ it { is_expected.to match /\n\[width=75%\]\n\|===\n\| 75% width table\n/ }
27
+ it { is_expected.to match /\n\[frame=topbot,rules=cols\]\n\|===\n\| topbot\n/ }
28
+
29
+ it { is_expected.to match /\na|\nHello\n\nThis cell has multiple paragraphs\n\n/ }
30
+ it { is_expected.to match /\n\| This cell has a single paragraph\n/ }
31
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor do
4
+
5
+ let(:input) { File.read('spec/assets/unknown_tags.html') }
6
+ let(:document) { Nokogiri::HTML(input) }
7
+ let(:result) { ReverseAsciidoctor.convert(input) }
8
+
9
+ context 'with unknown_tags = :pass_through' do
10
+ before { ReverseAsciidoctor.config.unknown_tags = :pass_through }
11
+
12
+ it { expect(result).to include "<bar>Foo with bar</bar>" }
13
+ end
14
+
15
+ context 'with unknown_tags = :raise' do
16
+ before { ReverseAsciidoctor.config.unknown_tags = :raise }
17
+
18
+ it { expect { result }.to raise_error(ReverseAsciidoctor::UnknownTagError) }
19
+ end
20
+
21
+ context 'with unknown_tags = :drop' do
22
+ before { ReverseAsciidoctor.config.unknown_tags = :drop }
23
+
24
+ it { expect(result).to eq '' }
25
+ end
26
+
27
+ context 'with unknown_tags = :bypass' do
28
+ before { ReverseAsciidoctor.config.unknown_tags = :bypass }
29
+
30
+ it { expect(result).to eq "Foo with bar\n\n" }
31
+ end
32
+
33
+ context 'with unknown_tags = :something_wrong' do
34
+ before { ReverseAsciidoctor.config.unknown_tags = :something_wrong }
35
+
36
+ it { expect { result }.to raise_error(ReverseAsciidoctor::InvalidConfigurationError) }
37
+ end
38
+ end
39
+
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReverseAsciidoctor::Cleaner do
4
+ let(:cleaner) { ReverseAsciidoctor::Cleaner.new }
5
+
6
+ describe '#remove_newlines' do
7
+ it 'removes more than 2 subsequent newlines' do
8
+ result = cleaner.remove_newlines("foo\n\n\nbar")
9
+ expect(result).to eq "foo\n\nbar"
10
+ end
11
+
12
+ it 'skips single and double newlines' do
13
+ result = cleaner.remove_newlines("foo\nbar\n\nbaz")
14
+ expect(result).to eq "foo\nbar\n\nbaz"
15
+ end
16
+ end
17
+
18
+ describe '#remove_inner_whitespaces' do
19
+ it 'removes duplicate whitespaces from the string' do
20
+ result = cleaner.remove_inner_whitespaces('foo bar')
21
+ expect(result).to eq "foo bar"
22
+ end
23
+
24
+ it 'performs changes for multiple lines' do
25
+ result = cleaner.remove_inner_whitespaces("foo bar\nbar foo")
26
+ expect(result).to eq "foo bar\nbar foo"
27
+ end
28
+
29
+ it 'keeps leading whitespaces' do
30
+ result = cleaner.remove_inner_whitespaces(" foo bar\n bar foo")
31
+ expect(result).to eq " foo bar\n bar foo"
32
+ end
33
+
34
+ it 'keeps trailing whitespaces' do
35
+ result = cleaner.remove_inner_whitespaces("foo \n")
36
+ expect(result).to eq "foo \n"
37
+ end
38
+
39
+ it 'keeps trailing newlines' do
40
+ result = cleaner.remove_inner_whitespaces("foo\n")
41
+ expect(result).to eq "foo\n"
42
+ end
43
+
44
+ it 'removes tabs as well' do
45
+ result = cleaner.remove_inner_whitespaces("foo\t \tbar")
46
+ expect(result).to eq "foo bar"
47
+ end
48
+
49
+ it 'keeps lines that only contain whitespace' do
50
+ result = cleaner.remove_inner_whitespaces("foo \nbar \n \n \nfoo")
51
+ expect(result).to eq "foo \nbar \n \n \nfoo"
52
+ end
53
+ end
54
+
55
+ describe '#clean_punctuation_characters' do
56
+ it 'removes whitespace between tag end and punctuation characters' do
57
+ input = "**fat** . ~~strike~~ ? __italic__ ! "
58
+ result = cleaner.clean_punctuation_characters(input)
59
+ expect(result).to eq "**fat**. ~~strike~~? __italic__! "
60
+ end
61
+ end
62
+
63
+ describe '#clean_tag_borders' do
64
+ context 'with default_border is set to space' do
65
+ before { ReverseAsciidoctor.config.tag_border = ' ' }
66
+
67
+ it 'removes not needed whitespaces from strong tags' do
68
+ input = "foo ** foobar ** bar"
69
+ result = cleaner.clean_tag_borders(input)
70
+ expect(result).to eq "foo **foobar** bar"
71
+ end
72
+
73
+ it 'remotes leading or trailing whitespaces independently' do
74
+ input = "1 **fat ** 2 ** fat** 3"
75
+ result = cleaner.clean_tag_borders(input)
76
+ expect(result).to eq "1 **fat** 2 **fat** 3"
77
+ end
78
+
79
+ it 'adds whitespaces if there are none' do
80
+ input = "1**fat**2"
81
+ result = cleaner.clean_tag_borders(input)
82
+ expect(result).to eq "1 **fat** 2"
83
+ end
84
+
85
+ it "doesn't add whitespaces to underscore'ed elements if they are part of links" do
86
+ input = "![im__age](sou__rce)"
87
+ result = cleaner.clean_tag_borders(input)
88
+ expect(result).to eq "![im__age](sou__rce)"
89
+ end
90
+
91
+ it "still cleans up whitespaces that aren't inside a link" do
92
+ input = "now __italic __with following [under__scored](link)"
93
+ result = cleaner.clean_tag_borders(input)
94
+ expect(result).to eq "now __italic__ with following [under__scored](link)"
95
+ end
96
+
97
+ it 'cleans italic stuff as well' do
98
+ input = "1 __italic __ 2 __ italic__ 3__italic __4"
99
+ result = cleaner.clean_tag_borders(input)
100
+ expect(result).to eq "1 __italic__ 2 __italic__ 3 __italic__ 4"
101
+ end
102
+
103
+ it 'cleans strikethrough stuff as well' do
104
+ input = "1 ~~italic ~~ 2 ~~ italic~~ 3~~italic ~~4"
105
+ result = cleaner.clean_tag_borders(input)
106
+ expect(result).to eq "1 ~~italic~~ 2 ~~italic~~ 3 ~~italic~~ 4"
107
+ end
108
+ end
109
+
110
+ context 'with default_border set to no space' do
111
+ before { ReverseAsciidoctor.config.tag_border = '' }
112
+
113
+ it 'removes not needed whitespaces from strong tags' do
114
+ input = "foo ** foobar ** bar"
115
+ result = cleaner.clean_tag_borders(input)
116
+ expect(result).to eq "foo **foobar** bar"
117
+ end
118
+
119
+ it 'remotes leading or trailing whitespaces independently' do
120
+ input = "1 **fat ** 2 ** fat** 3"
121
+ result = cleaner.clean_tag_borders(input)
122
+ expect(result).to eq "1 **fat** 2 **fat** 3"
123
+ end
124
+
125
+ it 'adds whitespaces if there are none' do
126
+ input = "1**fat**2"
127
+ result = cleaner.clean_tag_borders(input)
128
+ expect(result).to eq "1**fat**2"
129
+ end
130
+
131
+ it "doesn't add whitespaces to underscore'ed elements if they are part of links" do
132
+ input = "![im__age](sou__rce)"
133
+ result = cleaner.clean_tag_borders(input)
134
+ expect(result).to eq "![im__age](sou__rce)"
135
+ end
136
+
137
+ it "still cleans up whitespaces that aren't inside a link" do
138
+ input = "now __italic __with following [under__scored](link)"
139
+ result = cleaner.clean_tag_borders(input)
140
+ expect(result).to eq "now __italic__with following [under__scored](link)"
141
+ end
142
+
143
+ it 'cleans italic stuff as well' do
144
+ input = "1 __italic __ 2 __ italic__ 3__italic __4"
145
+ result = cleaner.clean_tag_borders(input)
146
+ expect(result).to eq "1 __italic__ 2 __italic__ 3__italic__4"
147
+ end
148
+
149
+ it 'cleans strikethrough stuff as well' do
150
+ input = "1 ~~italic ~~ 2 ~~ italic~~ 3~~italic ~~4"
151
+ result = cleaner.clean_tag_borders(input)
152
+ expect(result).to eq "1 ~~italic~~ 2 ~~italic~~ 3~~italic~~4"
153
+ end
154
+ end
155
+ end
156
+
157
+ end