asciidoctor 1.5.8 → 2.0.0.rc.1

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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +162 -17
  3. data/LICENSE +1 -1
  4. data/README-de.adoc +12 -13
  5. data/README-fr.adoc +11 -12
  6. data/README-jp.adoc +11 -12
  7. data/README-zh_CN.adoc +12 -13
  8. data/README.adoc +6 -7
  9. data/asciidoctor.gemspec +19 -24
  10. data/bin/asciidoctor +5 -4
  11. data/data/reference/syntax.adoc +283 -0
  12. data/data/stylesheets/asciidoctor-default.css +56 -52
  13. data/data/stylesheets/coderay-asciidoctor.css +7 -9
  14. data/lib/asciidoctor.rb +171 -232
  15. data/lib/asciidoctor/abstract_block.rb +96 -105
  16. data/lib/asciidoctor/abstract_node.rb +118 -139
  17. data/lib/asciidoctor/attribute_list.rb +10 -14
  18. data/lib/asciidoctor/block.rb +20 -19
  19. data/lib/asciidoctor/callouts.rb +4 -2
  20. data/lib/asciidoctor/cli.rb +3 -2
  21. data/lib/asciidoctor/cli/invoker.rb +14 -21
  22. data/lib/asciidoctor/cli/options.rb +64 -54
  23. data/lib/asciidoctor/converter.rb +357 -185
  24. data/lib/asciidoctor/converter/composite.rb +40 -48
  25. data/lib/asciidoctor/converter/docbook5.rb +604 -640
  26. data/lib/asciidoctor/converter/html5.rb +949 -963
  27. data/lib/asciidoctor/converter/manpage.rb +569 -548
  28. data/lib/asciidoctor/converter/template.rb +231 -272
  29. data/lib/asciidoctor/core_ext.rb +5 -18
  30. data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
  31. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  32. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  33. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  34. data/lib/asciidoctor/document.rb +399 -377
  35. data/lib/asciidoctor/extensions.rb +72 -140
  36. data/lib/asciidoctor/helpers.rb +122 -83
  37. data/lib/asciidoctor/inline.rb +5 -1
  38. data/lib/asciidoctor/list.rb +13 -11
  39. data/lib/asciidoctor/logging.rb +17 -16
  40. data/lib/asciidoctor/parser.rb +390 -423
  41. data/lib/asciidoctor/path_resolver.rb +10 -5
  42. data/lib/asciidoctor/reader.rb +286 -263
  43. data/lib/asciidoctor/rouge_ext.rb +39 -0
  44. data/lib/asciidoctor/section.rb +9 -8
  45. data/lib/asciidoctor/stylesheets.rb +19 -37
  46. data/lib/asciidoctor/substitutors.rb +364 -509
  47. data/lib/asciidoctor/syntax_highlighter.rb +238 -0
  48. data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
  49. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
  50. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  51. data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
  52. data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
  53. data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
  54. data/lib/asciidoctor/table.rb +73 -66
  55. data/lib/asciidoctor/timings.rb +4 -2
  56. data/lib/asciidoctor/version.rb +2 -1
  57. data/lib/asciidoctor/writer.rb +30 -0
  58. data/man/asciidoctor.1 +19 -15
  59. data/man/asciidoctor.adoc +14 -12
  60. metadata +69 -216
  61. data/CONTRIBUTING.adoc +0 -185
  62. data/Gemfile +0 -60
  63. data/Rakefile +0 -129
  64. data/bin/asciidoctor-safe +0 -15
  65. data/features/open_block.feature +0 -92
  66. data/features/pass_block.feature +0 -66
  67. data/features/step_definitions.rb +0 -49
  68. data/features/text_formatting.feature +0 -57
  69. data/features/xref.feature +0 -1039
  70. data/lib/asciidoctor/converter/base.rb +0 -59
  71. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  72. data/lib/asciidoctor/converter/factory.rb +0 -226
  73. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  74. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  75. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  76. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  77. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  78. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  79. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  80. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  81. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  82. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  83. data/test/api_test.rb +0 -1240
  84. data/test/attribute_list_test.rb +0 -242
  85. data/test/attributes_test.rb +0 -1623
  86. data/test/blocks_test.rb +0 -3870
  87. data/test/converter_test.rb +0 -470
  88. data/test/document_test.rb +0 -1853
  89. data/test/extensions_test.rb +0 -1560
  90. data/test/fixtures/asciidoc_index.txt +0 -521
  91. data/test/fixtures/basic-docinfo-footer.html +0 -6
  92. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  93. data/test/fixtures/basic-docinfo.html +0 -1
  94. data/test/fixtures/basic-docinfo.xml +0 -4
  95. data/test/fixtures/basic.asciidoc +0 -5
  96. data/test/fixtures/chapter-a.adoc +0 -3
  97. data/test/fixtures/child-include.adoc +0 -5
  98. data/test/fixtures/circle.svg +0 -9
  99. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  100. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  101. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  102. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  103. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  104. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  105. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  106. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  107. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  108. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  109. data/test/fixtures/docinfo-footer.html +0 -1
  110. data/test/fixtures/docinfo-footer.xml +0 -9
  111. data/test/fixtures/docinfo.html +0 -1
  112. data/test/fixtures/docinfo.xml +0 -3
  113. data/test/fixtures/doctime-localtime.adoc +0 -2
  114. data/test/fixtures/dot.gif +0 -0
  115. data/test/fixtures/encoding.asciidoc +0 -13
  116. data/test/fixtures/file-with-missing-include.adoc +0 -1
  117. data/test/fixtures/grandchild-include.adoc +0 -3
  118. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  119. data/test/fixtures/include-file.asciidoc +0 -24
  120. data/test/fixtures/include-file.jsx +0 -8
  121. data/test/fixtures/include-file.ml +0 -3
  122. data/test/fixtures/include-file.xml +0 -5
  123. data/test/fixtures/lists.adoc +0 -96
  124. data/test/fixtures/master.adoc +0 -5
  125. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  126. data/test/fixtures/other-chapters.adoc +0 -11
  127. data/test/fixtures/outer-include.adoc +0 -5
  128. data/test/fixtures/parent-include-restricted.adoc +0 -5
  129. data/test/fixtures/parent-include.adoc +0 -5
  130. data/test/fixtures/sample.asciidoc +0 -30
  131. data/test/fixtures/section-a.adoc +0 -4
  132. data/test/fixtures/stylesheets/custom.css +0 -3
  133. data/test/fixtures/subdir/index.adoc +0 -3
  134. data/test/fixtures/subdir/inner-include.adoc +0 -3
  135. data/test/fixtures/subdir/middle-include.adoc +0 -5
  136. data/test/fixtures/subs-docinfo.html +0 -2
  137. data/test/fixtures/subs.adoc +0 -6
  138. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  139. data/test/fixtures/tagged-class.rb +0 -23
  140. data/test/fixtures/tip.gif +0 -0
  141. data/test/fixtures/unclosed-tag.adoc +0 -3
  142. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  143. data/test/invoker_test.rb +0 -745
  144. data/test/links_test.rb +0 -855
  145. data/test/lists_test.rb +0 -5151
  146. data/test/logger_test.rb +0 -211
  147. data/test/manpage_test.rb +0 -660
  148. data/test/options_test.rb +0 -262
  149. data/test/paragraphs_test.rb +0 -562
  150. data/test/parser_test.rb +0 -742
  151. data/test/paths_test.rb +0 -395
  152. data/test/preamble_test.rb +0 -173
  153. data/test/reader_test.rb +0 -2161
  154. data/test/sections_test.rb +0 -3575
  155. data/test/substitutions_test.rb +0 -2066
  156. data/test/tables_test.rb +0 -2036
  157. data/test/test_helper.rb +0 -447
  158. data/test/text_test.rb +0 -309
@@ -1,2066 +0,0 @@
1
- # encoding: UTF-8
2
- unless defined? ASCIIDOCTOR_PROJECT_DIR
3
- $: << File.dirname(__FILE__); $:.uniq!
4
- require 'test_helper'
5
- end
6
-
7
- # TODO
8
- # - test negatives
9
- # - test role on every quote type
10
- context 'Substitutions' do
11
- BACKSLASH = %(\x5c)
12
- context 'Dispatcher' do
13
- test 'apply normal substitutions' do
14
- para = block_from_string("[blue]_http://asciidoc.org[AsciiDoc]_ & [red]*Ruby*\n&#167; Making +++<u>documentation</u>+++ together +\nsince (C) {inception_year}.")
15
- para.document.attributes['inception_year'] = '2012'
16
- result = para.apply_subs(para.source)
17
- assert_equal %{<em class="blue"><a href="http://asciidoc.org">AsciiDoc</a></em> &amp; <strong class="red">Ruby</strong>\n&#167; Making <u>documentation</u> together<br>\nsince &#169; 2012.}, result
18
- end
19
-
20
- test 'apply_subs should not modify string directly' do
21
- input = '<html> -- the root of all web'
22
- para = block_from_string input
23
- para_source = para.source
24
- result = para.apply_subs para_source
25
- assert_equal '&lt;html&gt;&#8201;&#8212;&#8201;the root of all web', result
26
- assert_equal input, para_source
27
- end
28
-
29
- test 'should not drop trailing blank lines when performing substitutions' do
30
- para = block_from_string %([%hardbreaks]\nthis\nis\n-> {program})
31
- para.lines << ''
32
- para.lines << ''
33
- para.document.attributes['program'] = 'Asciidoctor'
34
- result = para.apply_subs(para.lines)
35
- assert_equal ['this<br>', 'is<br>', '&#8594; Asciidoctor<br>', '<br>', ''], result
36
- result = para.apply_subs(para.lines * "\n")
37
- assert_equal %(this<br>\nis<br>\n&#8594; Asciidoctor<br>\n<br>\n), result
38
- end
39
-
40
- test 'should expand subs passe to expand_subs' do
41
- para = block_from_string %({program}\n*bold*\n2 > 1)
42
- para.document.attributes['program'] = 'Asciidoctor'
43
- assert_equal [:specialcharacters], (para.expand_subs [:specialchars])
44
- refute para.expand_subs([:none])
45
- assert_equal [:specialcharacters, :quotes, :attributes, :replacements, :macros, :post_replacements], (para.expand_subs [:normal])
46
- end
47
-
48
- test 'apply_subs should allow the subs argument to be nil' do
49
- block = block_from_string %([pass]\n*raw*)
50
- result = block.apply_subs block.source, nil
51
- assert_equal '*raw*', result
52
- end
53
- end
54
-
55
- context 'Quotes' do
56
- test 'single-line double-quoted string' do
57
- para = block_from_string(%q{``a few quoted words''}, :attributes => {'compat-mode' => ''})
58
- assert_equal '&#8220;a few quoted words&#8221;', para.sub_quotes(para.source)
59
-
60
- para = block_from_string(%q{"`a few quoted words`"})
61
- assert_equal '&#8220;a few quoted words&#8221;', para.sub_quotes(para.source)
62
-
63
- para = block_from_string(%q{"`a few quoted words`"}, :backend => 'docbook')
64
- assert_equal '<quote>a few quoted words</quote>', para.sub_quotes(para.source)
65
- end
66
-
67
- test 'escaped single-line double-quoted string' do
68
- para = block_from_string %(#{BACKSLASH}``a few quoted words''), :attributes => {'compat-mode' => ''}
69
- assert_equal %q(&#8216;`a few quoted words&#8217;'), para.sub_quotes(para.source)
70
-
71
- para = block_from_string %(#{BACKSLASH * 2}``a few quoted words''), :attributes => {'compat-mode' => ''}
72
- assert_equal %q(``a few quoted words''), para.sub_quotes(para.source)
73
-
74
- para = block_from_string(%(#{BACKSLASH}"`a few quoted words`"))
75
- assert_equal %q("`a few quoted words`"), para.sub_quotes(para.source)
76
-
77
- para = block_from_string(%(#{BACKSLASH * 2}"`a few quoted words`"))
78
- assert_equal %(#{BACKSLASH}"`a few quoted words`"), para.sub_quotes(para.source)
79
- end
80
-
81
- test 'multi-line double-quoted string' do
82
- para = block_from_string(%Q{``a few\nquoted words''}, :attributes => {'compat-mode' => ''})
83
- assert_equal "&#8220;a few\nquoted words&#8221;", para.sub_quotes(para.source)
84
-
85
- para = block_from_string(%Q{"`a few\nquoted words`"})
86
- assert_equal "&#8220;a few\nquoted words&#8221;", para.sub_quotes(para.source)
87
- end
88
-
89
- test 'double-quoted string with inline single quote' do
90
- para = block_from_string(%q{``Here's Johnny!''}, :attributes => {'compat-mode' => ''})
91
- assert_equal %q{&#8220;Here's Johnny!&#8221;}, para.sub_quotes(para.source)
92
-
93
- para = block_from_string(%q{"`Here's Johnny!`"})
94
- assert_equal %q{&#8220;Here's Johnny!&#8221;}, para.sub_quotes(para.source)
95
- end
96
-
97
- test 'double-quoted string with inline backquote' do
98
- para = block_from_string(%q{``Here`s Johnny!''}, :attributes => {'compat-mode' => ''})
99
- assert_equal %q{&#8220;Here`s Johnny!&#8221;}, para.sub_quotes(para.source)
100
-
101
- para = block_from_string(%q{"`Here`s Johnny!`"})
102
- assert_equal %q{&#8220;Here`s Johnny!&#8221;}, para.sub_quotes(para.source)
103
- end
104
-
105
- test 'double-quoted string around monospaced text' do
106
- para = block_from_string(%q("``E=mc^2^` is the solution!`"))
107
- assert_equal %q(&#8220;`E=mc<sup>2</sup>` is the solution!&#8221;), para.apply_subs(para.source);
108
-
109
- para = block_from_string(%q("```E=mc^2^`` is the solution!`"))
110
- assert_equal %q(&#8220;<code>E=mc<sup>2</sup></code> is the solution!&#8221;), para.apply_subs(para.source);
111
- end
112
-
113
- test 'single-line single-quoted string' do
114
- para = block_from_string(%q{`a few quoted words'}, :attributes => {'compat-mode' => ''})
115
- assert_equal '&#8216;a few quoted words&#8217;', para.sub_quotes(para.source)
116
-
117
- para = block_from_string(%q{'`a few quoted words`'})
118
- assert_equal '&#8216;a few quoted words&#8217;', para.sub_quotes(para.source)
119
-
120
- para = block_from_string(%q{'`a few quoted words`'}, :backend => 'docbook')
121
- assert_equal '<quote>a few quoted words</quote>', para.sub_quotes(para.source)
122
- end
123
-
124
- test 'escaped single-line single-quoted string' do
125
- para = block_from_string(%(#{BACKSLASH}`a few quoted words'), :attributes => {'compat-mode' => ''})
126
- assert_equal %(`a few quoted words'), para.sub_quotes(para.source)
127
-
128
- para = block_from_string(%(#{BACKSLASH}'`a few quoted words`'))
129
- assert_equal %('`a few quoted words`'), para.sub_quotes(para.source)
130
- end
131
-
132
- test 'multi-line single-quoted string' do
133
- para = block_from_string(%Q{`a few\nquoted words'}, :attributes => {'compat-mode' => ''})
134
- assert_equal "&#8216;a few\nquoted words&#8217;", para.sub_quotes(para.source)
135
-
136
- para = block_from_string(%Q{'`a few\nquoted words`'})
137
- assert_equal "&#8216;a few\nquoted words&#8217;", para.sub_quotes(para.source)
138
- end
139
-
140
- test 'single-quoted string with inline single quote' do
141
- para = block_from_string(%q{`That isn't what I did.'}, :attributes => {'compat-mode' => ''})
142
- assert_equal %q{&#8216;That isn't what I did.&#8217;}, para.sub_quotes(para.source)
143
-
144
- para = block_from_string(%q{'`That isn't what I did.`'})
145
- assert_equal %q{&#8216;That isn't what I did.&#8217;}, para.sub_quotes(para.source)
146
- end
147
-
148
- test 'single-quoted string with inline backquote' do
149
- para = block_from_string(%q{`Here`s Johnny!'}, :attributes => {'compat-mode' => ''})
150
- assert_equal %q{&#8216;Here`s Johnny!&#8217;}, para.sub_quotes(para.source)
151
-
152
- para = block_from_string(%q{'`Here`s Johnny!`'})
153
- assert_equal %q{&#8216;Here`s Johnny!&#8217;}, para.sub_quotes(para.source)
154
- end
155
-
156
- test 'single-line constrained marked string' do
157
- #para = block_from_string(%q{#a few words#}, :attributes => {'compat-mode' => ''})
158
- #assert_equal 'a few words', para.sub_quotes(para.source)
159
-
160
- para = block_from_string(%q{#a few words#})
161
- assert_equal '<mark>a few words</mark>', para.sub_quotes(para.source)
162
- end
163
-
164
- test 'escaped single-line constrained marked string' do
165
- para = block_from_string(%(#{BACKSLASH}#a few words#))
166
- assert_equal '#a few words#', para.sub_quotes(para.source)
167
- end
168
-
169
- test 'multi-line constrained marked string' do
170
- #para = block_from_string(%Q{#a few\nwords#}, :attributes => {'compat-mode' => ''})
171
- #assert_equal "a few\nwords", para.sub_quotes(para.source)
172
-
173
- para = block_from_string(%Q{#a few\nwords#})
174
- assert_equal "<mark>a few\nwords</mark>", para.sub_quotes(para.source)
175
- end
176
-
177
- test 'constrained marked string should not match entity references' do
178
- para = block_from_string('111 #mark a# 222 "`quote a`" 333 #mark b# 444')
179
- assert_equal %(111 <mark>mark a</mark> 222 &#8220;quote a&#8221; 333 <mark>mark b</mark> 444), para.sub_quotes(para.source)
180
- end
181
-
182
- test 'single-line unconstrained marked string' do
183
- #para = block_from_string(%q{##--anything goes ##}, :attributes => {'compat-mode' => ''})
184
- #assert_equal '--anything goes ', para.sub_quotes(para.source)
185
-
186
- para = block_from_string(%q{##--anything goes ##})
187
- assert_equal '<mark>--anything goes </mark>', para.sub_quotes(para.source)
188
- end
189
-
190
- test 'escaped single-line unconstrained marked string' do
191
- para = block_from_string(%(#{BACKSLASH}#{BACKSLASH}##--anything goes ##))
192
- assert_equal '##--anything goes ##', para.sub_quotes(para.source)
193
- end
194
-
195
- test 'multi-line unconstrained marked string' do
196
- #para = block_from_string(%Q{##--anything\ngoes ##}, :attributes => {'compat-mode' => ''})
197
- #assert_equal "--anything\ngoes ", para.sub_quotes(para.source)
198
-
199
- para = block_from_string(%Q{##--anything\ngoes ##})
200
- assert_equal "<mark>--anything\ngoes </mark>", para.sub_quotes(para.source)
201
- end
202
-
203
- test 'single-line constrained marked string with role' do
204
- para = block_from_string(%q{[statement]#a few words#})
205
- assert_equal '<span class="statement">a few words</span>', para.sub_quotes(para.source)
206
- end
207
-
208
- test 'single-line constrained strong string' do
209
- para = block_from_string(%q{*a few strong words*})
210
- assert_equal '<strong>a few strong words</strong>', para.sub_quotes(para.source)
211
- end
212
-
213
- test 'escaped single-line constrained strong string' do
214
- para = block_from_string(%(#{BACKSLASH}*a few strong words*))
215
- assert_equal '*a few strong words*', para.sub_quotes(para.source)
216
- end
217
-
218
- test 'multi-line constrained strong string' do
219
- para = block_from_string(%Q{*a few\nstrong words*})
220
- assert_equal "<strong>a few\nstrong words</strong>", para.sub_quotes(para.source)
221
- end
222
-
223
- test 'constrained strong string containing an asterisk' do
224
- para = block_from_string(%q{*bl*ck*-eye})
225
- assert_equal '<strong>bl*ck</strong>-eye', para.sub_quotes(para.source)
226
- end
227
-
228
- test 'constrained strong string containing an asterisk and multibyte word chars' do
229
- para = block_from_string(%q{*黑*眼圈*})
230
- assert_equal '<strong>黑*眼圈</strong>', para.sub_quotes(para.source)
231
- end if ::RUBY_MIN_VERSION_1_9
232
-
233
- test 'single-line constrained quote variation emphasized string' do
234
- para = block_from_string(%q{_a few emphasized words_})
235
- assert_equal '<em>a few emphasized words</em>', para.sub_quotes(para.source)
236
- end
237
-
238
- test 'escaped single-line constrained quote variation emphasized string' do
239
- para = block_from_string(%(#{BACKSLASH}_a few emphasized words_))
240
- assert_equal %q(_a few emphasized words_), para.sub_quotes(para.source)
241
- end
242
-
243
- test 'escaped single quoted string' do
244
- para = block_from_string(%(#{BACKSLASH}'a few emphasized words'))
245
- # NOTE the \' is replaced with ' by the :replacements substitution, later in the substitution pipeline
246
- assert_equal %(#{BACKSLASH}'a few emphasized words'), para.sub_quotes(para.source)
247
- end
248
-
249
- test 'multi-line constrained emphasized quote variation string' do
250
- para = block_from_string(%Q{_a few\nemphasized words_})
251
- assert_equal "<em>a few\nemphasized words</em>", para.sub_quotes(para.source)
252
- end
253
-
254
- test 'single-quoted string containing an emphasized phrase' do
255
- para = block_from_string(%q{`I told him, 'Just go for it!''}, :attributes => {'compat-mode' => ''})
256
- assert_equal '&#8216;I told him, <em>Just go for it!</em>&#8217;', para.sub_quotes(para.source)
257
-
258
- para = block_from_string(%q{'`I told him, 'Just go for it!'`'})
259
- assert_equal %q(&#8216;I told him, 'Just go for it!'&#8217;), para.sub_quotes(para.source)
260
- end
261
-
262
- test 'escaped single-quotes inside emphasized words are restored' do
263
- para = block_from_string(%('Here#{BACKSLASH}'s Johnny!'), :attributes => {'compat-mode' => ''})
264
- assert_equal %q(<em>Here's Johnny!</em>), para.apply_subs(para.source)
265
-
266
- para = block_from_string(%('Here#{BACKSLASH}'s Johnny!'))
267
- assert_equal %q('Here's Johnny!'), para.apply_subs(para.source)
268
- end
269
-
270
- test 'single-line constrained emphasized underline variation string' do
271
- para = block_from_string(%q{_a few emphasized words_})
272
- assert_equal '<em>a few emphasized words</em>', para.sub_quotes(para.source)
273
- end
274
-
275
- test 'escaped single-line constrained emphasized underline variation string' do
276
- para = block_from_string(%(#{BACKSLASH}_a few emphasized words_))
277
- assert_equal '_a few emphasized words_', para.sub_quotes(para.source)
278
- end
279
-
280
- test 'multi-line constrained emphasized underline variation string' do
281
- para = block_from_string(%Q{_a few\nemphasized words_})
282
- assert_equal "<em>a few\nemphasized words</em>", para.sub_quotes(para.source)
283
- end
284
-
285
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
286
- test 'single-line constrained monospaced string' do
287
- para = block_from_string(%(`a few <{monospaced}> words`), :attributes => {'monospaced' => 'monospaced', 'compat-mode' => ''})
288
- assert_equal '<code>a few &lt;{monospaced}&gt; words</code>', para.apply_subs(para.source)
289
-
290
- para = block_from_string(%(`a few <{monospaced}> words`), :attributes => {'monospaced' => 'monospaced'})
291
- assert_equal '<code>a few &lt;monospaced&gt; words</code>', para.apply_subs(para.source)
292
- end
293
-
294
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
295
- test 'single-line constrained monospaced string with role' do
296
- para = block_from_string(%([input]`a few <{monospaced}> words`), :attributes => {'monospaced' => 'monospaced', 'compat-mode' => ''})
297
- assert_equal '<code class="input">a few &lt;{monospaced}&gt; words</code>', para.apply_subs(para.source)
298
-
299
- para = block_from_string(%([input]`a few <{monospaced}> words`), :attributes => {'monospaced' => 'monospaced'})
300
- assert_equal '<code class="input">a few &lt;monospaced&gt; words</code>', para.apply_subs(para.source)
301
- end
302
-
303
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
304
- test 'escaped single-line constrained monospaced string' do
305
- para = block_from_string(%(#{BACKSLASH}`a few <monospaced> words`), :attributes => {'compat-mode' => ''})
306
- assert_equal '`a few &lt;monospaced&gt; words`', para.apply_subs(para.source)
307
-
308
- para = block_from_string(%(#{BACKSLASH}`a few <monospaced> words`))
309
- assert_equal '`a few &lt;monospaced&gt; words`', para.apply_subs(para.source)
310
- end
311
-
312
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
313
- test 'escaped single-line constrained monospaced string with role' do
314
- para = block_from_string(%([input]#{BACKSLASH}`a few <monospaced> words`), :attributes => {'compat-mode' => ''})
315
- assert_equal '[input]`a few &lt;monospaced&gt; words`', para.apply_subs(para.source)
316
-
317
- para = block_from_string(%([input]#{BACKSLASH}`a few <monospaced> words`))
318
- assert_equal '[input]`a few &lt;monospaced&gt; words`', para.apply_subs(para.source)
319
- end
320
-
321
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
322
- test 'escaped role on single-line constrained monospaced string' do
323
- para = block_from_string(%(#{BACKSLASH}[input]`a few <monospaced> words`), :attributes => {'compat-mode' => ''})
324
- assert_equal '[input]<code>a few &lt;monospaced&gt; words</code>', para.apply_subs(para.source)
325
-
326
- para = block_from_string(%(#{BACKSLASH}[input]`a few <monospaced> words`))
327
- assert_equal '[input]<code>a few &lt;monospaced&gt; words</code>', para.apply_subs(para.source)
328
- end
329
-
330
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
331
- test 'escaped role on escaped single-line constrained monospaced string' do
332
- para = block_from_string(%(#{BACKSLASH}[input]#{BACKSLASH}`a few <monospaced> words`), :attributes => {'compat-mode' => ''})
333
- assert_equal %(#{BACKSLASH}[input]`a few &lt;monospaced&gt; words`), para.apply_subs(para.source)
334
-
335
- para = block_from_string(%(#{BACKSLASH}[input]#{BACKSLASH}`a few <monospaced> words`))
336
- assert_equal %(#{BACKSLASH}[input]`a few &lt;monospaced&gt; words`), para.apply_subs(para.source)
337
- end
338
-
339
- # NOTE must use apply_subs because constrained monospaced is handled as a passthrough
340
- test 'multi-line constrained monospaced string' do
341
- para = block_from_string(%(`a few\n<{monospaced}> words`), :attributes => {'monospaced' => 'monospaced', 'compat-mode' => ''})
342
- assert_equal "<code>a few\n&lt;{monospaced}&gt; words</code>", para.apply_subs(para.source)
343
-
344
- para = block_from_string(%(`a few\n<{monospaced}> words`), :attributes => {'monospaced' => 'monospaced'})
345
- assert_equal "<code>a few\n&lt;monospaced&gt; words</code>", para.apply_subs(para.source)
346
- end
347
-
348
- test 'single-line unconstrained strong chars' do
349
- para = block_from_string(%q{**Git**Hub})
350
- assert_equal '<strong>Git</strong>Hub', para.sub_quotes(para.source)
351
- end
352
-
353
- test 'escaped single-line unconstrained strong chars' do
354
- para = block_from_string(%(#{BACKSLASH}**Git**Hub))
355
- assert_equal '<strong>*Git</strong>*Hub', para.sub_quotes(para.source)
356
- end
357
-
358
- test 'multi-line unconstrained strong chars' do
359
- para = block_from_string(%Q{**G\ni\nt\n**Hub})
360
- assert_equal "<strong>G\ni\nt\n</strong>Hub", para.sub_quotes(para.source)
361
- end
362
-
363
- test 'unconstrained strong chars with inline asterisk' do
364
- para = block_from_string(%q{**bl*ck**-eye})
365
- assert_equal '<strong>bl*ck</strong>-eye', para.sub_quotes(para.source)
366
- end
367
-
368
- test 'unconstrained strong chars with role' do
369
- para = block_from_string(%q{Git[blue]**Hub**})
370
- assert_equal %q{Git<strong class="blue">Hub</strong>}, para.sub_quotes(para.source)
371
- end
372
-
373
- # TODO this is not the same result as AsciiDoc, though I don't understand why AsciiDoc gets what it gets
374
- test 'escaped unconstrained strong chars with role' do
375
- para = block_from_string(%(Git#{BACKSLASH}[blue]**Hub**))
376
- assert_equal %q{Git[blue]<strong>*Hub</strong>*}, para.sub_quotes(para.source)
377
- end
378
-
379
- test 'single-line unconstrained emphasized chars' do
380
- para = block_from_string(%q{__Git__Hub})
381
- assert_equal '<em>Git</em>Hub', para.sub_quotes(para.source)
382
- end
383
-
384
- test 'escaped single-line unconstrained emphasized chars' do
385
- para = block_from_string(%(#{BACKSLASH}__Git__Hub))
386
- assert_equal '__Git__Hub', para.sub_quotes(para.source)
387
- end
388
-
389
- test 'escaped single-line unconstrained emphasized chars around word' do
390
- para = block_from_string(%(#{BACKSLASH}#{BACKSLASH}__GitHub__))
391
- assert_equal '__GitHub__', para.sub_quotes(para.source)
392
- end
393
-
394
- test 'multi-line unconstrained emphasized chars' do
395
- para = block_from_string(%Q{__G\ni\nt\n__Hub})
396
- assert_equal "<em>G\ni\nt\n</em>Hub", para.sub_quotes(para.source)
397
- end
398
-
399
- test 'unconstrained emphasis chars with role' do
400
- para = block_from_string(%q{[gray]__Git__Hub})
401
- assert_equal %q{<em class="gray">Git</em>Hub}, para.sub_quotes(para.source)
402
- end
403
-
404
- test 'escaped unconstrained emphasis chars with role' do
405
- para = block_from_string(%(#{BACKSLASH}[gray]__Git__Hub))
406
- assert_equal %q{[gray]__Git__Hub}, para.sub_quotes(para.source)
407
- end
408
-
409
- test 'single-line constrained monospaced chars' do
410
- para = block_from_string(%q{call +save()+ to persist the changes}, :attributes => {'compat-mode' => ''})
411
- assert_equal 'call <code>save()</code> to persist the changes', para.sub_quotes(para.source)
412
-
413
- para = block_from_string(%q{call [x-]+save()+ to persist the changes})
414
- assert_equal 'call <code>save()</code> to persist the changes', para.apply_subs(para.source)
415
-
416
- para = block_from_string(%q{call `save()` to persist the changes})
417
- assert_equal 'call <code>save()</code> to persist the changes', para.sub_quotes(para.source)
418
- end
419
-
420
- test 'single-line constrained monospaced chars with role' do
421
- para = block_from_string(%q{call [method]+save()+ to persist the changes}, :attributes => {'compat-mode' => ''})
422
- assert_equal 'call <code class="method">save()</code> to persist the changes', para.sub_quotes(para.source)
423
-
424
- para = block_from_string(%q{call [method x-]+save()+ to persist the changes})
425
- assert_equal 'call <code class="method">save()</code> to persist the changes', para.apply_subs(para.source)
426
-
427
- para = block_from_string(%q{call [method]`save()` to persist the changes})
428
- assert_equal 'call <code class="method">save()</code> to persist the changes', para.sub_quotes(para.source)
429
- end
430
-
431
- test 'escaped single-line constrained monospaced chars' do
432
- para = block_from_string(%(call #{BACKSLASH}+save()+ to persist the changes), :attributes => {'compat-mode' => ''})
433
- assert_equal 'call +save()+ to persist the changes', para.sub_quotes(para.source)
434
-
435
- para = block_from_string(%(call #{BACKSLASH}`save()` to persist the changes))
436
- assert_equal 'call `save()` to persist the changes', para.sub_quotes(para.source)
437
- end
438
-
439
- test 'escaped single-line constrained monospaced chars with role' do
440
- para = block_from_string(%(call [method]#{BACKSLASH}+save()+ to persist the changes), :attributes => {'compat-mode' => ''})
441
- assert_equal 'call [method]+save()+ to persist the changes', para.sub_quotes(para.source)
442
-
443
- para = block_from_string(%(call [method]#{BACKSLASH}`save()` to persist the changes))
444
- assert_equal 'call [method]`save()` to persist the changes', para.sub_quotes(para.source)
445
- end
446
-
447
- test 'escaped role on single-line constrained monospaced chars' do
448
- para = block_from_string(%(call #{BACKSLASH}[method]+save()+ to persist the changes), :attributes => {'compat-mode' => ''})
449
- assert_equal 'call [method]<code>save()</code> to persist the changes', para.sub_quotes(para.source)
450
-
451
- para = block_from_string(%(call #{BACKSLASH}[method]`save()` to persist the changes))
452
- assert_equal 'call [method]<code>save()</code> to persist the changes', para.sub_quotes(para.source)
453
- end
454
-
455
- test 'escaped role on escaped single-line constrained monospaced chars' do
456
- para = block_from_string(%(call #{BACKSLASH}[method]#{BACKSLASH}+save()+ to persist the changes), :attributes => {'compat-mode' => ''})
457
- assert_equal %(call #{BACKSLASH}[method]+save()+ to persist the changes), para.sub_quotes(para.source)
458
-
459
- para = block_from_string(%(call #{BACKSLASH}[method]#{BACKSLASH}`save()` to persist the changes))
460
- assert_equal %(call #{BACKSLASH}[method]`save()` to persist the changes), para.sub_quotes(para.source)
461
- end
462
-
463
- test 'single-line unconstrained monospaced chars' do
464
- para = block_from_string(%q{Git++Hub++}, :attributes => {'compat-mode' => ''})
465
- assert_equal 'Git<code>Hub</code>', para.sub_quotes(para.source)
466
-
467
- para = block_from_string(%q{Git[x-]++Hub++})
468
- assert_equal 'Git<code>Hub</code>', para.apply_subs(para.source)
469
-
470
- para = block_from_string(%q{Git``Hub``})
471
- assert_equal 'Git<code>Hub</code>', para.sub_quotes(para.source)
472
- end
473
-
474
- test 'escaped single-line unconstrained monospaced chars' do
475
- para = block_from_string(%(Git#{BACKSLASH}++Hub++), :attributes => {'compat-mode' => ''})
476
- assert_equal 'Git+<code>Hub</code>+', para.sub_quotes(para.source)
477
-
478
- para = block_from_string(%(Git#{BACKSLASH * 2}++Hub++), :attributes => {'compat-mode' => ''})
479
- assert_equal 'Git++Hub++', para.sub_quotes(para.source)
480
-
481
- para = block_from_string(%(Git#{BACKSLASH}``Hub``))
482
- assert_equal 'Git``Hub``', para.sub_quotes(para.source)
483
- end
484
-
485
- test 'multi-line unconstrained monospaced chars' do
486
- para = block_from_string(%Q{Git++\nH\nu\nb++}, :attributes => {'compat-mode' => ''})
487
- assert_equal "Git<code>\nH\nu\nb</code>", para.sub_quotes(para.source)
488
-
489
- para = block_from_string(%Q{Git[x-]++\nH\nu\nb++})
490
- assert_equal %(Git<code>\nH\nu\nb</code>), para.apply_subs(para.source)
491
-
492
- para = block_from_string(%Q{Git``\nH\nu\nb``})
493
- assert_equal "Git<code>\nH\nu\nb</code>", para.sub_quotes(para.source)
494
- end
495
-
496
- test 'single-line superscript chars' do
497
- para = block_from_string(%(x^2^ = x * x, e = mc^2^, there's a 1^st^ time for everything))
498
- assert_equal %(x<sup>2</sup> = x * x, e = mc<sup>2</sup>, there\'s a 1<sup>st</sup> time for everything), para.sub_quotes(para.source)
499
- end
500
-
501
- test 'escaped single-line superscript chars' do
502
- para = block_from_string(%(x#{BACKSLASH}^2^ = x * x))
503
- assert_equal 'x^2^ = x * x', para.sub_quotes(para.source)
504
- end
505
-
506
- test 'does not match superscript across whitespace' do
507
- para = block_from_string(%Q{x^(n\n-\n1)^})
508
- assert_equal para.source, para.sub_quotes(para.source)
509
- end
510
-
511
- test 'does not match adjacent superscript chars' do
512
- para = block_from_string 'a ^^ b'
513
- assert_equal 'a ^^ b', para.sub_quotes(para.source)
514
- end
515
-
516
- test 'does not confuse superscript and links with blank window shorthand' do
517
- para = block_from_string(%Q{http://localhost[Text^] on the 21^st^ and 22^nd^})
518
- assert_equal '<a href="http://localhost" target="_blank" rel="noopener">Text</a> on the 21<sup>st</sup> and 22<sup>nd</sup>', para.content
519
- end
520
-
521
- test 'single-line subscript chars' do
522
- para = block_from_string(%q{H~2~O})
523
- assert_equal 'H<sub>2</sub>O', para.sub_quotes(para.source)
524
- end
525
-
526
- test 'escaped single-line subscript chars' do
527
- para = block_from_string(%(H#{BACKSLASH}~2~O))
528
- assert_equal 'H~2~O', para.sub_quotes(para.source)
529
- end
530
-
531
- test 'does not match subscript across whitespace' do
532
- para = block_from_string(%Q{project~ view\non\nGitHub~})
533
- assert_equal para.source, para.sub_quotes(para.source)
534
- end
535
-
536
- test 'does not match adjacent subscript chars' do
537
- para = block_from_string 'a ~~ b'
538
- assert_equal 'a ~~ b', para.sub_quotes(para.source)
539
- end
540
-
541
- test 'does not match subscript across distinct URLs' do
542
- para = block_from_string(%Q{http://www.abc.com/~def[DEF] and http://www.abc.com/~ghi[GHI]})
543
- assert_equal para.source, para.sub_quotes(para.source)
544
- end
545
-
546
- test 'quoted text with role shorthand' do
547
- para = block_from_string(%q{[.white.red-background]#alert#})
548
- assert_equal '<span class="white red-background">alert</span>', para.sub_quotes(para.source)
549
- end
550
-
551
- test 'quoted text with id shorthand' do
552
- para = block_from_string(%q{[#bond]#007#})
553
- assert_equal '<span id="bond">007</span>', para.sub_quotes(para.source)
554
- end
555
-
556
- test 'quoted text with id and role shorthand' do
557
- para = block_from_string(%q{[#bond.white.red-background]#007#})
558
- assert_equal '<span id="bond" class="white red-background">007</span>', para.sub_quotes(para.source)
559
- end
560
-
561
- test 'quoted text with id and role shorthand using docbook backend' do
562
- para = block_from_string(%q{[#bond.white.red-background]#007#}, :backend => 'docbook45')
563
- assert_equal '<anchor id="bond" xreflabel="007"/><phrase role="white red-background">007</phrase>', para.sub_quotes(para.source)
564
- end
565
-
566
- test 'should ignore attributes after comma' do
567
- para = block_from_string(%q{[red, foobar]#alert#})
568
- assert_equal '<span class="red">alert</span>', para.sub_quotes(para.source)
569
- end
570
-
571
- test 'inline passthrough with id and role set using shorthand' do
572
- para = block_from_string '[#id.role]+pass+'
573
- # FIXME id should be propogated
574
- assert_equal '<span class="role">pass</span>', para.content
575
- end
576
-
577
- test 'should assign role attribute when shorthand style contains a role' do
578
- para = block_from_string 'blah'
579
- result = para.parse_quoted_text_attributes '.red#idref'
580
- expect = {'id' => 'idref', 'role' => 'red'}
581
- assert_equal expect, result
582
- end
583
-
584
- test 'should not assign role attribute if shorthand style has no roles' do
585
- para = block_from_string 'blah'
586
- result = para.parse_quoted_text_attributes '#idref'
587
- expect = {'id' => 'idref'}
588
- assert_equal expect, result
589
- end
590
- end
591
-
592
- context 'Macros' do
593
- test 'a single-line link macro should be interpreted as a link' do
594
- para = block_from_string('link:/home.html[]')
595
- assert_equal %q{<a href="/home.html" class="bare">/home.html</a>}, para.sub_macros(para.source)
596
- end
597
-
598
- test 'a single-line link macro with text should be interpreted as a link' do
599
- para = block_from_string('link:/home.html[Home]')
600
- assert_equal %q{<a href="/home.html">Home</a>}, para.sub_macros(para.source)
601
- end
602
-
603
- test 'a mailto macro should be interpreted as a mailto link' do
604
- para = block_from_string('mailto:doc.writer@asciidoc.org[]')
605
- assert_equal %q{<a href="mailto:doc.writer@asciidoc.org">doc.writer@asciidoc.org</a>}, para.sub_macros(para.source)
606
- end
607
-
608
- test 'a mailto macro with text should be interpreted as a mailto link' do
609
- para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer]')
610
- assert_equal %q{<a href="mailto:doc.writer@asciidoc.org">Doc Writer</a>}, para.sub_macros(para.source)
611
- end
612
-
613
- test 'a mailto macro with text and subject should be interpreted as a mailto link' do
614
- para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request]')
615
- assert_equal %q{<a href="mailto:doc.writer@asciidoc.org?subject=Pull%20request">Doc Writer</a>}, para.sub_macros(para.source)
616
- end
617
-
618
- test 'a mailto macro with text, subject and body should be interpreted as a mailto link' do
619
- para = block_from_string('mailto:doc.writer@asciidoc.org[Doc Writer, Pull request, Please accept my pull request]')
620
- assert_equal %q{<a href="mailto:doc.writer@asciidoc.org?subject=Pull%20request&amp;body=Please%20accept%20my%20pull%20request">Doc Writer</a>}, para.sub_macros(para.source)
621
- end
622
-
623
- test 'should recognize inline email addresses' do
624
- para = block_from_string('doc.writer@asciidoc.org')
625
- assert_equal %q{<a href="mailto:doc.writer@asciidoc.org">doc.writer@asciidoc.org</a>}, para.sub_macros(para.source)
626
- para = block_from_string('<doc.writer@asciidoc.org>')
627
- assert_equal %q{&lt;<a href="mailto:doc.writer@asciidoc.org">doc.writer@asciidoc.org</a>&gt;}, para.apply_subs(para.source)
628
- para = block_from_string('author+website@4fs.no')
629
- assert_equal %q{<a href="mailto:author+website@4fs.no">author+website@4fs.no</a>}, para.sub_macros(para.source)
630
- para = block_from_string('john@domain.uk.co')
631
- assert_equal %q{<a href="mailto:john@domain.uk.co">john@domain.uk.co</a>}, para.sub_macros(para.source)
632
- end
633
-
634
- test 'should ignore escaped inline email address' do
635
- para = block_from_string(%(#{BACKSLASH}doc.writer@asciidoc.org))
636
- assert_equal %q{doc.writer@asciidoc.org}, para.sub_macros(para.source)
637
- end
638
-
639
- test 'a single-line raw url should be interpreted as a link' do
640
- para = block_from_string('http://google.com')
641
- assert_equal %q{<a href="http://google.com" class="bare">http://google.com</a>}, para.sub_macros(para.source)
642
- end
643
-
644
- test 'a single-line raw url with text should be interpreted as a link' do
645
- para = block_from_string('http://google.com[Google]')
646
- assert_equal %q{<a href="http://google.com">Google</a>}, para.sub_macros(para.source)
647
- end
648
-
649
- test 'a multi-line raw url with text should be interpreted as a link' do
650
- para = block_from_string("http://google.com[Google\nHomepage]")
651
- assert_equal %{<a href="http://google.com">Google\nHomepage</a>}, para.sub_macros(para.source)
652
- end
653
-
654
- test 'a single-line raw url with attribute as text should be interpreted as a link with resolved attribute' do
655
- para = block_from_string("http://google.com[{google_homepage}]")
656
- para.document.attributes['google_homepage'] = 'Google Homepage'
657
- assert_equal %q{<a href="http://google.com">Google Homepage</a>}, para.sub_macros(para.sub_attributes(para.source))
658
- end
659
-
660
- test 'should not resolve an escaped attribute in link text' do
661
- {
662
- 'http://google.com' => "http://google.com[#{BACKSLASH}{google_homepage}]",
663
- 'http://google.com?q=,' => "link:http://google.com?q=,[#{BACKSLASH}{google_homepage}]"
664
- }.each do |uri, macro|
665
- para = block_from_string macro
666
- para.document.attributes['google_homepage'] = 'Google Homepage'
667
- assert_equal %(<a href="#{uri}">{google_homepage}</a>), para.sub_macros(para.sub_attributes(para.source))
668
- end
669
- end
670
-
671
- test 'a single-line escaped raw url should not be interpreted as a link' do
672
- para = block_from_string(%(#{BACKSLASH}http://google.com))
673
- assert_equal %q{http://google.com}, para.sub_macros(para.source)
674
- end
675
-
676
- test 'a comma separated list of links should not include commas in links' do
677
- para = block_from_string('http://foo.com, http://bar.com, http://example.org')
678
- assert_equal %q{<a href="http://foo.com" class="bare">http://foo.com</a>, <a href="http://bar.com" class="bare">http://bar.com</a>, <a href="http://example.org" class="bare">http://example.org</a>}, para.sub_macros(para.source)
679
- end
680
-
681
- test 'a single-line image macro should be interpreted as an image' do
682
- para = block_from_string('image:tiger.png[]')
683
- assert_equal %{<span class="image"><img src="tiger.png" alt="tiger"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
684
- end
685
-
686
- test 'should replace underscore and hyphen with space in generated alt text for an inline image' do
687
- para = block_from_string('image:tiger-with-family_1.png[]')
688
- assert_equal %{<span class="image"><img src="tiger-with-family_1.png" alt="tiger with family 1"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
689
- end
690
-
691
- test 'a single-line image macro with text should be interpreted as an image with alt text' do
692
- para = block_from_string('image:tiger.png[Tiger]')
693
- assert_equal %{<span class="image"><img src="tiger.png" alt="Tiger"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
694
- end
695
-
696
- test 'should encode special characters in alt text of inline image' do
697
- input = 'A tiger\'s "roar" is < a bear\'s "growl"'
698
- expected = 'A tiger&#8217;s &quot;roar&quot; is &lt; a bear&#8217;s &quot;growl&quot;'
699
- output = (convert_inline_string %(image:tiger-roar.png[#{input}])).gsub(/>\s+</, '><')
700
- assert_equal %(<span class="image"><img src="tiger-roar.png" alt="#{expected}"></span>), output
701
- end
702
-
703
- test 'an image macro with SVG image and text should be interpreted as an image with alt text' do
704
- para = block_from_string('image:tiger.svg[Tiger]')
705
- assert_equal %{<span class="image"><img src="tiger.svg" alt="Tiger"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
706
- end
707
-
708
- test 'an image macro with an interactive SVG image and alt text should be converted to an object element' do
709
- para = block_from_string('image:tiger.svg[Tiger,opts=interactive]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'images' })
710
- assert_equal %{<span class="image"><object type="image/svg+xml" data="images/tiger.svg"><span class="alt">Tiger</span></object></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
711
- end
712
-
713
- test 'an image macro with an interactive SVG image, fallback and alt text should be converted to an object element' do
714
- para = block_from_string('image:tiger.svg[Tiger,fallback=tiger.png,opts=interactive]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'images' })
715
- assert_equal %{<span class="image"><object type="image/svg+xml" data="images/tiger.svg"><img src="images/tiger.png" alt="Tiger"></object></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
716
- end
717
-
718
- test 'an image macro with an inline SVG image should be converted to an svg element' do
719
- para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'imagesdir' => 'fixtures', 'docdir' => testdir })
720
- result = para.sub_macros(para.source).gsub(/>\s+</, '><')
721
- assert_match(/<svg\s[^>]*width="100px"[^>]*>/, result)
722
- refute_match(/<svg\s[^>]*width="500px"[^>]*>/, result)
723
- refute_match(/<svg\s[^>]*height="500px"[^>]*>/, result)
724
- refute_match(/<svg\s[^>]*style="width:500px;height:500px"[^>]*>/, result)
725
- end
726
-
727
- test 'an image macro with an inline SVG image should be converted to an svg element even when data-uri is set' do
728
- para = block_from_string('image:circle.svg[Tiger,100,opts=inline]', :safe => Asciidoctor::SafeMode::SERVER, :attributes => { 'data-uri' => '', 'imagesdir' => 'fixtures', 'docdir' => testdir })
729
- assert_match(/<svg\s[^>]*width="100px">/, para.sub_macros(para.source).gsub(/>\s+</, '><'))
730
- end
731
-
732
- test 'an image macro with an SVG image should not use an object element when safe mode is secure' do
733
- para = block_from_string('image:tiger.svg[Tiger,opts=interactive]', :attributes => { 'imagesdir' => 'images' })
734
- assert_equal %{<span class="image"><img src="images/tiger.svg" alt="Tiger"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
735
- end
736
-
737
- test 'a single-line image macro with text containing escaped square bracket should be interpreted as an image with alt text' do
738
- para = block_from_string(%(image:tiger.png[[Another#{BACKSLASH}] Tiger]))
739
- assert_equal %{<span class="image"><img src="tiger.png" alt="[Another] Tiger"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
740
- end
741
-
742
- test 'a single-line image macro with text and dimensions should be interpreted as an image with alt text and dimensions' do
743
- para = block_from_string('image:tiger.png[Tiger, 200, 100]')
744
- assert_equal %{<span class="image"><img src="tiger.png" alt="Tiger" width="200" height="100"></span>},
745
- para.sub_macros(para.source).gsub(/>\s+</, '><')
746
- end
747
-
748
- test 'a single-line image macro with text and dimensions should be interpreted as an image with alt text and dimensions in docbook' do
749
- para = block_from_string 'image:tiger.png[Tiger, 200, 100]', :backend => 'docbook'
750
- assert_equal %{<inlinemediaobject><imageobject><imagedata fileref="tiger.png" contentwidth="200" contentdepth="100"/></imageobject><textobject><phrase>Tiger</phrase></textobject></inlinemediaobject>},
751
- para.sub_macros(para.source).gsub(/>\s+</, '><')
752
- end
753
-
754
- test 'a single-line image macro with text and link should be interpreted as a linked image with alt text' do
755
- para = block_from_string('image:tiger.png[Tiger, link="http://en.wikipedia.org/wiki/Tiger"]')
756
- assert_equal %{<span class="image"><a class="image" href="http://en.wikipedia.org/wiki/Tiger"><img src="tiger.png" alt="Tiger"></a></span>},
757
- para.sub_macros(para.source).gsub(/>\s+</, '><')
758
- end
759
-
760
- test 'rel=noopener should be added to an image with a link that targets the _blank window' do
761
- para = block_from_string 'image:tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,window=_blank]'
762
- assert_equal %{<span class="image"><a class="image" href="http://en.wikipedia.org/wiki/Tiger" target="_blank" rel="noopener"><img src="tiger.png" alt="Tiger"></a></span>},
763
- para.sub_macros(para.source).gsub(/>\s+</, '><')
764
- end
765
-
766
- test 'rel=noopener should be added to an image with a link that targets a named window when the noopener option is set' do
767
- para = block_from_string 'image:tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,window=name,opts=noopener]'
768
- assert_equal %{<span class="image"><a class="image" href="http://en.wikipedia.org/wiki/Tiger" target="name" rel="noopener"><img src="tiger.png" alt="Tiger"></a></span>},
769
- para.sub_macros(para.source).gsub(/>\s+</, '><')
770
- end
771
-
772
- test 'rel=nofollow should be added to an image with a link when the nofollow option is set' do
773
- para = block_from_string 'image:tiger.png[Tiger,link=http://en.wikipedia.org/wiki/Tiger,opts=nofollow]'
774
- assert_equal %{<span class="image"><a class="image" href="http://en.wikipedia.org/wiki/Tiger" rel="nofollow"><img src="tiger.png" alt="Tiger"></a></span>},
775
- para.sub_macros(para.source).gsub(/>\s+</, '><')
776
- end
777
-
778
- test 'a multi-line image macro with text and dimensions should be interpreted as an image with alt text and dimensions' do
779
- para = block_from_string(%(image:tiger.png[Another\nAwesome\nTiger, 200,\n100]))
780
- assert_equal %{<span class="image"><img src="tiger.png" alt="Another Awesome Tiger" width="200" height="100"></span>},
781
- para.sub_macros(para.source).gsub(/>\s+</, '><')
782
- end
783
-
784
- test 'an inline image macro with a url target should be interpreted as an image' do
785
- para = block_from_string %(Beware of the image:http://example.com/images/tiger.png[tiger].)
786
- assert_equal %{Beware of the <span class="image"><img src="http://example.com/images/tiger.png" alt="tiger"></span>.},
787
- para.sub_macros(para.source).gsub(/>\s+</, '><')
788
- end
789
-
790
- test 'an inline image macro with a float attribute should be interpreted as a floating image' do
791
- para = block_from_string %(image:http://example.com/images/tiger.png[tiger, float="right"] Beware of the tigers!)
792
- assert_equal %{<span class="image right"><img src="http://example.com/images/tiger.png" alt="tiger"></span> Beware of the tigers!},
793
- para.sub_macros(para.source).gsub(/>\s+</, '><')
794
- end
795
-
796
- test 'should prepend value of imagesdir attribute to inline image target if target is relative path' do
797
- para = block_from_string %(Beware of the image:tiger.png[tiger].), :attributes => {'imagesdir' => './images'}
798
- assert_equal %{Beware of the <span class="image"><img src="./images/tiger.png" alt="tiger"></span>.},
799
- para.sub_macros(para.source).gsub(/>\s+</, '><')
800
- end
801
-
802
- test 'should not prepend value of imagesdir attribute to inline image target if target is absolute path' do
803
- para = block_from_string %(Beware of the image:/tiger.png[tiger].), :attributes => {'imagesdir' => './images'}
804
- assert_equal %{Beware of the <span class="image"><img src="/tiger.png" alt="tiger"></span>.},
805
- para.sub_macros(para.source).gsub(/>\s+</, '><')
806
- end
807
-
808
- test 'should not prepend value of imagesdir attribute to inline image target if target is url' do
809
- para = block_from_string %(Beware of the image:http://example.com/images/tiger.png[tiger].), :attributes => {'imagesdir' => './images'}
810
- assert_equal %{Beware of the <span class="image"><img src="http://example.com/images/tiger.png" alt="tiger"></span>.},
811
- para.sub_macros(para.source).gsub(/>\s+</, '><')
812
- end
813
-
814
- test 'should match an inline image macro if target contains a space character' do
815
- para = block_from_string(%(Beware of the image:big cats.png[] around here.))
816
- assert_equal %(Beware of the <span class="image"><img src="big%20cats.png" alt="big cats"></span> around here.),
817
- para.sub_macros(para.source).gsub(/>\s+</, '><')
818
- end
819
-
820
- test 'should not match an inline image macro if target contains an endline character' do
821
- para = block_from_string(%(Fear not. There are no image:big\ncats.png[] around here.))
822
- result = para.sub_macros(para.source)
823
- refute_includes result, '<img '
824
- assert_includes result, %(image:big\ncats.png[])
825
- end
826
-
827
- test 'should not match an inline image macro if target begins or ends with space character' do
828
- ['image: big cats.png[]', 'image:big cats.png []'].each do |input|
829
- para = block_from_string %(Fear not. There are no #{input} around here.)
830
- result = para.sub_macros(para.source)
831
- refute_includes result, '<img '
832
- assert_includes result, input
833
- end
834
- end
835
-
836
- test 'should not detect a block image macro found inline' do
837
- para = block_from_string(%(Not an inline image macro image::tiger.png[].))
838
- result = para.sub_macros(para.source)
839
- refute_includes result, '<img '
840
- assert_includes result, 'image::tiger.png[]'
841
- end
842
-
843
- # NOTE this test verifies attributes get substituted eagerly in target of image in title
844
- test 'should substitute attributes in target of inline image in section title' do
845
- input = <<-EOS
846
- == image:{iconsdir}/dot.gif[dot] Title
847
- EOS
848
-
849
- using_memory_logger do |logger|
850
- sect = block_from_string input, :attributes => { 'data-uri' => '', 'iconsdir' => 'fixtures', 'docdir' => testdir }, :safe => :server, :catalog_assets => true
851
- assert 1, sect.document.catalog[:images].size
852
- assert_equal 'fixtures/dot.gif', sect.document.catalog[:images][0].to_s
853
- assert_nil sect.document.catalog[:images][0].imagesdir
854
- assert logger.empty?
855
- end
856
- end
857
-
858
- test 'an icon macro should be interpreted as an icon if icons are enabled' do
859
- para = block_from_string 'icon:github[]', :attributes => {'icons' => ''}
860
- assert_equal %{<span class="icon"><img src="./images/icons/github.png" alt="github"></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
861
- end
862
-
863
- test 'an icon macro should be interpreted as alt text if icons are disabled' do
864
- para = block_from_string 'icon:github[]'
865
- assert_equal %{<span class="icon">[github]</span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
866
- end
867
-
868
- test 'an icon macro should output alt text if icons are disabled and alt is given' do
869
- para = block_from_string 'icon:github[alt="GitHub"]'
870
- assert_equal %{<span class="icon">[GitHub]</span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
871
- end
872
-
873
- test 'an icon macro should be interpreted as a font-based icon when icons=font' do
874
- para = block_from_string 'icon:github[]', :attributes => {'icons' => 'font'}
875
- assert_equal %{<span class="icon"><i class="fa fa-github"></i></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
876
- end
877
-
878
- test 'an icon macro with a size should be interpreted as a font-based icon with a size when icons=font' do
879
- para = block_from_string 'icon:github[4x]', :attributes => {'icons' => 'font'}
880
- assert_equal %{<span class="icon"><i class="fa fa-github fa-4x"></i></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
881
- end
882
-
883
- test 'an icon macro with a role and title should be interpreted as a font-based icon with a class and title when icons=font' do
884
- para = block_from_string 'icon:heart[role="red", title="Heart me"]', :attributes => {'icons' => 'font'}
885
- assert_equal %{<span class="icon red"><i class="fa fa-heart" title="Heart me"></i></span>}, para.sub_macros(para.source).gsub(/>\s+</, '><')
886
- end
887
-
888
- test 'a single-line footnote macro should be registered and output as a footnote' do
889
- para = block_from_string('Sentence text footnote:[An example footnote.].')
890
- assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
891
- assert_equal 1, para.document.catalog[:footnotes].size
892
- footnote = para.document.catalog[:footnotes].first
893
- assert_equal 1, footnote.index
894
- assert_nil footnote.id
895
- assert_equal 'An example footnote.', footnote.text
896
- end
897
-
898
- test 'a multi-line footnote macro should be registered and output as a footnote without endline' do
899
- para = block_from_string("Sentence text footnote:[An example footnote\nwith wrapped text.].")
900
- assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
901
- assert_equal 1, para.document.catalog[:footnotes].size
902
- footnote = para.document.catalog[:footnotes].first
903
- assert_equal 1, footnote.index
904
- assert_nil footnote.id
905
- assert_equal "An example footnote with wrapped text.", footnote.text
906
- end
907
-
908
- test 'an escaped closing square bracket in a footnote should be unescaped when converted' do
909
- para = block_from_string(%(footnote:[a #{BACKSLASH}] b].))
910
- assert_equal %(<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
911
- assert_equal 1, para.document.catalog[:footnotes].size
912
- footnote = para.document.catalog[:footnotes].first
913
- assert_equal "a ] b", footnote.text
914
- end
915
-
916
- test 'a footnote macro can be directly adjacent to preceding word' do
917
- para = block_from_string('Sentence textfootnote:[An example footnote.].')
918
- assert_equal %(Sentence text<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
919
- end
920
-
921
- test 'a footnote macro may contain an escaped backslash' do
922
- para = block_from_string("footnote:[\\]]\nfootnote:[a \\] b]\nfootnote:[a \\]\\] b]")
923
- para.sub_macros(para.source)
924
- assert_equal 3, para.document.catalog[:footnotes].size
925
- footnote1 = para.document.catalog[:footnotes][0]
926
- assert_equal ']', footnote1.text
927
- footnote2 = para.document.catalog[:footnotes][1]
928
- assert_equal 'a ] b', footnote2.text
929
- footnote3 = para.document.catalog[:footnotes][2]
930
- assert_equal 'a ]] b', footnote3.text
931
- end
932
-
933
- test 'a footnote macro may contain a link macro' do
934
- para = block_from_string('Share your code. footnote:[https://github.com[GitHub]]')
935
- assert_equal %(Share your code. <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
936
- assert_equal 1, para.document.catalog[:footnotes].size
937
- footnote1 = para.document.catalog[:footnotes][0]
938
- assert_equal '<a href="https://github.com">GitHub</a>', footnote1.text
939
- end
940
-
941
- test 'a footnote macro may contain a plain URL' do
942
- para = block_from_string %(the JLine footnote:[https://github.com/jline/jline2]\nlibrary.)
943
- result = para.sub_macros para.source
944
- assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>\nlibrary.), result
945
- assert_equal 1, para.document.catalog[:footnotes].size
946
- fn1 = para.document.catalog[:footnotes].first
947
- assert_equal '<a href="https://github.com/jline/jline2" class="bare">https://github.com/jline/jline2</a>', fn1.text
948
- end
949
-
950
- test 'a footnote macro followed by a semi-colon may contain a plain URL' do
951
- para = block_from_string %(the JLine footnote:[https://github.com/jline/jline2];\nlibrary.)
952
- result = para.sub_macros para.source
953
- assert_equal %(the JLine <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>;\nlibrary.), result
954
- assert_equal 1, para.document.catalog[:footnotes].size
955
- fn1 = para.document.catalog[:footnotes].first
956
- assert_equal '<a href="https://github.com/jline/jline2" class="bare">https://github.com/jline/jline2</a>', fn1.text
957
- end
958
-
959
- test 'a footnote macro may contain an xref macro' do
960
- # specialcharacters escaping is simulated
961
- para = block_from_string('text footnote:[&lt;&lt;_install,install&gt;&gt;]')
962
- doc = para.document
963
- doc.register :refs, ['_install', (Asciidoctor::Inline.new doc, :anchor, 'Install', :type => :ref, :target => '_install'), 'Install']
964
- catalog = doc.catalog
965
- assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
966
- assert_equal 1, catalog[:footnotes].size
967
- footnote1 = catalog[:footnotes][0]
968
- assert_equal '<a href="#_install">install</a>', footnote1.text
969
- end
970
-
971
- test 'a footnote macro may contain an anchor macro' do
972
- para = block_from_string('text footnote:[a [[b\]\] \[[c\]\] d]')
973
- assert_equal %(text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>), para.sub_macros(para.source)
974
- assert_equal 1, para.document.catalog[:footnotes].size
975
- footnote1 = para.document.catalog[:footnotes][0]
976
- assert_equal 'a <a id="b"></a> [[c]] d', footnote1.text
977
- end
978
-
979
- test 'subsequent footnote macros with escaped URLs should be restored in DocBook' do
980
- input = <<-EOS
981
- foofootnote:[+http://example.com+]barfootnote:[+http://acme.com+]baz
982
- EOS
983
-
984
- result = convert_string_to_embedded input, :doctype => 'inline', :backend => 'docbook'
985
- assert_equal 'foo<footnote><simpara>http://example.com</simpara></footnote>bar<footnote><simpara>http://acme.com</simpara></footnote>baz', result
986
- end
987
-
988
- test 'should increment index of subsequent footnote macros' do
989
- para = block_from_string("Sentence text footnote:[An example footnote.]. Sentence text footnote:[Another footnote.].")
990
- assert_equal %(Sentence text <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>. Sentence text <sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup>.), para.sub_macros(para.source)
991
- assert_equal 2, para.document.catalog[:footnotes].size
992
- footnote1 = para.document.catalog[:footnotes][0]
993
- assert_equal 1, footnote1.index
994
- assert_nil footnote1.id
995
- assert_equal "An example footnote.", footnote1.text
996
- footnote2 = para.document.catalog[:footnotes][1]
997
- assert_equal 2, footnote2.index
998
- assert_nil footnote2.id
999
- assert_equal "Another footnote.", footnote2.text
1000
- end
1001
-
1002
- test 'a footnoteref macro with id and single-line text should be registered and output as a footnote' do
1003
- para = block_from_string('Sentence text footnoteref:[ex1, An example footnote.].')
1004
- assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
1005
- assert_equal 1, para.document.catalog[:footnotes].size
1006
- footnote = para.document.catalog[:footnotes].first
1007
- assert_equal 1, footnote.index
1008
- assert_equal 'ex1', footnote.id
1009
- assert_equal 'An example footnote.', footnote.text
1010
- end
1011
-
1012
- test 'a footnoteref macro with id and multi-line text should be registered and output as a footnote without endlines' do
1013
- para = block_from_string("Sentence text footnoteref:[ex1, An example footnote\nwith wrapped text.].")
1014
- assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
1015
- assert_equal 1, para.document.catalog[:footnotes].size
1016
- footnote = para.document.catalog[:footnotes].first
1017
- assert_equal 1, footnote.index
1018
- assert_equal 'ex1', footnote.id
1019
- assert_equal "An example footnote with wrapped text.", footnote.text
1020
- end
1021
-
1022
- test 'a footnoteref macro with id should refer to footnoteref with same id' do
1023
- para = block_from_string('Sentence text footnoteref:[ex1, An example footnote.]. Sentence text footnoteref:[ex1].')
1024
- assert_equal %(Sentence text <sup class="footnote" id="_footnote_ex1">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>. Sentence text <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.), para.sub_macros(para.source)
1025
- assert_equal 1, para.document.catalog[:footnotes].size
1026
- footnote = para.document.catalog[:footnotes].first
1027
- assert_equal 1, footnote.index
1028
- assert_equal 'ex1', footnote.id
1029
- assert_equal 'An example footnote.', footnote.text
1030
- end
1031
-
1032
- test 'an unresolved footnote reference should produce a warning message' do
1033
- input = 'Sentence text.footnote:ex1[]'
1034
- using_memory_logger do |logger|
1035
- para = block_from_string input
1036
- para.sub_macros para.source
1037
- assert_message logger, :WARN, 'invalid footnote reference: ex1'
1038
- end
1039
- end
1040
-
1041
- test 'inline footnote macro can be used to define and reference a footnote reference' do
1042
- input = <<-EOS
1043
- You can download the software from the product page.footnote:sub[Option only available if you have an active subscription.]
1044
-
1045
- You can also file a support request.footnote:sub[]
1046
-
1047
- If all else fails, you can give us a call.footnoteref:[sub]
1048
- EOS
1049
-
1050
- output = convert_string_to_embedded input
1051
- assert_css '#_footnotedef_1', output, 1
1052
- assert_css 'p a[href="#_footnotedef_1"]', output, 3
1053
- assert_css '#footnotes .footnote', output, 1
1054
- end
1055
-
1056
- test 'should parse multiple footnote references in a single line' do
1057
- input = <<-'EOS'
1058
- notable text.footnote:id[about this [text\]], footnote:id[], footnote:id[]
1059
- EOS
1060
-
1061
- output = convert_string_to_embedded input
1062
- assert_xpath '(//p)[1]/sup[starts-with(@class,"footnote")]', output, 3
1063
- assert_xpath '(//p)[1]/sup[@class="footnote"]', output, 1
1064
- assert_xpath '(//p)[1]/sup[@class="footnoteref"]', output, 2
1065
- assert_xpath '(//p)[1]/sup[starts-with(@class,"footnote")]/a[@class="footnote"][text()="1"]', output, 3
1066
- assert_css '#footnotes .footnote', output, 1
1067
- end
1068
-
1069
- test 'should not resolve an inline footnote macro missing both id and text' do
1070
- input = <<-EOS
1071
- The footnote:[] macro can be used for defining and referencing footnotes.
1072
-
1073
- The footnoteref:[] macro is now deprecated.
1074
- EOS
1075
-
1076
- output = convert_string_to_embedded input
1077
- assert_includes output, 'The footnote:[] macro'
1078
- assert_includes output, 'The footnoteref:[] macro'
1079
- end
1080
-
1081
- test 'inline footnote macro can define a numeric id without conflicting with auto-generated ID' do
1082
- input = <<-EOS
1083
- You can download the software from the product page.footnote:1[Option only available if you have an active subscription.]
1084
- EOS
1085
-
1086
- output = convert_string_to_embedded input
1087
- assert_css '#_footnote_1', output, 1
1088
- assert_css 'p sup#_footnote_1', output, 1
1089
- assert_css 'p a#_footnoteref_1', output, 1
1090
- assert_css 'p a[href="#_footnotedef_1"]', output, 1
1091
- assert_css '#footnotes #_footnotedef_1', output, 1
1092
- end
1093
-
1094
- test 'a single-line index term macro with a primary term should be registered as an index reference' do
1095
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1096
- macros = ['indexterm:[Tigers]', '(((Tigers)))']
1097
- macros.each do |macro|
1098
- para = block_from_string("#{sentence}#{macro}")
1099
- output = para.sub_macros(para.source)
1100
- assert_equal sentence, output
1101
- assert_equal 1, para.document.catalog[:indexterms].size
1102
- assert_equal ['Tigers'], para.document.catalog[:indexterms].first
1103
- end
1104
- end
1105
-
1106
- test 'a single-line index term macro with primary and secondary terms should be registered as an index reference' do
1107
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1108
- macros = ['indexterm:[Big cats, Tigers]', '(((Big cats, Tigers)))']
1109
- macros.each do |macro|
1110
- para = block_from_string("#{sentence}#{macro}")
1111
- output = para.sub_macros(para.source)
1112
- assert_equal sentence, output
1113
- assert_equal 1, para.document.catalog[:indexterms].size
1114
- assert_equal ['Big cats', 'Tigers'], para.document.catalog[:indexterms].first
1115
- end
1116
- end
1117
-
1118
- test 'a single-line index term macro with primary, secondary and tertiary terms should be registered as an index reference' do
1119
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1120
- macros = ['indexterm:[Big cats,Tigers , Panthera tigris]', '(((Big cats,Tigers , Panthera tigris)))']
1121
- macros.each do |macro|
1122
- para = block_from_string("#{sentence}#{macro}")
1123
- output = para.sub_macros(para.source)
1124
- assert_equal sentence, output
1125
- assert_equal 1, para.document.catalog[:indexterms].size
1126
- assert_equal ['Big cats', 'Tigers', 'Panthera tigris'], para.document.catalog[:indexterms].first
1127
- end
1128
- end
1129
-
1130
- test 'a multi-line index term macro should be compacted and registered as an index reference' do
1131
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1132
- macros = ["indexterm:[Panthera\ntigris]", "(((Panthera\ntigris)))"]
1133
- macros.each do |macro|
1134
- para = block_from_string("#{sentence}#{macro}")
1135
- output = para.sub_macros(para.source)
1136
- assert_equal sentence, output
1137
- assert_equal 1, para.document.catalog[:indexterms].size
1138
- assert_equal ['Panthera tigris'], para.document.catalog[:indexterms].first
1139
- end
1140
- end
1141
-
1142
- test 'should escape concealed index term if second bracket is preceded by a backslash' do
1143
- input = %[National Institute of Science and Technology (#{BACKSLASH}((NIST)))]
1144
- doc = document_from_string input, :header_footer => false
1145
- output = doc.convert
1146
- assert_xpath '//p[text()="National Institute of Science and Technology (((NIST)))"]', output, 1
1147
- assert doc.catalog[:indexterms].empty?
1148
- end
1149
-
1150
- test 'should only escape enclosing brackets if concealed index term is preceded by a backslash' do
1151
- input = %[National Institute of Science and Technology #{BACKSLASH}(((NIST)))]
1152
- doc = document_from_string input, :header_footer => false
1153
- output = doc.convert
1154
- assert_xpath '//p[text()="National Institute of Science and Technology (NIST)"]', output, 1
1155
- term = doc.catalog[:indexterms].first
1156
- assert_equal 1, term.size
1157
- assert_equal 'NIST', term.first
1158
- end
1159
-
1160
- test 'should not split index terms on commas inside of quoted terms' do
1161
- inputs = []
1162
- inputs.push <<-EOS
1163
- Tigers are big, scary cats.
1164
- indexterm:[Tigers, "[Big\\],
1165
- scary cats"]
1166
- EOS
1167
- inputs.push <<-EOS
1168
- Tigers are big, scary cats.
1169
- (((Tigers, "[Big],
1170
- scary cats")))
1171
- EOS
1172
-
1173
- inputs.each do |input|
1174
- para = block_from_string input
1175
- output = para.sub_macros(para.source)
1176
- assert_equal input.lines.first, output
1177
- assert_equal 1, para.document.catalog[:indexterms].size
1178
- terms = para.document.catalog[:indexterms].first
1179
- assert_equal 2, terms.size
1180
- assert_equal 'Tigers', terms.first
1181
- assert_equal '[Big], scary cats', terms.last
1182
- end
1183
- end
1184
-
1185
- test 'normal substitutions are performed on an index term macro' do
1186
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1187
- macros = ['indexterm:[*Tigers*]', '(((*Tigers*)))']
1188
- macros.each do |macro|
1189
- para = block_from_string("#{sentence}#{macro}")
1190
- output = para.apply_subs(para.source)
1191
- assert_equal sentence, output
1192
- assert_equal 1, para.document.catalog[:indexterms].size
1193
- assert_equal ['<strong>Tigers</strong>'], para.document.catalog[:indexterms].first
1194
- end
1195
- end
1196
-
1197
- test 'registers multiple index term macros' do
1198
- sentence = "The tiger (Panthera tigris) is the largest cat species."
1199
- macros = "(((Tigers)))\n(((Animals,Cats)))"
1200
- para = block_from_string("#{sentence}\n#{macros}")
1201
- output = para.sub_macros(para.source)
1202
- assert_equal sentence, output.rstrip
1203
- assert_equal 2, para.document.catalog[:indexterms].size
1204
- assert_equal ['Tigers'], para.document.catalog[:indexterms][0]
1205
- assert_equal ['Animals', 'Cats'], para.document.catalog[:indexterms][1]
1206
- end
1207
-
1208
- test 'an index term macro with round bracket syntax may contain round brackets in term' do
1209
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1210
- macro = '(((Tiger (Panthera tigris))))'
1211
- para = block_from_string("#{sentence}#{macro}")
1212
- output = para.sub_macros(para.source)
1213
- assert_equal sentence, output
1214
- assert_equal 1, para.document.catalog[:indexterms].size
1215
- assert_equal ['Tiger (Panthera tigris)'], para.document.catalog[:indexterms].first
1216
- end
1217
-
1218
- test 'visible shorthand index term macro should not consume trailing round bracket' do
1219
- input = '(text with ((index term)))'
1220
- expected = '(text with <indexterm><primary>index term</primary></indexterm>index term)'
1221
- expected_term = ['index term']
1222
- para = block_from_string input, :backend => :docbook
1223
- output = para.sub_macros para.source
1224
- indexterms_table = para.document.catalog[:indexterms]
1225
- assert_equal 1, indexterms_table.size
1226
- assert_equal expected_term, indexterms_table[0]
1227
- assert_equal expected, output
1228
- end
1229
-
1230
- test 'visible shorthand index term macro should not consume leading round bracket' do
1231
- input = '(((index term)) for text)'
1232
- expected = '(<indexterm><primary>index term</primary></indexterm>index term for text)'
1233
- expected_term = ['index term']
1234
- para = block_from_string input, :backend => :docbook
1235
- output = para.sub_macros para.source
1236
- indexterms_table = para.document.catalog[:indexterms]
1237
- assert_equal 1, indexterms_table.size
1238
- assert_equal expected_term, indexterms_table[0]
1239
- assert_equal expected, output
1240
- end
1241
-
1242
- test 'an index term macro with square bracket syntax may contain square brackets in term' do
1243
- sentence = "The tiger (Panthera tigris) is the largest cat species.\n"
1244
- macro = 'indexterm:[Tiger [Panthera tigris\\]]'
1245
- para = block_from_string("#{sentence}#{macro}")
1246
- output = para.sub_macros(para.source)
1247
- assert_equal sentence, output
1248
- assert_equal 1, para.document.catalog[:indexterms].size
1249
- assert_equal ['Tiger [Panthera tigris]'], para.document.catalog[:indexterms].first
1250
- end
1251
-
1252
- test 'a single-line index term 2 macro should be registered as an index reference and retain term inline' do
1253
- sentence = 'The tiger (Panthera tigris) is the largest cat species.'
1254
- macros = ['The indexterm2:[tiger] (Panthera tigris) is the largest cat species.', 'The ((tiger)) (Panthera tigris) is the largest cat species.']
1255
- macros.each do |macro|
1256
- para = block_from_string(macro)
1257
- output = para.sub_macros(para.source)
1258
- assert_equal sentence, output
1259
- assert_equal 1, para.document.catalog[:indexterms].size
1260
- assert_equal ['tiger'], para.document.catalog[:indexterms].first
1261
- end
1262
- end
1263
-
1264
- test 'a multi-line index term 2 macro should be compacted and registered as an index reference and retain term inline' do
1265
- sentence = 'The panthera tigris is the largest cat species.'
1266
- macros = ["The indexterm2:[ panthera\ntigris ] is the largest cat species.", "The (( panthera\ntigris )) is the largest cat species."]
1267
- macros.each do |macro|
1268
- para = block_from_string(macro)
1269
- output = para.sub_macros(para.source)
1270
- assert_equal sentence, output
1271
- assert_equal 1, para.document.catalog[:indexterms].size
1272
- assert_equal ['panthera tigris'], para.document.catalog[:indexterms].first
1273
- end
1274
- end
1275
-
1276
- test 'registers multiple index term 2 macros' do
1277
- sentence = "The ((tiger)) (Panthera tigris) is the largest ((cat)) species."
1278
- para = block_from_string(sentence)
1279
- output = para.sub_macros(para.source)
1280
- assert_equal 'The tiger (Panthera tigris) is the largest cat species.', output
1281
- assert_equal 2, para.document.catalog[:indexterms].size
1282
- assert_equal ['tiger'], para.document.catalog[:indexterms][0]
1283
- assert_equal ['cat'], para.document.catalog[:indexterms][1]
1284
- end
1285
-
1286
- test 'should escape visible index term if preceded by a backslash' do
1287
- sentence = "The #{BACKSLASH}((tiger)) (Panthera tigris) is the largest #{BACKSLASH}((cat)) species."
1288
- para = block_from_string(sentence)
1289
- output = para.sub_macros(para.source)
1290
- assert_equal 'The ((tiger)) (Panthera tigris) is the largest ((cat)) species.', output
1291
- assert para.document.catalog[:indexterms].empty?
1292
- end
1293
-
1294
- test 'normal substitutions are performed on an index term 2 macro' do
1295
- sentence = 'The ((*tiger*)) (Panthera tigris) is the largest cat species.'
1296
- para = block_from_string sentence
1297
- output = para.apply_subs(para.source)
1298
- assert_equal 'The <strong>tiger</strong> (Panthera tigris) is the largest cat species.', output
1299
- assert_equal 1, para.document.catalog[:indexterms].size
1300
- assert_equal ['<strong>tiger</strong>'], para.document.catalog[:indexterms].first
1301
- end
1302
-
1303
- test 'index term 2 macro with round bracket syntex should not interfer with index term macro with round bracket syntax' do
1304
- sentence = "The ((panthera tigris)) is the largest cat species.\n(((Big cats,Tigers)))"
1305
- para = block_from_string sentence
1306
- output = para.sub_macros(para.source)
1307
- assert_equal "The panthera tigris is the largest cat species.\n", output
1308
- terms = para.document.catalog[:indexterms]
1309
- assert_equal 2, terms.size
1310
- assert_equal ['panthera tigris'], terms[0]
1311
- assert_equal ['Big cats', 'Tigers'], terms[1]
1312
- end
1313
-
1314
- context 'Button macro' do
1315
- test 'btn macro' do
1316
- para = block_from_string('btn:[Save]', :attributes => {'experimental' => ''})
1317
- assert_equal %q{<b class="button">Save</b>}, para.sub_macros(para.source)
1318
- end
1319
-
1320
- test 'btn macro that spans multiple lines' do
1321
- para = block_from_string(%(btn:[Rebase and\nmerge]), :attributes => {'experimental' => ''})
1322
- assert_equal %q{<b class="button">Rebase and merge</b>}, para.sub_macros(para.source)
1323
- end
1324
-
1325
- test 'btn macro for docbook backend' do
1326
- para = block_from_string('btn:[Save]', :backend => 'docbook', :attributes => {'experimental' => ''})
1327
- assert_equal %q{<guibutton>Save</guibutton>}, para.sub_macros(para.source)
1328
- end
1329
- end
1330
-
1331
- context 'Keyboard macro' do
1332
- test 'kbd macro with single key' do
1333
- para = block_from_string('kbd:[F3]', :attributes => {'experimental' => ''})
1334
- assert_equal %q{<kbd>F3</kbd>}, para.sub_macros(para.source)
1335
- end
1336
-
1337
- test 'kbd macro with single backslash key' do
1338
- para = block_from_string("kbd:[#{BACKSLASH} ]", :attributes => {'experimental' => ''})
1339
- assert_equal %q(<kbd>\</kbd>), para.sub_macros(para.source)
1340
- end
1341
-
1342
- test 'kbd macro with single key, docbook backend' do
1343
- para = block_from_string('kbd:[F3]', :backend => 'docbook', :attributes => {'experimental' => ''})
1344
- assert_equal %q{<keycap>F3</keycap>}, para.sub_macros(para.source)
1345
- end
1346
-
1347
- test 'kbd macro with key combination' do
1348
- para = block_from_string('kbd:[Ctrl+Shift+T]', :attributes => {'experimental' => ''})
1349
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></span>}, para.sub_macros(para.source)
1350
- end
1351
-
1352
- test 'kbd macro with key combination that spans multiple lines' do
1353
- para = block_from_string(%(kbd:[Ctrl +\nT]), :attributes => {'experimental' => ''})
1354
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>T</kbd></span>}, para.sub_macros(para.source)
1355
- end
1356
-
1357
- test 'kbd macro with key combination, docbook backend' do
1358
- para = block_from_string('kbd:[Ctrl+Shift+T]', :backend => 'docbook', :attributes => {'experimental' => ''})
1359
- assert_equal %q{<keycombo><keycap>Ctrl</keycap><keycap>Shift</keycap><keycap>T</keycap></keycombo>}, para.sub_macros(para.source)
1360
- end
1361
-
1362
- test 'kbd macro with key combination delimited by pluses with spaces' do
1363
- para = block_from_string('kbd:[Ctrl + Shift + T]', :attributes => {'experimental' => ''})
1364
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></span>}, para.sub_macros(para.source)
1365
- end
1366
-
1367
- test 'kbd macro with key combination delimited by commas' do
1368
- para = block_from_string('kbd:[Ctrl,Shift,T]', :attributes => {'experimental' => ''})
1369
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></span>}, para.sub_macros(para.source)
1370
- end
1371
-
1372
- test 'kbd macro with key combination delimited by commas with spaces' do
1373
- para = block_from_string('kbd:[Ctrl, Shift, T]', :attributes => {'experimental' => ''})
1374
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>T</kbd></span>}, para.sub_macros(para.source)
1375
- end
1376
-
1377
- test 'kbd macro with key combination delimited by plus containing a comma key' do
1378
- para = block_from_string('kbd:[Ctrl+,]', :attributes => {'experimental' => ''})
1379
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>,</kbd></span>}, para.sub_macros(para.source)
1380
- end
1381
-
1382
- test 'kbd macro with key combination delimited by commas containing a plus key' do
1383
- para = block_from_string('kbd:[Ctrl, +, Shift]', :attributes => {'experimental' => ''})
1384
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>+</kbd>+<kbd>Shift</kbd></span>}, para.sub_macros(para.source)
1385
- end
1386
-
1387
- test 'kbd macro with key combination where last key matches plus delimiter' do
1388
- para = block_from_string('kbd:[Ctrl + +]', :attributes => {'experimental' => ''})
1389
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>+</kbd></span>}, para.sub_macros(para.source)
1390
- end
1391
-
1392
- test 'kbd macro with key combination where last key matches comma delimiter' do
1393
- para = block_from_string('kbd:[Ctrl, ,]', :attributes => {'experimental' => ''})
1394
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>,</kbd></span>}, para.sub_macros(para.source)
1395
- end
1396
-
1397
- test 'kbd macro with key combination containing escaped bracket' do
1398
- para = block_from_string('kbd:[Ctrl + \]]', :attributes => {'experimental' => ''})
1399
- assert_equal %q{<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>]</kbd></span>}, para.sub_macros(para.source)
1400
- end
1401
-
1402
- test 'kbd macro with key combination ending in backslash' do
1403
- para = block_from_string("kbd:[Ctrl + #{BACKSLASH} ]", :attributes => {'experimental' => ''})
1404
- assert_equal %q(<span class="keyseq"><kbd>Ctrl</kbd>+<kbd>\\</kbd></span>), para.sub_macros(para.source)
1405
- end
1406
-
1407
- test 'kbd macro looks for delimiter beyond first character' do
1408
- para = block_from_string('kbd:[,te]', :attributes => {'experimental' => ''})
1409
- assert_equal %q(<kbd>,te</kbd>), para.sub_macros(para.source)
1410
- end
1411
-
1412
- test 'kbd macro restores trailing delimiter as key value' do
1413
- para = block_from_string('kbd:[te,]', :attributes => {'experimental' => ''})
1414
- assert_equal %q(<kbd>te,</kbd>), para.sub_macros(para.source)
1415
- end
1416
- end
1417
-
1418
- context 'Menu macro' do
1419
- test 'should process menu using macro sytnax' do
1420
- para = block_from_string('menu:File[]', :attributes => {'experimental' => ''})
1421
- assert_equal %q{<b class="menuref">File</b>}, para.sub_macros(para.source)
1422
- end
1423
-
1424
- test 'should process menu for docbook backend' do
1425
- para = block_from_string('menu:File[]', :backend => 'docbook', :attributes => {'experimental' => ''})
1426
- assert_equal %q{<guimenu>File</guimenu>}, para.sub_macros(para.source)
1427
- end
1428
-
1429
- test 'should process menu with menu item using macro syntax' do
1430
- para = block_from_string('menu:File[Save As&#8230;]', :attributes => {'experimental' => ''})
1431
- assert_equal %q{<span class="menuseq"><b class="menu">File</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Save As&#8230;</b></span>}, para.sub_macros(para.source)
1432
- end
1433
-
1434
- test 'should process menu macro that spans multiple lines' do
1435
- input = %(menu:Preferences[Compile\non\nSave])
1436
- para = block_from_string input, :attributes => {'experimental' => ''}
1437
- assert_equal %(<span class="menuseq"><b class="menu">Preferences</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Compile\non\nSave</b></span>), para.sub_macros(para.source)
1438
- end
1439
-
1440
- test 'should unescape escaped closing bracket in menu macro' do
1441
- input = 'menu:Preferences[Compile [on\\] Save]'
1442
- para = block_from_string input, :attributes => {'experimental' => ''}
1443
- assert_equal %q(<span class="menuseq"><b class="menu">Preferences</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Compile [on] Save</b></span>), para.sub_macros(para.source)
1444
- end
1445
-
1446
- test 'should process menu with menu item using macro syntax when fonts icons are enabled' do
1447
- para = block_from_string('menu:Tools[More Tools &gt; Extensions]', :attributes => {'experimental' => '', 'icons' => 'font'})
1448
- assert_equal %q{<span class="menuseq"><b class="menu">Tools</b>&#160;<i class="fa fa-angle-right caret"></i> <b class="submenu">More Tools</b>&#160;<i class="fa fa-angle-right caret"></i> <b class="menuitem">Extensions</b></span>}, para.sub_macros(para.source)
1449
- end
1450
-
1451
- test 'should process menu with menu item for docbook backend' do
1452
- para = block_from_string('menu:File[Save As&#8230;]', :backend => 'docbook', :attributes => {'experimental' => ''})
1453
- assert_equal %q{<menuchoice><guimenu>File</guimenu> <guimenuitem>Save As&#8230;</guimenuitem></menuchoice>}, para.sub_macros(para.source)
1454
- end
1455
-
1456
- test 'should process menu with menu item in submenu using macro syntax' do
1457
- para = block_from_string('menu:Tools[Project &gt; Build]', :attributes => {'experimental' => ''})
1458
- assert_equal %q{<span class="menuseq"><b class="menu">Tools</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">Project</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Build</b></span>}, para.sub_macros(para.source)
1459
- end
1460
-
1461
- test 'should process menu with menu item in submenu for docbook backend' do
1462
- para = block_from_string('menu:Tools[Project &gt; Build]', :backend => 'docbook', :attributes => {'experimental' => ''})
1463
- assert_equal %q{<menuchoice><guimenu>Tools</guimenu> <guisubmenu>Project</guisubmenu> <guimenuitem>Build</guimenuitem></menuchoice>}, para.sub_macros(para.source)
1464
- end
1465
-
1466
- test 'should process menu with menu item in submenu using macro syntax and comma delimiter' do
1467
- para = block_from_string('menu:Tools[Project, Build]', :attributes => {'experimental' => ''})
1468
- assert_equal %q{<span class="menuseq"><b class="menu">Tools</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">Project</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Build</b></span>}, para.sub_macros(para.source)
1469
- end
1470
-
1471
- test 'should process menu with menu item using inline syntax' do
1472
- para = block_from_string('"File &gt; Save As&#8230;"', :attributes => {'experimental' => ''})
1473
- assert_equal %q{<span class="menuseq"><b class="menu">File</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Save As&#8230;</b></span>}, para.sub_macros(para.source)
1474
- end
1475
-
1476
- test 'should process menu with menu item in submenu using inline syntax' do
1477
- para = block_from_string('"Tools &gt; Project &gt; Build"', :attributes => {'experimental' => ''})
1478
- assert_equal %q{<span class="menuseq"><b class="menu">Tools</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">Project</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Build</b></span>}, para.sub_macros(para.source)
1479
- end
1480
-
1481
- test 'inline menu syntax should not match closing quote of XML attribute' do
1482
- para = block_from_string('<span class="xmltag">&lt;node&gt;</span><span class="classname">r</span>', :attributes => {'experimental' => ''})
1483
- assert_equal %q{<span class="xmltag">&lt;node&gt;</span><span class="classname">r</span>}, para.sub_macros(para.source)
1484
- end
1485
-
1486
- test 'should process menu macro with items containing multibyte characters' do
1487
- para = block_from_string('menu:视图[放大, 重置]', :attributes => {'experimental' => ''})
1488
- assert_equal %q{<span class="menuseq"><b class="menu">视图</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">放大</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">重置</b></span>}, para.sub_macros(para.source)
1489
- end if ::RUBY_MIN_VERSION_1_9
1490
-
1491
- test 'should process inline menu with items containing multibyte characters' do
1492
- para = block_from_string('"视图 &gt; 放大 &gt; 重置"', :attributes => {'experimental' => ''})
1493
- assert_equal %q{<span class="menuseq"><b class="menu">视图</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">放大</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">重置</b></span>}, para.sub_macros(para.source)
1494
- end if ::RUBY_MIN_VERSION_1_9
1495
-
1496
- test 'should process a menu macro with a target that begins with a character reference' do
1497
- para = block_from_string('menu:&#8942;[More Tools, Extensions]', :attributes => {'experimental' => ''})
1498
- assert_equal %q{<span class="menuseq"><b class="menu">&#8942;</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">More Tools</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Extensions</b></span>}, para.sub_macros(para.source)
1499
- end
1500
-
1501
- test 'should not process a menu macro with a target that ends with a space' do
1502
- input = 'menu:foo [bar] menu:File[Save]'
1503
- para = block_from_string input, :attributes => {'experimental' => ''}
1504
- result = para.sub_macros para.source
1505
- assert_xpath '/span[@class="menuseq"]', result, 1
1506
- assert_xpath '//b[@class="menu"][text()="File"]', result, 1
1507
- end
1508
-
1509
- test 'should process an inline menu that begins with a character reference' do
1510
- para = block_from_string('"&#8942; &gt; More Tools &gt; Extensions"', :attributes => {'experimental' => ''})
1511
- assert_equal %q{<span class="menuseq"><b class="menu">&#8942;</b>&#160;<b class="caret">&#8250;</b> <b class="submenu">More Tools</b>&#160;<b class="caret">&#8250;</b> <b class="menuitem">Extensions</b></span>}, para.sub_macros(para.source)
1512
- end
1513
- end
1514
- end
1515
-
1516
- context 'Passthroughs' do
1517
- test 'collect inline triple plus passthroughs' do
1518
- para = block_from_string('+++<code>inline code</code>+++')
1519
- result = para.extract_passthroughs(para.source)
1520
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1521
- assert_equal 1, para.passthroughs.size
1522
- assert_equal '<code>inline code</code>', para.passthroughs[0][:text]
1523
- assert_empty para.passthroughs[0][:subs]
1524
- end
1525
-
1526
- test 'collect multi-line inline triple plus passthroughs' do
1527
- para = block_from_string("+++<code>inline\ncode</code>+++")
1528
- result = para.extract_passthroughs(para.source)
1529
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1530
- assert_equal 1, para.passthroughs.size
1531
- assert_equal "<code>inline\ncode</code>", para.passthroughs[0][:text]
1532
- assert_empty para.passthroughs[0][:subs]
1533
- end
1534
-
1535
- test 'collect inline double dollar passthroughs' do
1536
- para = block_from_string('$$<code>{code}</code>$$')
1537
- result = para.extract_passthroughs(para.source)
1538
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1539
- assert_equal 1, para.passthroughs.size
1540
- assert_equal '<code>{code}</code>', para.passthroughs[0][:text]
1541
- assert_equal [:specialcharacters], para.passthroughs[0][:subs]
1542
- end
1543
-
1544
- test 'collect inline double plus passthroughs' do
1545
- para = block_from_string('++<code>{code}</code>++')
1546
- result = para.extract_passthroughs(para.source)
1547
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1548
- assert_equal 1, para.passthroughs.size
1549
- assert_equal '<code>{code}</code>', para.passthroughs[0][:text]
1550
- assert_equal [:specialcharacters], para.passthroughs[0][:subs]
1551
- end
1552
-
1553
- test 'should not crash if role on passthrough is enclosed in quotes' do
1554
- %W(
1555
- ['role']#{BACKSLASH}++This++++++++++++
1556
- ['role']#{BACKSLASH}+++++++++This++++++++++++
1557
- ).each do |input|
1558
- para = block_from_string input
1559
- assert_includes para.content, %(<span class="'role'">)
1560
- end
1561
- end
1562
-
1563
- test 'should allow inline double plus passthrough to be escaped using backslash' do
1564
- para = block_from_string("you need to replace `int a = n#{BACKSLASH}++;` with `int a = ++n;`!")
1565
- result = para.apply_subs para.source
1566
- assert_equal 'you need to replace <code>int a = n++;</code> with <code>int a = ++n;</code>!', result
1567
- end
1568
-
1569
- test 'should allow inline double plus passthrough with attributes to be escaped using backslash' do
1570
- para = block_from_string("=[attrs]#{BACKSLASH}#{BACKSLASH}++text++")
1571
- result = para.apply_subs para.source
1572
- assert_equal '=[attrs]++text++', result
1573
- end
1574
-
1575
- test 'collect multi-line inline double dollar passthroughs' do
1576
- para = block_from_string("$$<code>\n{code}\n</code>$$")
1577
- result = para.extract_passthroughs(para.source)
1578
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1579
- assert_equal 1, para.passthroughs.size
1580
- assert_equal "<code>\n{code}\n</code>", para.passthroughs[0][:text]
1581
- assert_equal [:specialcharacters], para.passthroughs[0][:subs]
1582
- end
1583
-
1584
- test 'collect multi-line inline double plus passthroughs' do
1585
- para = block_from_string("++<code>\n{code}\n</code>++")
1586
- result = para.extract_passthroughs(para.source)
1587
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1588
- assert_equal 1, para.passthroughs.size
1589
- assert_equal "<code>\n{code}\n</code>", para.passthroughs[0][:text]
1590
- assert_equal [:specialcharacters], para.passthroughs[0][:subs]
1591
- end
1592
-
1593
- test 'collect passthroughs from inline pass macro' do
1594
- para = block_from_string(%Q{pass:specialcharacters,quotes[<code>['code'\\]</code>]})
1595
- result = para.extract_passthroughs(para.source)
1596
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1597
- assert_equal 1, para.passthroughs.size
1598
- assert_equal %q{<code>['code']</code>}, para.passthroughs[0][:text]
1599
- assert_equal [:specialcharacters, :quotes], para.passthroughs[0][:subs]
1600
- end
1601
-
1602
- test 'collect multi-line passthroughs from inline pass macro' do
1603
- para = block_from_string(%Q{pass:specialcharacters,quotes[<code>['more\ncode'\\]</code>]})
1604
- result = para.extract_passthroughs(para.source)
1605
- assert_equal Asciidoctor::Substitutors::PASS_START + '0' + Asciidoctor::Substitutors::PASS_END, result
1606
- assert_equal 1, para.passthroughs.size
1607
- assert_equal %Q{<code>['more\ncode']</code>}, para.passthroughs[0][:text]
1608
- assert_equal [:specialcharacters, :quotes], para.passthroughs[0][:subs]
1609
- end
1610
-
1611
- test 'should find and replace placeholder duplicated by substitution' do
1612
- input = %q(+first passthrough+ followed by link:$$http://example.com/__u_no_format_me__$$[] with passthrough)
1613
- result = convert_inline_string input
1614
- assert_equal 'first passthrough followed by <a href="http://example.com/__u_no_format_me__" class="bare">http://example.com/__u_no_format_me__</a> with passthrough', result
1615
- end
1616
-
1617
- test 'resolves sub shorthands on inline pass macro' do
1618
- para = block_from_string 'pass:q,a[*<{backend}>*]'
1619
- result = para.extract_passthroughs para.source
1620
- assert_equal 1, para.passthroughs.size
1621
- assert_equal [:quotes, :attributes], para.passthroughs[0][:subs]
1622
- result = para.restore_passthroughs result
1623
- assert_equal '<strong><html5></strong>', result
1624
- end
1625
-
1626
- test 'should not recognize pass macro with invalid subsitution list' do
1627
- [',', '42', 'a,'].each do |subs|
1628
- para = block_from_string %(pass:#{subs}[foobar])
1629
- result = para.extract_passthroughs para.source
1630
- assert_equal %(pass:#{subs}[foobar]), result
1631
- end
1632
- end
1633
-
1634
- test 'should allow content of inline pass macro to be empty' do
1635
- para = block_from_string 'pass:[]'
1636
- result = para.extract_passthroughs para.source
1637
- assert_equal 1, para.passthroughs.size
1638
- assert_equal '', para.restore_passthroughs(result)
1639
- end
1640
-
1641
- # NOTE placeholder is surrounded by text to prevent reader from stripping trailing boundary char (unique to test scenario)
1642
- test 'restore inline passthroughs without subs' do
1643
- para = block_from_string("some #{Asciidoctor::Substitutors::PASS_START}" + '0' + "#{Asciidoctor::Substitutors::PASS_END} to study")
1644
- para.passthroughs[0] = {:text => '<code>inline code</code>', :subs => []}
1645
- result = para.restore_passthroughs(para.source)
1646
- assert_equal "some <code>inline code</code> to study", result
1647
- end
1648
-
1649
- # NOTE placeholder is surrounded by text to prevent reader from stripping trailing boundary char (unique to test scenario)
1650
- test 'restore inline passthroughs with subs' do
1651
- para = block_from_string("some #{Asciidoctor::Substitutors::PASS_START}" + '0' + "#{Asciidoctor::Substitutors::PASS_END} to study in the #{Asciidoctor::Substitutors::PASS_START}" + '1' + "#{Asciidoctor::Substitutors::PASS_END} programming language")
1652
- para.passthroughs[0] = {:text => '<code>{code}</code>', :subs => [:specialcharacters]}
1653
- para.passthroughs[1] = {:text => '{language}', :subs => [:specialcharacters]}
1654
- result = para.restore_passthroughs(para.source)
1655
- assert_equal 'some &lt;code&gt;{code}&lt;/code&gt; to study in the {language} programming language', result
1656
- end
1657
-
1658
- test 'should restore nested passthroughs' do
1659
- result = convert_inline_string %q(+Sometimes you feel pass:q[`mono`].+ Sometimes you +$$don't$$+.)
1660
- assert_equal %q(Sometimes you feel <code>mono</code>. Sometimes you don't.), result
1661
- end
1662
-
1663
- test 'should honor role on double plus passthrough' do
1664
- result = convert_inline_string 'Print the version using [var]++{asciidoctor-version}++.'
1665
- assert_equal 'Print the version using <span class="var">{asciidoctor-version}</span>.', result
1666
- end
1667
-
1668
- test 'complex inline passthrough macro' do
1669
- text_to_escape = %q{[(] <'basic form'> <'logical operator'> <'basic form'> [)]}
1670
- para = block_from_string %($$#{text_to_escape}$$)
1671
- para.extract_passthroughs(para.source)
1672
- assert_equal 1, para.passthroughs.size
1673
- assert_equal text_to_escape, para.passthroughs[0][:text]
1674
-
1675
- text_to_escape_escaped = %q{[(\] <'basic form'> <'logical operator'> <'basic form'> [)\]}
1676
- para = block_from_string %(pass:specialcharacters[#{text_to_escape_escaped}])
1677
- para.extract_passthroughs(para.source)
1678
- assert_equal 1, para.passthroughs.size
1679
- assert_equal text_to_escape, para.passthroughs[0][:text]
1680
- end
1681
-
1682
- test 'inline pass macro with a composite sub' do
1683
- para = block_from_string %(pass:verbatim[<{backend}>])
1684
- assert_equal '&lt;{backend}&gt;', para.content
1685
- end
1686
-
1687
- context 'Math macros' do
1688
- test 'should passthrough text in asciimath macro and surround with AsciiMath delimiters' do
1689
- input = 'asciimath:[x/x={(1,if x!=0),(text{undefined},if x=0):}]'
1690
- para = block_from_string input
1691
- assert_equal '\$x/x={(1,if x!=0),(text{undefined},if x=0):}\$', para.content
1692
- end
1693
-
1694
- test 'should not recognize asciimath macro with no content' do
1695
- input = 'asciimath:[]'
1696
- para = block_from_string input
1697
- assert_equal 'asciimath:[]', para.content
1698
- end
1699
-
1700
- test 'should perform specialcharacters subs on asciimath macro content in html backend by default' do
1701
- input = 'asciimath:[a < b]'
1702
- para = block_from_string input
1703
- assert_equal '\$a &lt; b\$', para.content
1704
- end
1705
-
1706
- test 'should convert contents of asciimath macro to MathML in DocBook output if asciimath gem is available' do
1707
- asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
1708
- input = 'asciimath:[a < b]'
1709
- expected = '<inlineequation><mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>a</mml:mi><mml:mo>&#x003C;</mml:mo><mml:mi>b</mml:mi></mml:math></inlineequation>'
1710
- using_memory_logger do |logger|
1711
- para = block_from_string input, :backend => :docbook
1712
- actual = para.content
1713
- if asciimath_available
1714
- assert_equal expected, actual
1715
- assert_equal :loaded, para.document.converter.instance_variable_get(:@asciimath)
1716
- else
1717
- assert_message logger, :WARN, 'optional gem \'asciimath\' is not installed. Functionality disabled.'
1718
- assert_equal :unavailable, para.document.converter.instance_variable_get(:@asciimath)
1719
- end
1720
- end
1721
- end
1722
-
1723
- test 'should not perform specialcharacters subs on asciimath macro content in Docbook output if asciimath gem not available' do
1724
- asciimath_available = !(Asciidoctor::Helpers.require_library 'asciimath', true, :ignore).nil?
1725
- input = 'asciimath:[a < b]'
1726
- para = block_from_string input, :backend => :docbook
1727
- para.document.converter.instance_variable_set :@asciimath, :unavailable
1728
- if asciimath_available
1729
- old_asciimath = ::AsciiMath
1730
- Object.send :remove_const, 'AsciiMath'
1731
- end
1732
- assert_equal '<inlineequation><mathphrase><![CDATA[a < b]]></mathphrase></inlineequation>', para.content
1733
- ::AsciiMath = old_asciimath if asciimath_available
1734
- end
1735
-
1736
- test 'should honor explicit subslist on asciimath macro' do
1737
- input = 'asciimath:attributes[{expr}]'
1738
- para = block_from_string input, :attributes => {'expr' => 'x != 0'}
1739
- assert_equal '\$x != 0\$', para.content
1740
- end
1741
-
1742
- test 'should passthrough text in latexmath macro and surround with LaTeX math delimiters' do
1743
- input = 'latexmath:[C = \alpha + \beta Y^{\gamma} + \epsilon]'
1744
- para = block_from_string input
1745
- assert_equal '\(C = \alpha + \beta Y^{\gamma} + \epsilon\)', para.content
1746
- end
1747
-
1748
- test 'should not recognize latexmath macro with no content' do
1749
- input = 'latexmath:[]'
1750
- para = block_from_string input
1751
- assert_equal 'latexmath:[]', para.content
1752
- end
1753
-
1754
- test 'should perform specialcharacters subs on latexmath macro in html backend by default' do
1755
- input = 'latexmath:[a < b]'
1756
- para = block_from_string input
1757
- assert_equal '\(a &lt; b\)', para.content
1758
- end
1759
-
1760
- test 'should not perform specialcharacters subs on latexmath macro content in docbook backend by default' do
1761
- input = 'latexmath:[a < b]'
1762
- para = block_from_string input, :backend => :docbook
1763
- assert_equal '<inlineequation><alt><![CDATA[a < b]]></alt><mathphrase><![CDATA[a < b]]></mathphrase></inlineequation>', para.content
1764
- end
1765
-
1766
- test 'should honor explicit subslist on latexmath macro' do
1767
- input = 'latexmath:attributes[{expr}]'
1768
- para = block_from_string input, :attributes => {'expr' => '\sqrt{4} = 2'}
1769
- assert_equal '\(\sqrt{4} = 2\)', para.content
1770
- end
1771
-
1772
- test 'should passthrough math macro inside another passthrough' do
1773
- input = 'the text `asciimath:[x = y]` should be passed through as +literal+ text'
1774
- para = block_from_string input, :attributes => {'compat-mode' => ''}
1775
- assert_equal 'the text <code>asciimath:[x = y]</code> should be passed through as <code>literal</code> text', para.content
1776
-
1777
- input = 'the text [x-]`asciimath:[x = y]` should be passed through as `literal` text'
1778
- para = block_from_string input
1779
- assert_equal 'the text <code>asciimath:[x = y]</code> should be passed through as <code>literal</code> text', para.content
1780
-
1781
- input = 'the text `+asciimath:[x = y]+` should be passed through as `literal` text'
1782
- para = block_from_string input
1783
- assert_equal 'the text <code>asciimath:[x = y]</code> should be passed through as <code>literal</code> text', para.content
1784
- end
1785
-
1786
- test 'should not process an escaped passthrough macro inside a monospaced phrase' do
1787
- input = 'use the `\pass:c[]` macro'
1788
- para = block_from_string input
1789
- assert_equal 'use the <code>pass:c[]</code> macro', para.content
1790
- end
1791
-
1792
- test 'should not process an escaped passthrough macro inside a monospaced phrase with attributes' do
1793
- input = 'use the [syntax]`\pass:c[]` macro'
1794
- para = block_from_string input
1795
- assert_equal 'use the <code class="syntax">pass:c[]</code> macro', para.content
1796
- end
1797
-
1798
- test 'should honor an escaped single plus passthrough inside a monospaced phrase' do
1799
- input = 'use `\+{author}+` to show an attribute reference'
1800
- para = block_from_string input
1801
- assert_equal 'use <code>+{author}+</code> to show an attribute reference', para.content
1802
- end
1803
-
1804
- test 'should not recognize stem macro with no content' do
1805
- input = 'stem:[]'
1806
- para = block_from_string input
1807
- assert_equal input, para.content
1808
- end
1809
-
1810
- test 'should passthrough text in stem macro and surround with AsciiMath delimiters if stem attribute is asciimath, empty, or not set' do
1811
- [
1812
- {},
1813
- {'stem' => ''},
1814
- {'stem' => 'asciimath'},
1815
- {'stem' => 'bogus'}
1816
- ].each do |attributes|
1817
- input = 'stem:[x/x={(1,if x!=0),(text{undefined},if x=0):}]'
1818
- para = block_from_string input, :attributes => attributes
1819
- assert_equal '\$x/x={(1,if x!=0),(text{undefined},if x=0):}\$', para.content
1820
- end
1821
- end
1822
-
1823
- test 'should passthrough text in stem macro and surround with LaTeX math delimiters if stem attribute is latexmath, latex, or tex' do
1824
- [
1825
- {'stem' => 'latexmath'},
1826
- {'stem' => 'latex'},
1827
- {'stem' => 'tex'}
1828
- ].each do |attributes|
1829
- input = 'stem:[C = \alpha + \beta Y^{\gamma} + \epsilon]'
1830
- para = block_from_string input, :attributes => attributes
1831
- assert_equal '\(C = \alpha + \beta Y^{\gamma} + \epsilon\)', para.content
1832
- end
1833
- end
1834
-
1835
- test 'should apply substitutions specified on stem macro' do
1836
- input = 'stem:c,a[sqrt(x) <=> {solve-for-x}]'
1837
- para = block_from_string input, :attributes => {'stem' => 'asciimath', 'solve-for-x' => '13'}
1838
- assert_equal '\$sqrt(x) &lt;=&gt; 13\$', para.content
1839
- end
1840
-
1841
- test 'should not recognize stem macro with invalid substitution list' do
1842
- [',', '42', 'a,'].each do |subs|
1843
- input = %(stem:#{subs}[x^2])
1844
- para = block_from_string input, :attributes => {'stem' => 'asciimath'}
1845
- assert_equal %(stem:#{subs}[x^2]), para.content
1846
- end
1847
- end
1848
- end
1849
- end
1850
-
1851
- context 'Replacements' do
1852
- test 'unescapes XML entities' do
1853
- para = block_from_string '< &quot; &there4; &#34; &#x22; >'
1854
- assert_equal '&lt; &quot; &there4; &#34; &#x22; &gt;', para.apply_subs(para.source)
1855
- end
1856
-
1857
- test 'replaces arrows' do
1858
- para = block_from_string '<- -> <= => \<- \-> \<= \=>'
1859
- assert_equal '&#8592; &#8594; &#8656; &#8658; &lt;- -&gt; &lt;= =&gt;', para.apply_subs(para.source)
1860
- end
1861
-
1862
- test 'replaces dashes' do
1863
- para = block_from_string %(-- foo foo--bar foo\\--bar foo -- bar foo \\-- bar
1864
- stuff in between
1865
- -- foo
1866
- stuff in between
1867
- foo --
1868
- stuff in between
1869
- foo --)
1870
- expected = '&#8201;&#8212;&#8201;foo foo&#8212;&#8203;bar foo--bar foo&#8201;&#8212;&#8201;bar foo -- bar
1871
- stuff in between&#8201;&#8212;&#8201;foo
1872
- stuff in between
1873
- foo&#8201;&#8212;&#8201;stuff in between
1874
- foo&#8201;&#8212;&#8201;'
1875
- assert_equal expected, para.sub_replacements(para.source)
1876
- end
1877
-
1878
- test 'replaces dashes between multibyte word characters' do
1879
- para = block_from_string %(富--巴)
1880
- expected = '富&#8212;&#8203;巴'
1881
- assert_equal expected, para.sub_replacements(para.source)
1882
- end if ::RUBY_MIN_VERSION_1_9
1883
-
1884
- test 'replaces marks' do
1885
- para = block_from_string '(C) (R) (TM) \(C) \(R) \(TM)'
1886
- assert_equal '&#169; &#174; &#8482; (C) (R) (TM)', para.sub_replacements(para.source)
1887
- end
1888
-
1889
- test 'preserves entity references' do
1890
- input = '&amp; &#169; &#10004; &#128512; &#x2022; &#x1f600;'
1891
- result = convert_inline_string input
1892
- assert_equal input, result
1893
- end
1894
-
1895
- test 'only preserves named entities with two or more letters' do
1896
- input = '&amp; &a; &gt;'
1897
- result = convert_inline_string input
1898
- assert_equal '&amp; &amp;a; &gt;', result
1899
- end
1900
-
1901
- test 'replaces punctuation' do
1902
- para = block_from_string %(John's Hideout is the Whites`' place... foo\\'bar)
1903
- assert_equal "John&#8217;s Hideout is the Whites&#8217; place&#8230;&#8203; foo'bar", para.sub_replacements(para.source)
1904
- end
1905
-
1906
- test 'should replace right single quote marks' do
1907
- given = [
1908
- %(`'Twas the night),
1909
- %(a `'57 Chevy!),
1910
- %(the whites`' place),
1911
- %(the whites`'.),
1912
- %(the whites`'--where the wild things are),
1913
- %(the whites`'\nhave),
1914
- %(It's Mary`'s little lamb.),
1915
- %(consecutive single quotes '' are not modified),
1916
- %(he is 6' tall),
1917
- %(\\`')
1918
- ]
1919
- expected = [
1920
- %(&#8217;Twas the night),
1921
- %(a &#8217;57 Chevy!),
1922
- %(the whites&#8217; place),
1923
- %(the whites&#8217;.),
1924
- %(the whites&#8217;--where the wild things are),
1925
- %(the whites&#8217;\nhave),
1926
- %(It&#8217;s Mary&#8217;s little lamb.),
1927
- %(consecutive single quotes '' are not modified),
1928
- %(he is 6' tall),
1929
- %(`')
1930
- ]
1931
- given.size.times {|i|
1932
- para = block_from_string given[i]
1933
- assert_equal expected[i], para.sub_replacements(para.source)
1934
- }
1935
- end
1936
- end
1937
-
1938
- context 'Post replacements' do
1939
- test 'line break inserted after line with line break character' do
1940
- para = block_from_string("First line +\nSecond line")
1941
- result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
1942
- assert_equal 'First line<br>', result.first
1943
- end
1944
-
1945
- test 'line break inserted after line wrap with hardbreaks enabled' do
1946
- para = block_from_string("First line\nSecond line", :attributes => {'hardbreaks' => ''})
1947
- result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
1948
- assert_equal 'First line<br>', result.first
1949
- end
1950
-
1951
- test 'line break character stripped from end of line with hardbreaks enabled' do
1952
- para = block_from_string("First line +\nSecond line", :attributes => {'hardbreaks' => ''})
1953
- result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
1954
- assert_equal 'First line<br>', result.first
1955
- end
1956
-
1957
- test 'line break not inserted for single line with hardbreaks enabled' do
1958
- para = block_from_string('First line', :attributes => {'hardbreaks' => ''})
1959
- result = para.apply_subs para.lines, (para.expand_subs :post_replacements)
1960
- assert_equal 'First line', result.first
1961
- end
1962
- end
1963
-
1964
- context 'Resolve subs' do
1965
- test 'should resolve subs for block' do
1966
- block = Asciidoctor::Block.new(empty_document, :paragraph)
1967
- block.attributes['subs'] = 'quotes,normal'
1968
- block.lock_in_subs
1969
- assert_equal [:quotes, :specialcharacters, :attributes, :replacements, :macros, :post_replacements], block.subs
1970
- end
1971
-
1972
- test 'should resolve specialcharacters sub as highlight for source block when source highlighter is coderay' do
1973
- doc = empty_document :attributes => {'source-highlighter' => 'coderay'}
1974
- block = Asciidoctor::Block.new(doc, :listing, :content_model => :verbatim)
1975
- block.style = 'source'
1976
- block.attributes['subs'] = 'specialcharacters'
1977
- block.attributes['language'] = 'ruby'
1978
- block.lock_in_subs
1979
- assert_equal [:highlight], block.subs
1980
- end
1981
-
1982
- test 'should resolve specialcharacters sub as highlight for source block when source highlighter is pygments' do
1983
- doc = empty_document :attributes => {'source-highlighter' => 'pygments'}
1984
- block = Asciidoctor::Block.new(doc, :listing, :content_model => :verbatim)
1985
- block.style = 'source'
1986
- block.attributes['subs'] = 'specialcharacters'
1987
- block.attributes['language'] = 'ruby'
1988
- block.lock_in_subs
1989
- assert_equal [:highlight], block.subs
1990
- end
1991
-
1992
- test 'should not resolve specialcharacters sub as highlight for source block when source highlighter is not set' do
1993
- doc = empty_document
1994
- block = Asciidoctor::Block.new(doc, :listing, :content_model => :verbatim)
1995
- block.style = 'source'
1996
- block.attributes['subs'] = 'specialcharacters'
1997
- block.attributes['language'] = 'ruby'
1998
- block.lock_in_subs
1999
- assert_equal [:specialcharacters], block.subs
2000
- end
2001
-
2002
- test 'should not use subs if subs option passed to block constructor is nil' do
2003
- doc = empty_document
2004
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :subs => nil, :attributes => {'subs' => 'quotes'}
2005
- assert_empty block.subs
2006
- block.lock_in_subs
2007
- assert_empty block.subs
2008
- end
2009
-
2010
- test 'should not use subs if subs option passed to block constructor is empty array' do
2011
- doc = empty_document
2012
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :subs => [], :attributes => {'subs' => 'quotes'}
2013
- assert_empty block.subs
2014
- block.lock_in_subs
2015
- assert_empty block.subs
2016
- end
2017
-
2018
- test 'should use subs from subs option passed to block constructor' do
2019
- doc = empty_document
2020
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :subs => [:specialcharacters], :attributes => {'subs' => 'quotes'}
2021
- assert_equal [:specialcharacters], block.subs
2022
- block.lock_in_subs
2023
- assert_equal [:specialcharacters], block.subs
2024
- end
2025
-
2026
- test 'should use subs from subs attribute if subs option is not passed to block constructor' do
2027
- doc = empty_document
2028
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :attributes => {'subs' => 'quotes'}
2029
- assert_empty block.subs
2030
- # in this case, we have to call lock_in_subs to resolve the subs
2031
- block.lock_in_subs
2032
- assert_equal [:quotes], block.subs
2033
- end
2034
-
2035
- test 'should use subs from subs attribute if subs option passed to block constructor is :default' do
2036
- doc = empty_document
2037
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :subs => :default, :attributes => {'subs' => 'quotes'}
2038
- assert_equal [:quotes], block.subs
2039
- block.lock_in_subs
2040
- assert_equal [:quotes], block.subs
2041
- end
2042
-
2043
- test 'should use built-in subs if subs option passed to block constructor is :default and subs attribute is absent' do
2044
- doc = empty_document
2045
- block = Asciidoctor::Block.new doc, :paragraph, :source => '*bold* _italic_', :subs => :default
2046
- assert_equal [:specialcharacters, :quotes, :attributes, :replacements, :macros, :post_replacements], block.subs
2047
- block.lock_in_subs
2048
- assert_equal [:specialcharacters, :quotes, :attributes, :replacements, :macros, :post_replacements], block.subs
2049
- end
2050
- end
2051
-
2052
- # TODO move to helpers_test.rb
2053
- context 'Helpers' do
2054
- test 'should URI encode non-word characters generally' do
2055
- given = ' /%&?\\'
2056
- expect = '%20%2F%25%26%3F%5C'
2057
- assert_equal expect, (Asciidoctor::Helpers.uri_encode given)
2058
- end
2059
-
2060
- test 'should not URI select non-word characters' do
2061
- given = '-.!~*\';:@=+$,()[]'
2062
- expect = given
2063
- assert_equal expect, (Asciidoctor::Helpers.uri_encode given)
2064
- end
2065
- end
2066
- end