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,447 +0,0 @@
1
- # encoding: UTF-8
2
- ASCIIDOCTOR_TEST_DIR = File.expand_path File.dirname __FILE__
3
- ASCIIDOCTOR_PROJECT_DIR = File.dirname ASCIIDOCTOR_TEST_DIR
4
- ASCIIDOCTOR_LIB_DIR = ENV['ASCIIDOCTOR_LIB_DIR'] || File.join(ASCIIDOCTOR_PROJECT_DIR, 'lib')
5
- Dir.chdir ASCIIDOCTOR_PROJECT_DIR
6
-
7
- if RUBY_VERSION < '1.9'
8
- require 'rubygems'
9
- end
10
-
11
- require 'simplecov' if ENV['COVERAGE'] == 'true'
12
-
13
- require File.join(ASCIIDOCTOR_LIB_DIR, 'asciidoctor')
14
-
15
- require 'socket'
16
- require 'nokogiri'
17
- require 'tempfile'
18
- require 'tmpdir'
19
-
20
- autoload :FileUtils, 'fileutils'
21
- autoload :Pathname, 'pathname'
22
- autoload :Open3, 'open3'
23
-
24
- RE_XMLNS_ATTRIBUTE = / xmlns="[^"]+"/
25
- RE_DOCTYPE = /\s*<!DOCTYPE (.*)/
26
-
27
- require 'minitest/autorun'
28
-
29
- # Minitest 4 doesn't have Minitest::Test
30
- Minitest::Test = MiniTest::Unit::TestCase unless defined? Minitest::Test
31
-
32
- class Minitest::Test
33
- def windows?
34
- RbConfig::CONFIG['host_os'] =~ /win|ming/
35
- end
36
-
37
- def disk_root
38
- %(#{windows? ? ASCIIDOCTOR_PROJECT_DIR.split('/')[0] : ''}/)
39
- end
40
-
41
- def empty_document options = {}
42
- if options[:parse]
43
- (Asciidoctor::Document.new [], options).parse
44
- else
45
- Asciidoctor::Document.new [], options
46
- end
47
- end
48
-
49
- def empty_safe_document options = {}
50
- options[:safe] = :safe
51
- Asciidoctor::Document.new [], options
52
- end
53
-
54
- def sample_doc_path(name)
55
- name = name.to_s
56
- unless name.include?('.')
57
- ['asciidoc', 'txt'].each do |ext|
58
- if File.exist?(fixture_path("#{name}.#{ext}"))
59
- name = "#{name}.#{ext}"
60
- break
61
- end
62
- end
63
- end
64
- fixture_path(name)
65
- end
66
-
67
- def testdir
68
- ASCIIDOCTOR_TEST_DIR
69
- end
70
-
71
- def fixturedir
72
- File.join testdir, 'fixtures'
73
- end
74
-
75
- def fixture_path name
76
- File.join fixturedir, name
77
- end
78
-
79
- def example_document(name, opts = {})
80
- document_from_string IO.read(sample_doc_path(name)), opts
81
- end
82
-
83
- def xmlnodes_at_css(css, content, count = nil)
84
- xmlnodes_at_path(:css, css, content, count)
85
- end
86
-
87
- def xmlnodes_at_xpath(xpath, content, count = nil)
88
- xmlnodes_at_path(:xpath, xpath, content, count)
89
- end
90
-
91
- def xmlnodes_at_path(type, path, content, count = nil)
92
- doc = xmldoc_from_string content
93
- case type
94
- when :xpath
95
- namespaces = doc.respond_to?(:root) ? doc.root.namespaces : {}
96
- results = doc.xpath("#{path.sub('/', './')}", namespaces)
97
- when :css
98
- results = doc.css(path)
99
- end
100
- count == 1 ? results.first : results
101
- end
102
-
103
- # Generate an xpath attribute matcher that matches a name in the class attribute
104
- def contains_class(name)
105
- %(contains(concat(' ', normalize-space(@class), ' '), ' #{name} '))
106
- end
107
-
108
- def assert_css(css, content, count = nil)
109
- assert_path(:css, css, content, count)
110
- end
111
-
112
- def assert_xpath(xpath, content, count = nil)
113
- assert_path(:xpath, xpath, content, count)
114
- end
115
-
116
- def assert_path(type, path, content, count = nil)
117
- case type
118
- when :xpath
119
- type_name = 'XPath'
120
- when :css
121
- type_name = 'CSS'
122
- end
123
-
124
- results = xmlnodes_at_path type, path, content
125
-
126
- if (count == true || count == false)
127
- if (count != results)
128
- flunk "#{type_name} #{path} yielded #{results} rather than #{count} for:\n#{content}"
129
- else
130
- assert true
131
- end
132
- elsif (count && results.size != count)
133
- flunk "#{type_name} #{path} yielded #{results.size} elements rather than #{count} for:\n#{content}"
134
- elsif (count.nil? && results.empty?)
135
- flunk "#{type_name} #{path} not found in:\n#{content}"
136
- else
137
- assert true
138
- end
139
- end
140
-
141
- def assert_message logger, severity, expected_message, kind = String, idx = nil
142
- unless idx
143
- assert_equal 1, logger.messages.size
144
- idx = 0
145
- end
146
- message = logger.messages[idx]
147
- assert_equal severity, message[:severity]
148
- assert_kind_of kind, message[:message]
149
- if kind == String
150
- actual_message = message[:message]
151
- else
152
- refute_nil message[:message][:source_location]
153
- actual_message = message[:message].inspect
154
- end
155
- if expected_message.start_with? '~'
156
- assert_includes actual_message, expected_message[1..-1]
157
- else
158
- assert_equal expected_message, actual_message
159
- end
160
- end
161
-
162
- def assert_messages logger, expected_messages
163
- assert_equal expected_messages.size, logger.messages.size
164
- expected_messages.each_with_index do |expected_message_details, idx|
165
- severity, expected_message, kind = expected_message_details
166
- assert_message logger, severity, expected_message, (kind || String), idx
167
- end
168
- end
169
-
170
- def xmldoc_from_string(content)
171
- if content.match(RE_XMLNS_ATTRIBUTE)
172
- Nokogiri::XML::Document.parse(content)
173
- elsif !(doctype_match = content.match(RE_DOCTYPE))
174
- Nokogiri::HTML::DocumentFragment.parse(content)
175
- elsif doctype_match[1].start_with? 'html'
176
- Nokogiri::HTML::Document.parse(content)
177
- else
178
- Nokogiri::XML::Document.parse(content)
179
- end
180
- end
181
-
182
- def document_from_string(src, opts = {})
183
- assign_default_test_options opts
184
- if opts[:parse]
185
- (Asciidoctor::Document.new src.lines.entries, opts).parse
186
- else
187
- Asciidoctor::Document.new src.lines.entries, opts
188
- end
189
- end
190
-
191
- def block_from_string(src, opts = {})
192
- opts[:header_footer] = false
193
- doc = document_from_string src, opts
194
- doc.blocks.first
195
- end
196
-
197
- def convert_string(src, opts = {})
198
- keep_namespaces = opts.delete(:keep_namespaces)
199
- if keep_namespaces
200
- document_from_string(src, opts).convert
201
- else
202
- # this is required because nokogiri is ignorant
203
- result = document_from_string(src, opts).convert
204
- result = result.sub(RE_XMLNS_ATTRIBUTE, '') if result
205
- result
206
- end
207
- end
208
-
209
- def convert_string_to_embedded(src, opts = {})
210
- opts[:header_footer] = false
211
- document_from_string(src, opts).convert
212
- end
213
-
214
- def convert_inline_string(src, opts = {})
215
- opts[:doctype] = :inline
216
- document_from_string(src, opts).convert
217
- end
218
-
219
- def parse_header_metadata(source, doc = nil)
220
- reader = Asciidoctor::Reader.new source.split ::Asciidoctor::LF
221
- [::Asciidoctor::Parser.parse_header_metadata(reader, doc), reader]
222
- end
223
-
224
- def assign_default_test_options(opts)
225
- opts[:header_footer] = true unless opts.key? :header_footer
226
- opts[:parse] = true unless opts.key? :parse
227
- if opts[:header_footer]
228
- # don't embed stylesheet unless test requests the default behavior
229
- if opts.has_key? :linkcss_default
230
- opts.delete(:linkcss_default)
231
- else
232
- opts[:attributes] ||= {}
233
- opts[:attributes]['linkcss'] = ''
234
- end
235
- end
236
- if (template_dir = ENV['TEMPLATE_DIR'])
237
- opts[:template_dir] = template_dir unless opts.has_key? :template_dir
238
- end
239
- nil
240
- end
241
-
242
- # Decode the numeric character reference, such as 8212, to a Unicode glyph
243
- # so it may be used in an XPath expression.
244
- #
245
- # Examples
246
- #
247
- # decode_char 60
248
- # # => "<"
249
- #
250
- # Returns the decoded String that corresponds to the numeric character reference
251
- def decode_char number
252
- [number].pack 'U1'
253
- end
254
-
255
- def invoke_cli_with_filenames(argv = [], filenames = [], &block)
256
- filepaths = Array.new
257
-
258
- filenames.each {|filename|
259
- if filenames.nil? || ::Pathname.new(filename).absolute?
260
- filepaths << filename
261
- else
262
- filepaths << (fixture_path filename)
263
- end
264
- }
265
-
266
- invoker = Asciidoctor::Cli::Invoker.new(argv + filepaths)
267
-
268
- invoker.invoke!(&block)
269
- invoker
270
- end
271
-
272
- def invoke_cli_to_buffer(argv = [], filename = 'sample.asciidoc', &block)
273
- invoke_cli(argv, filename, [StringIO.new, StringIO.new], &block)
274
- end
275
-
276
- def invoke_cli(argv = [], filename = 'sample.asciidoc', buffers = nil, &block)
277
- if filename.nil? || filename == '-' || ::Pathname.new(filename).absolute?
278
- filepath = filename
279
- else
280
- filepath = fixture_path filename
281
- end
282
- invoker = Asciidoctor::Cli::Invoker.new(argv + [filepath])
283
- if buffers
284
- invoker.redirect_streams(*buffers)
285
- end
286
- invoker.invoke!(&block)
287
- invoker
288
- end
289
-
290
- def redirect_streams
291
- old_stdout, $stdout = $stdout, (tmp_stdout = ::StringIO.new)
292
- old_stderr, $stderr = $stderr, (tmp_stderr = ::StringIO.new)
293
- old_logger = Asciidoctor::LoggerManager.logger
294
- old_logger_level = old_logger.level
295
- new_logger = (Asciidoctor::LoggerManager.logger = Asciidoctor::Logger.new $stderr)
296
- new_logger.level = old_logger_level
297
- yield tmp_stdout, tmp_stderr
298
- ensure
299
- $stdout, $stderr = old_stdout, old_stderr
300
- Asciidoctor::LoggerManager.logger = old_logger
301
- end
302
-
303
- def resolve_localhost
304
- (RUBY_VERSION < '1.9' || RUBY_ENGINE == 'rbx') ? Socket.gethostname :
305
- Socket.ip_address_list.find {|addr| addr.ipv4? }.ip_address
306
- end
307
-
308
- def using_memory_logger
309
- old_logger = Asciidoctor::LoggerManager.logger
310
- memory_logger = Asciidoctor::MemoryLogger.new
311
- begin
312
- Asciidoctor::LoggerManager.logger = memory_logger
313
- yield memory_logger
314
- ensure
315
- Asciidoctor::LoggerManager.logger = old_logger
316
- end
317
- end
318
-
319
- def in_verbose_mode
320
- begin
321
- old_verbose, $VERBOSE = $VERBOSE, true
322
- yield
323
- ensure
324
- $VERBOSE = old_verbose
325
- end
326
- end
327
-
328
- def using_test_webserver host = resolve_localhost, port = 9876
329
- server = TCPServer.new host, port
330
- base_dir = testdir
331
- t = Thread.new do
332
- while (session = server.accept)
333
- request = session.gets
334
- resource = nil
335
- if (m = /GET (\S+) HTTP\/1\.1$/.match(request.chomp))
336
- resource = (resource = m[1]) == '' ? '.' : resource
337
- else
338
- session.print %(HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\n)
339
- session.print %(405 - Method not allowed\n)
340
- session.close
341
- break
342
- end
343
-
344
- if resource == '/name/asciidoctor'
345
- session.print %(HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n)
346
- session.print %({"name": "asciidoctor"}\n)
347
- elsif File.file?(resource_file = (File.join base_dir, resource))
348
- mimetype = if (ext = ::File.extname(resource_file)[1..-1])
349
- ext == 'adoc' ? 'text/plain' : %(image/#{ext})
350
- else
351
- 'text/plain'
352
- end
353
- session.print %(HTTP/1.1 200 OK\r\nContent-Type: #{mimetype}\r\n\r\n)
354
- File.open resource_file, 'rb' do |fd|
355
- until fd.eof? do
356
- buffer = fd.read 256
357
- session.write buffer
358
- end
359
- end
360
- else
361
- session.print %(HTTP/1.1 404 File Not Found\r\nContent-Type: text/plain\r\n\r\n)
362
- session.print %(404 - Resource not found.\n)
363
- end
364
- session.close
365
- end
366
- end
367
- begin
368
- yield
369
- ensure
370
- begin
371
- server.shutdown
372
- # "Errno::ENOTCONN: Socket is not connected' is reported on some platforms; call #close instead of #shutdown
373
- rescue Errno::ENOTCONN
374
- server.close
375
- end
376
- t.exit
377
- end
378
- end
379
- end
380
-
381
- ###
382
- #
383
- # Context goodness provided by @citrusbyte's contest.
384
- # See https://github.com/citrusbyte/contest
385
- #
386
- ###
387
-
388
- # Contest adds +teardown+, +test+ and +context+ as class methods, and the
389
- # instance methods +setup+ and +teardown+ now iterate on the corresponding
390
- # blocks. Note that all setup and teardown blocks must be defined with the
391
- # block syntax. Adding setup or teardown instance methods defeats the purpose
392
- # of this library.
393
- class Minitest::Test
394
- def self.setup(&block)
395
- define_method :setup do
396
- super(&block)
397
- instance_eval(&block)
398
- end
399
- end
400
-
401
- def self.teardown(&block)
402
- define_method :teardown do
403
- instance_eval(&block)
404
- super(&block)
405
- end
406
- end
407
-
408
- def self.context(*name, &block)
409
- subclass = Class.new(self)
410
- remove_tests(subclass)
411
- subclass.class_eval(&block) if block_given?
412
- const_set(context_name(name.join(" ")), subclass)
413
- end
414
-
415
- def self.test(name, &block)
416
- define_method(test_name(name), &block)
417
- end
418
-
419
- class << self
420
- alias_method :should, :test
421
- alias_method :describe, :context
422
- end
423
-
424
- private
425
-
426
- def self.context_name(name)
427
- "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym
428
- end
429
-
430
- def self.test_name(name)
431
- "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym
432
- end
433
-
434
- def self.sanitize_name(name)
435
- name.gsub(/\W+/, ' ').strip
436
- end
437
-
438
- def self.remove_tests(subclass)
439
- subclass.public_instance_methods.grep(/^test_/).each do |meth|
440
- subclass.send(:undef_method, meth.to_sym)
441
- end
442
- end
443
- end
444
-
445
- def context(*name, &block)
446
- Minitest::Test.context(name, &block)
447
- end
@@ -1,309 +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
- context "Text" do
8
- test "proper encoding to handle utf8 characters in document using html backend" do
9
- output = example_document(:encoding).convert
10
- assert_xpath '//p', output, 4
11
- assert_xpath '//a', output, 1
12
- end
13
-
14
- test "proper encoding to handle utf8 characters in embedded document using html backend" do
15
- output = example_document(:encoding, :header_footer => false).convert
16
- assert_xpath '//p', output, 4
17
- assert_xpath '//a', output, 1
18
- end
19
-
20
- test "proper encoding to handle utf8 characters in document using docbook45 backend" do
21
- output = example_document(:encoding, :attributes => {'backend' => 'docbook45', 'xmlns' => ''}).convert
22
- assert_xpath '//xmlns:simpara', output, 4
23
- assert_xpath '//xmlns:ulink', output, 1
24
- end
25
-
26
- test "proper encoding to handle utf8 characters in embedded document using docbook45 backend" do
27
- output = example_document(:encoding, :header_footer => false, :attributes => {'backend' => 'docbook45'}).convert
28
- assert_xpath '//simpara', output, 4
29
- assert_xpath '//ulink', output, 1
30
- end
31
-
32
- # NOTE this test ensures we have the encoding line on block templates too
33
- test 'proper encoding to handle utf8 characters in arbitrary block' do
34
- input = []
35
- input << "[verse]\n"
36
- input.concat(File.readlines(sample_doc_path(:encoding)))
37
- doc = empty_document
38
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
39
- block = Asciidoctor::Parser.next_block(reader, doc)
40
- assert_xpath '//pre', block.convert.gsub(/^\s*\n/, ''), 1
41
- end
42
-
43
- test 'proper encoding to handle utf8 characters from included file' do
44
- input = <<-EOS
45
- include::fixtures/encoding.asciidoc[tags=romé]
46
- EOS
47
- doc = empty_safe_document :base_dir => testdir
48
- reader = Asciidoctor::PreprocessorReader.new doc, input, nil, :normalize => true
49
- block = Asciidoctor::Parser.next_block(reader, doc)
50
- output = block.convert
51
- assert_css '.paragraph', output, 1
52
- end
53
-
54
- test 'escaped text markup' do
55
- assert_match(/All your &lt;em&gt;inline&lt;\/em&gt; markup belongs to &lt;strong&gt;us&lt;\/strong&gt;!/,
56
- convert_string('All your <em>inline</em> markup belongs to <strong>us</strong>!'))
57
- end
58
-
59
- test "line breaks" do
60
- assert_xpath "//br", convert_string("Well this is +\njust fine and dandy, isn't it?"), 1
61
- end
62
-
63
- test 'single- and double-quoted text' do
64
- output = convert_string_to_embedded(%q(``Where?,'' she said, flipping through her copy of `The New Yorker.'), :attributes => {'compat-mode' => ''})
65
- assert_match(/&#8220;Where\?,&#8221;/, output)
66
- assert_match(/&#8216;The New Yorker.&#8217;/, output)
67
-
68
- output = convert_string_to_embedded(%q("`Where?,`" she said, flipping through her copy of '`The New Yorker.`'))
69
- assert_match(/&#8220;Where\?,&#8221;/, output)
70
- assert_match(/&#8216;The New Yorker.&#8217;/, output)
71
- end
72
-
73
- test 'multiple double-quoted text on a single line' do
74
- assert_equal '&#8220;Our business is constantly changing&#8221; or &#8220;We need faster time to market.&#8221;',
75
- convert_inline_string(%q(``Our business is constantly changing'' or ``We need faster time to market.''), :attributes => {'compat-mode' => ''})
76
- assert_equal '&#8220;Our business is constantly changing&#8221; or &#8220;We need faster time to market.&#8221;',
77
- convert_inline_string(%q("`Our business is constantly changing`" or "`We need faster time to market.`"))
78
- end
79
-
80
- test 'horizontal rule' do
81
- input = <<-EOS
82
- This line is separated by a horizontal rule...
83
-
84
- '''
85
-
86
- ...from this line.
87
- EOS
88
- output = convert_string_to_embedded input
89
- assert_xpath "//hr", output, 1
90
- assert_xpath "/*[@class='paragraph']", output, 2
91
- assert_xpath "(/*[@class='paragraph'])[1]/following-sibling::hr", output, 1
92
- assert_xpath "/hr/following-sibling::*[@class='paragraph']", output, 1
93
- end
94
-
95
- test 'markdown horizontal rules' do
96
- variants = [
97
- '---',
98
- '- - -',
99
- '***',
100
- '* * *',
101
- '___',
102
- '_ _ _'
103
- ]
104
-
105
- offsets = [
106
- '',
107
- ' ',
108
- ' ',
109
- ' '
110
- ]
111
-
112
- variants.each do |variant|
113
- offsets.each do |offset|
114
- input = <<-EOS
115
- This line is separated by a horizontal rule...
116
-
117
- #{offset}#{variant}
118
-
119
- ...from this line.
120
- EOS
121
- output = convert_string_to_embedded input
122
- assert_xpath "//hr", output, 1
123
- assert_xpath "/*[@class='paragraph']", output, 2
124
- assert_xpath "(/*[@class='paragraph'])[1]/following-sibling::hr", output, 1
125
- assert_xpath "/hr/following-sibling::*[@class='paragraph']", output, 1
126
- end
127
- end
128
- end
129
-
130
- test 'markdown horizontal rules negative case' do
131
-
132
- bad_variants = [
133
- '- - - -',
134
- '* * * *',
135
- '_ _ _ _'
136
- ]
137
-
138
- good_offsets = [
139
- '',
140
- ' ',
141
- ' ',
142
- ' '
143
- ]
144
-
145
- bad_variants.each do |variant|
146
- good_offsets.each do |offset|
147
- input = <<-EOS
148
- This line is separated by something that is not a horizontal rule...
149
-
150
- #{offset}#{variant}
151
-
152
- ...from this line.
153
- EOS
154
- output = convert_string_to_embedded input
155
- assert_xpath '//hr', output, 0
156
- end
157
- end
158
-
159
- good_variants = [
160
- '- - -',
161
- '* * *',
162
- '_ _ _'
163
- ]
164
-
165
- bad_offsets = [
166
- "\t",
167
- ' '
168
- ]
169
-
170
- good_variants.each do |variant|
171
- bad_offsets.each do |offset|
172
- input = <<-EOS
173
- This line is separated by something that is not a horizontal rule...
174
-
175
- #{offset}#{variant}
176
-
177
- ...from this line.
178
- EOS
179
- output = convert_string_to_embedded input
180
- assert_xpath '//hr', output, 0
181
- end
182
- end
183
- end
184
-
185
- test "emphasized text using underscore characters" do
186
- assert_xpath "//em", convert_string("An _emphatic_ no")
187
- end
188
-
189
- test 'emphasized text with single quote using apostrophe characters' do
190
- rsquo = decode_char 8217
191
- assert_xpath %(//em[text()="Johnny#{rsquo}s"]), convert_string(%q(It's 'Johnny's' phone), :attributes => {'compat-mode' => ''})
192
- assert_xpath %(//p[text()="It#{rsquo}s 'Johnny#{rsquo}s' phone"]), convert_string(%q(It's 'Johnny's' phone))
193
- end
194
-
195
- test 'emphasized text with escaped single quote using apostrophe characters' do
196
- assert_xpath %(//em[text()="Johnny's"]), convert_string(%q(It's 'Johnny\\'s' phone), :attributes => {'compat-mode' => ''})
197
- assert_xpath %(//p[text()="It's 'Johnny's' phone"]), convert_string(%q(It\\'s 'Johnny\\'s' phone))
198
- end
199
-
200
- test "escaped single quote is restored as single quote" do
201
- assert_xpath "//p[contains(text(), \"Let's do it!\")]", convert_string("Let\\'s do it!")
202
- end
203
-
204
- test 'unescape escaped single quote emphasis in compat mode only' do
205
- assert_xpath %(//p[text()="A 'single quoted string' example"]), convert_string_to_embedded(%(A \\'single quoted string' example), :attributes => {'compat-mode' => ''})
206
- assert_xpath %(//p[text()="'single quoted string'"]), convert_string_to_embedded(%(\\'single quoted string'), :attributes => {'compat-mode' => ''})
207
-
208
- assert_xpath %(//p[text()="A \\'single quoted string' example"]), convert_string_to_embedded(%(A \\'single quoted string' example))
209
- assert_xpath %(//p[text()="\\'single quoted string'"]), convert_string_to_embedded(%(\\'single quoted string'))
210
- end
211
-
212
- test "emphasized text at end of line" do
213
- assert_xpath "//em", convert_string("This library is _awesome_")
214
- end
215
-
216
- test "emphasized text at beginning of line" do
217
- assert_xpath "//em", convert_string("_drop_ it")
218
- end
219
-
220
- test "emphasized text across line" do
221
- assert_xpath "//em", convert_string("_check it_")
222
- end
223
-
224
- test "unquoted text" do
225
- refute_match(/#/, convert_string("An #unquoted# word"))
226
- end
227
-
228
- test 'backticks and straight quotes in text' do
229
- backslash = '\\'
230
- assert_equal %q(run <code>foo</code> <em>dog</em>), convert_inline_string(%q(run `foo` 'dog'), :attributes => {'compat-mode' => ''})
231
- assert_equal %q(run <code>foo</code> 'dog'), convert_inline_string(%q(run `foo` 'dog'))
232
- assert_equal %q(run `foo` 'dog'), convert_inline_string(%(run #{backslash}`foo` 'dog'))
233
- assert_equal %q(run &#8216;foo` 'dog&#8217;), convert_inline_string(%q(run '`foo` 'dog`'))
234
- assert_equal %q(run '`foo` 'dog`'), convert_inline_string(%(run #{backslash}'`foo` 'dog#{backslash}`'))
235
- end
236
-
237
- test 'plus characters inside single plus passthrough' do
238
- assert_xpath '//p[text()="+"]', convert_string_to_embedded('+++')
239
- assert_xpath '//p[text()="+="]', convert_string_to_embedded('++=+')
240
- end
241
-
242
- test 'plus passthrough escapes entity reference' do
243
- assert_match(/&amp;#44;/, convert_string_to_embedded('+&#44;+'))
244
- assert_match(/one&amp;#44;two/, convert_string_to_embedded('one++&#44;++two'))
245
- end
246
-
247
- context "basic styling" do
248
- setup do
249
- @output = convert_string("A *BOLD* word. An _italic_ word. A `mono` word. ^superscript!^ and some ~subscript~.")
250
- end
251
-
252
- test "strong" do
253
- assert_xpath "//strong", @output, 1
254
- end
255
-
256
- test "italic" do
257
- assert_xpath "//em", @output, 1
258
- end
259
-
260
- test "monospaced" do
261
- assert_xpath "//code", @output, 1
262
- end
263
-
264
- test "superscript" do
265
- assert_xpath "//sup", @output, 1
266
- end
267
-
268
- test "subscript" do
269
- assert_xpath "//sub", @output, 1
270
- end
271
-
272
- test "passthrough" do
273
- assert_xpath "//code", convert_string("This is +passed through+."), 0
274
- assert_xpath "//code", convert_string("This is +passed through and monospaced+.", :attributes => {'compat-mode' => ''}), 1
275
- end
276
-
277
- test "nested styles" do
278
- output = convert_string("Winning *big _time_* in the +city *boyeeee*+.", :attributes => {'compat-mode' => ''})
279
-
280
- assert_xpath "//strong/em", output
281
- assert_xpath "//code/strong", output
282
-
283
- output = convert_string("Winning *big _time_* in the `city *boyeeee*`.")
284
-
285
- assert_xpath "//strong/em", output
286
- assert_xpath "//code/strong", output
287
- end
288
-
289
- test 'unconstrained quotes' do
290
- output = convert_string('**B**__I__++M++[role]++M++', :attributes => {'compat-mode' => ''})
291
- assert_xpath '//strong', output, 1
292
- assert_xpath '//em', output, 1
293
- assert_xpath '//code[not(@class)]', output, 1
294
- assert_xpath '//code[@class="role"]', output, 1
295
-
296
- output = convert_string('**B**__I__``M``[role]``M``')
297
- assert_xpath '//strong', output, 1
298
- assert_xpath '//em', output, 1
299
- assert_xpath '//code[not(@class)]', output, 1
300
- assert_xpath '//code[@class="role"]', output, 1
301
- end
302
- end
303
-
304
- test 'should format Asian characters as words' do
305
- assert_xpath '//strong', (convert_string_to_embedded 'bold *要* bold')
306
- assert_xpath '//strong', (convert_string_to_embedded 'bold *素* bold')
307
- assert_xpath '//strong', (convert_string_to_embedded 'bold *要素* bold')
308
- end
309
- end