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