asciidoctor 1.5.6.2 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +330 -143
- data/README-fr.adoc +441 -0
- data/README-jp.adoc +418 -0
- data/README-zh_CN.adoc +430 -0
- data/README.adoc +454 -0
- data/Rakefile +57 -0
- data/asciidoctor.gemspec +7 -1
- data/data/locale/attributes-ar.adoc +22 -0
- data/data/locale/attributes-bg.adoc +22 -0
- data/data/locale/attributes-ca.adoc +22 -0
- data/data/locale/attributes-cs.adoc +22 -0
- data/data/locale/attributes-da.adoc +22 -0
- data/data/locale/attributes-de.adoc +22 -0
- data/data/locale/attributes-en.adoc +23 -0
- data/data/locale/attributes-es.adoc +22 -0
- data/data/locale/attributes-fa.adoc +22 -0
- data/data/locale/attributes-fi.adoc +22 -0
- data/data/locale/attributes-fr.adoc +22 -0
- data/data/locale/attributes-hu.adoc +22 -0
- data/data/locale/attributes-id.adoc +22 -0
- data/data/locale/attributes-it.adoc +22 -0
- data/data/locale/attributes-ja.adoc +22 -0
- data/data/locale/attributes-kr.adoc +22 -0
- data/data/locale/attributes-nb.adoc +22 -0
- data/data/locale/attributes-nl.adoc +22 -0
- data/data/locale/attributes-nn.adoc +22 -0
- data/data/locale/attributes-pl.adoc +22 -0
- data/data/locale/attributes-pt.adoc +22 -0
- data/data/locale/attributes-pt_BR.adoc +22 -0
- data/data/locale/attributes-ro.adoc +22 -0
- data/data/locale/attributes-ru.adoc +22 -0
- data/data/locale/attributes-sr.adoc +22 -0
- data/data/locale/attributes-sr_Latn.adoc +22 -0
- data/data/locale/attributes-tr.adoc +22 -0
- data/data/locale/attributes-uk.adoc +22 -0
- data/data/locale/attributes-zh_CN.adoc +22 -0
- data/data/locale/attributes-zh_TW.adoc +22 -0
- data/data/locale/attributes.adoc +8 -649
- data/data/stylesheets/asciidoctor-default.css +77 -72
- data/features/xref.feature +366 -7
- data/lib/asciidoctor.rb +107 -93
- data/lib/asciidoctor/abstract_block.rb +247 -239
- data/lib/asciidoctor/abstract_node.rb +56 -58
- data/lib/asciidoctor/block.rb +3 -3
- data/lib/asciidoctor/callouts.rb +1 -1
- data/lib/asciidoctor/cli/invoker.rb +36 -9
- data/lib/asciidoctor/cli/options.rb +63 -25
- data/lib/asciidoctor/converter.rb +23 -13
- data/lib/asciidoctor/converter/base.rb +4 -0
- data/lib/asciidoctor/converter/docbook45.rb +16 -9
- data/lib/asciidoctor/converter/docbook5.rb +115 -97
- data/lib/asciidoctor/converter/factory.rb +29 -31
- data/lib/asciidoctor/converter/html5.rb +229 -192
- data/lib/asciidoctor/converter/manpage.rb +72 -50
- data/lib/asciidoctor/converter/template.rb +12 -12
- data/lib/asciidoctor/core_ext.rb +5 -1
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
- data/lib/asciidoctor/document.rb +168 -77
- data/lib/asciidoctor/extensions.rb +79 -47
- data/lib/asciidoctor/helpers.rb +33 -11
- data/lib/asciidoctor/inline.rb +3 -2
- data/lib/asciidoctor/list.rb +2 -1
- data/lib/asciidoctor/logging.rb +122 -0
- data/lib/asciidoctor/parser.rb +406 -382
- data/lib/asciidoctor/path_resolver.rb +169 -162
- data/lib/asciidoctor/reader.rb +166 -121
- data/lib/asciidoctor/section.rb +45 -28
- data/lib/asciidoctor/stylesheets.rb +13 -5
- data/lib/asciidoctor/substitutors.rb +328 -254
- data/lib/asciidoctor/table.rb +105 -48
- data/lib/asciidoctor/timings.rb +34 -6
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +41 -23
- data/man/asciidoctor.adoc +14 -8
- data/test/api_test.rb +1004 -0
- data/test/attributes_test.rb +241 -50
- data/test/blocks_test.rb +549 -124
- data/test/converter_test.rb +170 -78
- data/test/document_test.rb +208 -767
- data/test/extensions_test.rb +188 -53
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
- data/test/fixtures/file-with-missing-include.adoc +1 -0
- data/test/fixtures/include-file.jsx +8 -0
- data/test/fixtures/lists.adoc +96 -0
- data/test/fixtures/other-chapters.adoc +11 -0
- data/test/fixtures/outer-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +5 -1
- data/test/fixtures/subdir/index.adoc +3 -0
- data/test/fixtures/subdir/inner-include.adoc +3 -0
- data/test/fixtures/subdir/middle-include.adoc +5 -0
- data/test/fixtures/tagged-class-enclosed.rb +0 -1
- data/test/fixtures/unclosed-tag.adoc +3 -0
- data/test/fixtures/unexpected-end-tag.adoc +4 -0
- data/test/invoker_test.rb +101 -40
- data/test/links_test.rb +266 -72
- data/test/lists_test.rb +243 -45
- data/test/logger_test.rb +211 -0
- data/test/manpage_test.rb +124 -6
- data/test/options_test.rb +46 -1
- data/test/paragraphs_test.rb +23 -10
- data/test/parser_test.rb +30 -1
- data/test/paths_test.rb +115 -33
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +337 -81
- data/test/sections_test.rb +656 -72
- data/test/substitutions_test.rb +182 -57
- data/test/tables_test.rb +324 -57
- data/test/test_helper.rb +77 -32
- data/test/text_test.rb +7 -7
- metadata +67 -3
data/man/asciidoctor.adoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
Dan Allen; Sarah White; Ryan Waldron
|
3
3
|
:doctype: manpage
|
4
4
|
:man manual: Asciidoctor Manual
|
5
|
-
:man source: Asciidoctor 1.5.
|
5
|
+
:man source: Asciidoctor 1.5.7
|
6
6
|
:page-layout: base
|
7
7
|
|
8
8
|
== NAME
|
@@ -65,11 +65,7 @@ This option may be specified more than once.
|
|
65
65
|
The _inline_ document type allows the content of a single paragraph to be formatted and returned without wrapping it in a containing element.
|
66
66
|
Defaults to _article_.
|
67
67
|
|
68
|
-
===
|
69
|
-
|
70
|
-
*-C, --compact*::
|
71
|
-
Compact the output by removing blank lines.
|
72
|
-
(No longer in use).
|
68
|
+
=== Document Conversion
|
73
69
|
|
74
70
|
*-D, --destination-dir*=_DIR_::
|
75
71
|
Destination output directory.
|
@@ -93,7 +89,7 @@ This option may be specified more than once.
|
|
93
89
|
|
94
90
|
*-n, --section-numbers*::
|
95
91
|
Auto-number section titles.
|
96
|
-
Synonym for *--attribute
|
92
|
+
Synonym for *--attribute sectnums*.
|
97
93
|
|
98
94
|
*-o, --out-file*=_OUT_FILE_::
|
99
95
|
Write output to file _OUT_FILE_.
|
@@ -102,6 +98,12 @@ This option may be specified more than once.
|
|
102
98
|
If the input is read from standard input or a named pipe (fifo), then the output file defaults to stdout.
|
103
99
|
If _OUT_FILE_ is _-_, then the output file is written to standard output.
|
104
100
|
|
101
|
+
*-R, --source-dir*=_DIR_::
|
102
|
+
Source directory.
|
103
|
+
Currently only used if the destination directory is also specified.
|
104
|
+
Used to preserve the directory structure of files converted within this directory in the destination directory.
|
105
|
+
If specified, the directory is resolved relative to the working directory.
|
106
|
+
|
105
107
|
*-r, --require*=_LIBRARY_::
|
106
108
|
Require the specified library before executing the processor, using the standard Ruby require.
|
107
109
|
This option may be specified more than once.
|
@@ -121,6 +123,10 @@ Matching templates found in subsequent directories override ones previously disc
|
|
121
123
|
|
122
124
|
=== Processing Information
|
123
125
|
|
126
|
+
*--failure-level*=_LEVEL_::
|
127
|
+
The minimum logging level that triggers a non-zero exit code (failure).
|
128
|
+
If this option is not set (default: FATAL), the program exits with a status code zero even if warnings or errors have been logged.
|
129
|
+
|
124
130
|
*-q, --quiet*::
|
125
131
|
Silence warnings.
|
126
132
|
|
@@ -172,7 +178,7 @@ Refer to the *Asciidoctor* issue tracker at https://github.com/asciidoctor/ascii
|
|
172
178
|
|
173
179
|
== RESOURCES
|
174
180
|
|
175
|
-
*Project web site:*
|
181
|
+
*Project web site:* https://asciidoctor.org
|
176
182
|
|
177
183
|
*Git source repository on GitHub:* https://github.com/asciidoctor/asciidoctor
|
178
184
|
|
data/test/api_test.rb
ADDED
@@ -0,0 +1,1004 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
unless defined? ASCIIDOCTOR_PROJECT_DIR
|
3
|
+
$: << File.dirname(__FILE__); $:.uniq!
|
4
|
+
require 'test_helper'
|
5
|
+
end
|
6
|
+
|
7
|
+
context 'API' do
|
8
|
+
context 'Load' do
|
9
|
+
test 'should load input file' do
|
10
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
11
|
+
doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
|
12
|
+
assert_equal 'Document Title', doc.doctitle
|
13
|
+
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
14
|
+
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
15
|
+
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'should load input file from filename' do
|
19
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
20
|
+
doc = Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
|
21
|
+
assert_equal 'Document Title', doc.doctitle
|
22
|
+
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
23
|
+
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
24
|
+
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
25
|
+
end
|
26
|
+
|
27
|
+
test 'should not load invalid file' do
|
28
|
+
sample_input_path = fixture_path('hello-asciidoctor.pdf')
|
29
|
+
exception = assert_raises ArgumentError do
|
30
|
+
Asciidoctor.load_file(sample_input_path, :safe => Asciidoctor::SafeMode::SAFE)
|
31
|
+
end
|
32
|
+
assert_match(/Failed to load AsciiDoc document/, exception.message)
|
33
|
+
# verify we have the correct backtrace (should be in at least first 5 lines)
|
34
|
+
assert_match((RUBY_ENGINE == 'rbx' ? /parser\.rb/ : /helpers\.rb/), exception.backtrace[0..4].join("\n"))
|
35
|
+
end if RUBY_MIN_VERSION_1_9
|
36
|
+
|
37
|
+
test 'should load input IO' do
|
38
|
+
input = StringIO.new(<<-EOS)
|
39
|
+
Document Title
|
40
|
+
==============
|
41
|
+
|
42
|
+
preamble
|
43
|
+
EOS
|
44
|
+
doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
|
45
|
+
assert_equal 'Document Title', doc.doctitle
|
46
|
+
refute doc.attr?('docfile')
|
47
|
+
assert_equal doc.base_dir, doc.attr('docdir')
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'should load input string' do
|
51
|
+
input = <<-EOS
|
52
|
+
Document Title
|
53
|
+
==============
|
54
|
+
|
55
|
+
preamble
|
56
|
+
EOS
|
57
|
+
doc = Asciidoctor.load(input, :safe => Asciidoctor::SafeMode::SAFE)
|
58
|
+
assert_equal 'Document Title', doc.doctitle
|
59
|
+
refute doc.attr?('docfile')
|
60
|
+
assert_equal doc.base_dir, doc.attr('docdir')
|
61
|
+
end
|
62
|
+
|
63
|
+
test 'should load input string array' do
|
64
|
+
input = <<-EOS
|
65
|
+
Document Title
|
66
|
+
==============
|
67
|
+
|
68
|
+
preamble
|
69
|
+
EOS
|
70
|
+
doc = Asciidoctor.load(input.lines.entries, :safe => Asciidoctor::SafeMode::SAFE)
|
71
|
+
assert_equal 'Document Title', doc.doctitle
|
72
|
+
refute doc.attr?('docfile')
|
73
|
+
assert_equal doc.base_dir, doc.attr('docdir')
|
74
|
+
end
|
75
|
+
|
76
|
+
test 'should accept attributes as array' do
|
77
|
+
# NOTE there's a tab character before idseparator
|
78
|
+
doc = Asciidoctor.load('text', :attributes => %w(toc sectnums source-highlighter=coderay idprefix idseparator=-))
|
79
|
+
assert_kind_of Hash, doc.attributes
|
80
|
+
assert doc.attr?('toc')
|
81
|
+
assert_equal '', doc.attr('toc')
|
82
|
+
assert doc.attr?('sectnums')
|
83
|
+
assert_equal '', doc.attr('sectnums')
|
84
|
+
assert doc.attr?('source-highlighter')
|
85
|
+
assert_equal 'coderay', doc.attr('source-highlighter')
|
86
|
+
assert doc.attr?('idprefix')
|
87
|
+
assert_equal '', doc.attr('idprefix')
|
88
|
+
assert doc.attr?('idseparator')
|
89
|
+
assert_equal '-', doc.attr('idseparator')
|
90
|
+
end
|
91
|
+
|
92
|
+
test 'should accept attributes as empty array' do
|
93
|
+
doc = Asciidoctor.load('text', :attributes => [])
|
94
|
+
assert_kind_of Hash, doc.attributes
|
95
|
+
end
|
96
|
+
|
97
|
+
test 'should accept attributes as string' do
|
98
|
+
doc = Asciidoctor.load('text', :attributes => 'toc sectnums
|
99
|
+
source-highlighter=coderay
|
100
|
+
idprefix
|
101
|
+
idseparator=-')
|
102
|
+
assert_kind_of Hash, doc.attributes
|
103
|
+
assert doc.attr?('toc')
|
104
|
+
assert_equal '', doc.attr('toc')
|
105
|
+
assert doc.attr?('sectnums')
|
106
|
+
assert_equal '', doc.attr('sectnums')
|
107
|
+
assert doc.attr?('source-highlighter')
|
108
|
+
assert_equal 'coderay', doc.attr('source-highlighter')
|
109
|
+
assert doc.attr?('idprefix')
|
110
|
+
assert_equal '', doc.attr('idprefix')
|
111
|
+
assert doc.attr?('idseparator')
|
112
|
+
assert_equal '-', doc.attr('idseparator')
|
113
|
+
end
|
114
|
+
|
115
|
+
test 'should accept values containing spaces in attributes string' do
|
116
|
+
doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=- note-caption=Note\\ to\\\tself toc))
|
117
|
+
assert_kind_of Hash, doc.attributes
|
118
|
+
assert doc.attr?('idprefix')
|
119
|
+
assert_equal '', doc.attr('idprefix')
|
120
|
+
assert doc.attr?('idseparator')
|
121
|
+
assert_equal '-', doc.attr('idseparator')
|
122
|
+
assert doc.attr?('note-caption')
|
123
|
+
assert_equal "Note to\tself", doc.attr('note-caption')
|
124
|
+
end
|
125
|
+
|
126
|
+
test 'should accept attributes as empty string' do
|
127
|
+
doc = Asciidoctor.load('text', :attributes => '')
|
128
|
+
assert_kind_of Hash, doc.attributes
|
129
|
+
end
|
130
|
+
|
131
|
+
test 'should accept attributes as nil' do
|
132
|
+
doc = Asciidoctor.load('text', :attributes => nil)
|
133
|
+
assert_kind_of Hash, doc.attributes
|
134
|
+
end
|
135
|
+
|
136
|
+
test 'should accept attributes if hash like' do
|
137
|
+
class Hashish
|
138
|
+
def initialize
|
139
|
+
@table = {'toc' => ''}
|
140
|
+
end
|
141
|
+
|
142
|
+
def keys
|
143
|
+
@table.keys
|
144
|
+
end
|
145
|
+
|
146
|
+
def [](key)
|
147
|
+
@table[key]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
doc = Asciidoctor.load('text', :attributes => Hashish.new)
|
152
|
+
assert_kind_of Hash, doc.attributes
|
153
|
+
assert doc.attributes.has_key?('toc')
|
154
|
+
end
|
155
|
+
|
156
|
+
test 'should not expand value of docdir attribute if specified via API' do
|
157
|
+
docdir = 'virtual/directory'
|
158
|
+
doc = document_from_string '', :safe => :safe, :attributes => { 'docdir' => docdir }
|
159
|
+
assert_equal docdir, (doc.attr 'docdir')
|
160
|
+
assert_equal docdir, doc.base_dir
|
161
|
+
end
|
162
|
+
|
163
|
+
test 'converts block to output format when convert is called' do
|
164
|
+
doc = Asciidoctor.load 'paragraph text'
|
165
|
+
expected = <<-EOS
|
166
|
+
<div class="paragraph">
|
167
|
+
<p>paragraph text</p>
|
168
|
+
</div>
|
169
|
+
EOS
|
170
|
+
assert_equal 1, doc.blocks.length
|
171
|
+
assert_equal :paragraph, doc.blocks[0].context
|
172
|
+
assert_equal expected.chomp, doc.blocks[0].convert
|
173
|
+
end
|
174
|
+
|
175
|
+
test 'render method on node is aliased to convert method' do
|
176
|
+
input = <<-EOS
|
177
|
+
paragraph text
|
178
|
+
|
179
|
+
* list item
|
180
|
+
EOS
|
181
|
+
doc = Asciidoctor.load input
|
182
|
+
assert_equal 2, doc.blocks.length
|
183
|
+
([doc] + doc.blocks).each do |block|
|
184
|
+
assert_equal block.method(:convert), block.method(:render)
|
185
|
+
end
|
186
|
+
inline = Asciidoctor::Inline.new doc.blocks[0], :image, nil, :type => 'image', :target => 'tiger.png'
|
187
|
+
assert_equal inline.method(:convert), inline.method(:render)
|
188
|
+
end
|
189
|
+
|
190
|
+
test 'should output timestamps by default' do
|
191
|
+
doc = document_from_string 'text', :backend => :html5, :attributes => nil
|
192
|
+
result = doc.convert
|
193
|
+
assert doc.attr?('docdate')
|
194
|
+
refute doc.attr? 'reproducible'
|
195
|
+
assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 1
|
196
|
+
end
|
197
|
+
|
198
|
+
test 'should not output timestamps if reproducible attribute is set in HTML 5' do
|
199
|
+
doc = document_from_string 'text', :backend => :html5, :attributes => { 'reproducible' => '' }
|
200
|
+
result = doc.convert
|
201
|
+
assert doc.attr?('docdate')
|
202
|
+
assert doc.attr?('reproducible')
|
203
|
+
assert_xpath '//div[@id="footer-text" and contains(string(.//text()), "Last updated")]', result, 0
|
204
|
+
end
|
205
|
+
|
206
|
+
test 'should not output timestamps if reproducible attribute is set in DocBook' do
|
207
|
+
doc = document_from_string 'text', :backend => :docbook, :attributes => { 'reproducible' => '' }
|
208
|
+
result = doc.convert
|
209
|
+
assert doc.attr?('docdate')
|
210
|
+
assert doc.attr?('reproducible')
|
211
|
+
assert_xpath '/article/info/date', result, 0
|
212
|
+
end
|
213
|
+
|
214
|
+
test 'should not modify options argument' do
|
215
|
+
options = {
|
216
|
+
:safe => Asciidoctor::SafeMode::SAFE
|
217
|
+
}
|
218
|
+
options.freeze
|
219
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
220
|
+
begin
|
221
|
+
Asciidoctor.load_file sample_input_path, options
|
222
|
+
rescue
|
223
|
+
flunk %(options argument should not be modified)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
test 'should not modify attributes Hash argument' do
|
228
|
+
attributes = {}
|
229
|
+
attributes.freeze
|
230
|
+
options = {
|
231
|
+
:safe => Asciidoctor::SafeMode::SAFE,
|
232
|
+
:attributes => attributes
|
233
|
+
}
|
234
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
235
|
+
begin
|
236
|
+
Asciidoctor.load_file sample_input_path, options
|
237
|
+
rescue
|
238
|
+
flunk %(attributes argument should not be modified)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
test 'should be able to restore header attributes after call to convert' do
|
243
|
+
input = <<-EOS
|
244
|
+
= Document Title
|
245
|
+
:foo: bar
|
246
|
+
|
247
|
+
content
|
248
|
+
|
249
|
+
:foo: baz
|
250
|
+
|
251
|
+
content
|
252
|
+
EOS
|
253
|
+
doc = Asciidoctor.load input
|
254
|
+
assert_equal 'bar', (doc.attr 'foo')
|
255
|
+
doc.convert
|
256
|
+
assert_equal 'baz', (doc.attr 'foo')
|
257
|
+
doc.restore_attributes
|
258
|
+
assert_equal 'bar', (doc.attr 'foo')
|
259
|
+
end
|
260
|
+
|
261
|
+
test 'should track file and line information with blocks if sourcemap option is set' do
|
262
|
+
doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :sourcemap => true
|
263
|
+
|
264
|
+
refute_nil doc.source_location
|
265
|
+
assert_equal 'sample.asciidoc', doc.file
|
266
|
+
assert_equal 1, doc.lineno
|
267
|
+
|
268
|
+
section_1 = doc.sections[0]
|
269
|
+
assert_equal 'Section A', section_1.title
|
270
|
+
refute_nil section_1.source_location
|
271
|
+
assert_equal 'sample.asciidoc', section_1.file
|
272
|
+
assert_equal 10, section_1.lineno
|
273
|
+
|
274
|
+
section_2 = doc.sections[1]
|
275
|
+
assert_equal 'Section B', section_2.title
|
276
|
+
refute_nil section_2.source_location
|
277
|
+
assert_equal 'sample.asciidoc', section_2.file
|
278
|
+
assert_equal 18, section_2.lineno
|
279
|
+
|
280
|
+
table_block = section_2.blocks[1]
|
281
|
+
assert_equal :table, table_block.context
|
282
|
+
refute_nil table_block.source_location
|
283
|
+
assert_equal 'sample.asciidoc', table_block.file
|
284
|
+
assert_equal 22, table_block.lineno
|
285
|
+
first_cell = table_block.rows.body[0][0]
|
286
|
+
refute_nil first_cell.source_location
|
287
|
+
assert_equal 'sample.asciidoc', first_cell.file
|
288
|
+
assert_equal 23, first_cell.lineno
|
289
|
+
second_cell = table_block.rows.body[0][1]
|
290
|
+
refute_nil second_cell.source_location
|
291
|
+
assert_equal 'sample.asciidoc', second_cell.file
|
292
|
+
assert_equal 23, second_cell.lineno
|
293
|
+
last_cell = table_block.rows.body[-1][-1]
|
294
|
+
refute_nil last_cell.source_location
|
295
|
+
assert_equal 'sample.asciidoc', last_cell.file
|
296
|
+
assert_equal 24, last_cell.lineno
|
297
|
+
|
298
|
+
last_block = section_2.blocks[-1]
|
299
|
+
assert_equal :ulist, last_block.context
|
300
|
+
refute_nil last_block.source_location
|
301
|
+
assert_equal 'sample.asciidoc', last_block.file
|
302
|
+
assert_equal 28, last_block.lineno
|
303
|
+
|
304
|
+
list_items = last_block.blocks
|
305
|
+
refute_nil list_items[0].source_location
|
306
|
+
assert_equal 'sample.asciidoc', list_items[0].file
|
307
|
+
assert_equal 28, list_items[0].lineno
|
308
|
+
|
309
|
+
refute_nil list_items[1].source_location
|
310
|
+
assert_equal 'sample.asciidoc', list_items[1].file
|
311
|
+
assert_equal 29, list_items[1].lineno
|
312
|
+
|
313
|
+
refute_nil list_items[2].source_location
|
314
|
+
assert_equal 'sample.asciidoc', list_items[2].file
|
315
|
+
assert_equal 30, list_items[2].lineno
|
316
|
+
|
317
|
+
doc = Asciidoctor.load_file fixture_path('master.adoc'), :sourcemap => true, :safe => :safe
|
318
|
+
|
319
|
+
section_1 = doc.sections[0]
|
320
|
+
assert_equal 'Chapter A', section_1.title
|
321
|
+
refute_nil section_1.source_location
|
322
|
+
assert_equal fixture_path('chapter-a.adoc'), section_1.file
|
323
|
+
assert_equal 1, section_1.lineno
|
324
|
+
end
|
325
|
+
|
326
|
+
test 'should track file and line information on list items if sourcemap option is set' do
|
327
|
+
doc = Asciidoctor.load_file fixture_path('lists.adoc'), :sourcemap => true
|
328
|
+
|
329
|
+
first_section = doc.blocks[1]
|
330
|
+
|
331
|
+
unordered_basic_list = first_section.blocks[0]
|
332
|
+
assert_equal 11, unordered_basic_list.lineno
|
333
|
+
|
334
|
+
unordered_basic_list_items = unordered_basic_list.find_by :context => :list_item
|
335
|
+
assert_equal 11, unordered_basic_list_items[0].lineno
|
336
|
+
assert_equal 12, unordered_basic_list_items[1].lineno
|
337
|
+
assert_equal 13, unordered_basic_list_items[2].lineno
|
338
|
+
|
339
|
+
unordered_max_nesting = first_section.blocks[1]
|
340
|
+
assert_equal 16, unordered_max_nesting.lineno
|
341
|
+
unordered_max_nesting_items = unordered_max_nesting.find_by :context => :list_item
|
342
|
+
assert_equal 16, unordered_max_nesting_items[0].lineno
|
343
|
+
assert_equal 17, unordered_max_nesting_items[1].lineno
|
344
|
+
assert_equal 18, unordered_max_nesting_items[2].lineno
|
345
|
+
assert_equal 19, unordered_max_nesting_items[3].lineno
|
346
|
+
assert_equal 20, unordered_max_nesting_items[4].lineno
|
347
|
+
assert_equal 21, unordered_max_nesting_items[5].lineno
|
348
|
+
|
349
|
+
checklist = first_section.blocks[2]
|
350
|
+
assert_equal 24, checklist.lineno
|
351
|
+
checklist_list_items = checklist.find_by :context => :list_item
|
352
|
+
assert_equal 24, checklist_list_items[0].lineno
|
353
|
+
assert_equal 25, checklist_list_items[1].lineno
|
354
|
+
assert_equal 26, checklist_list_items[2].lineno
|
355
|
+
assert_equal 27, checklist_list_items[3].lineno
|
356
|
+
|
357
|
+
ordered_basic = first_section.blocks[3]
|
358
|
+
assert_equal 30, ordered_basic.lineno
|
359
|
+
ordered_basic_list_items = ordered_basic.find_by :context => :list_item
|
360
|
+
assert_equal 30, ordered_basic_list_items[0].lineno
|
361
|
+
assert_equal 31, ordered_basic_list_items[1].lineno
|
362
|
+
assert_equal 32, ordered_basic_list_items[2].lineno
|
363
|
+
|
364
|
+
ordered_nested = first_section.blocks[4]
|
365
|
+
assert_equal 35, ordered_nested.lineno
|
366
|
+
ordered_nested_list_items = ordered_nested.find_by :context => :list_item
|
367
|
+
assert_equal 35, ordered_nested_list_items[0].lineno
|
368
|
+
assert_equal 36, ordered_nested_list_items[1].lineno
|
369
|
+
assert_equal 37, ordered_nested_list_items[2].lineno
|
370
|
+
assert_equal 38, ordered_nested_list_items[3].lineno
|
371
|
+
assert_equal 39, ordered_nested_list_items[4].lineno
|
372
|
+
|
373
|
+
ordered_max_nesting = first_section.blocks[5]
|
374
|
+
assert_equal 42, ordered_max_nesting.lineno
|
375
|
+
ordered_max_nesting_items = ordered_max_nesting.find_by :context => :list_item
|
376
|
+
assert_equal 42, ordered_max_nesting_items[0].lineno
|
377
|
+
assert_equal 43, ordered_max_nesting_items[1].lineno
|
378
|
+
assert_equal 44, ordered_max_nesting_items[2].lineno
|
379
|
+
assert_equal 45, ordered_max_nesting_items[3].lineno
|
380
|
+
assert_equal 46, ordered_max_nesting_items[4].lineno
|
381
|
+
assert_equal 47, ordered_max_nesting_items[5].lineno
|
382
|
+
|
383
|
+
labeled_singleline = first_section.blocks[6]
|
384
|
+
assert_equal 50, labeled_singleline.lineno
|
385
|
+
labeled_singleline_items = labeled_singleline.find_by :context => :list_item
|
386
|
+
assert_equal 50, labeled_singleline_items[0].lineno
|
387
|
+
assert_equal 50, labeled_singleline_items[1].lineno
|
388
|
+
assert_equal 51, labeled_singleline_items[2].lineno
|
389
|
+
assert_equal 51, labeled_singleline_items[3].lineno
|
390
|
+
|
391
|
+
labeled_multiline = first_section.blocks[7]
|
392
|
+
assert_equal 54, labeled_multiline.lineno
|
393
|
+
labeled_multiline_items = labeled_multiline.find_by :context => :list_item
|
394
|
+
assert_equal 54, labeled_multiline_items[0].lineno
|
395
|
+
assert_equal 55, labeled_multiline_items[1].lineno
|
396
|
+
assert_equal 56, labeled_multiline_items[2].lineno
|
397
|
+
assert_equal 57, labeled_multiline_items[3].lineno
|
398
|
+
|
399
|
+
qanda = first_section.blocks[8]
|
400
|
+
assert_equal 61, qanda.lineno
|
401
|
+
qanda_items = qanda.find_by :context => :list_item
|
402
|
+
assert_equal 61, qanda_items[0].lineno
|
403
|
+
assert_equal 62, qanda_items[1].lineno
|
404
|
+
assert_equal 63, qanda_items[2].lineno
|
405
|
+
assert_equal 63, qanda_items[3].lineno
|
406
|
+
|
407
|
+
mixed = first_section.blocks[9]
|
408
|
+
assert_equal 66, mixed.lineno
|
409
|
+
mixed_items = mixed.find_by(:context => :list_item) {|block| block.text? }
|
410
|
+
assert_equal 66, mixed_items[0].lineno
|
411
|
+
assert_equal 67, mixed_items[1].lineno
|
412
|
+
assert_equal 68, mixed_items[2].lineno
|
413
|
+
assert_equal 69, mixed_items[3].lineno
|
414
|
+
assert_equal 70, mixed_items[4].lineno
|
415
|
+
assert_equal 71, mixed_items[5].lineno
|
416
|
+
assert_equal 72, mixed_items[6].lineno
|
417
|
+
assert_equal 73, mixed_items[7].lineno
|
418
|
+
assert_equal 74, mixed_items[8].lineno
|
419
|
+
assert_equal 75, mixed_items[9].lineno
|
420
|
+
assert_equal 77, mixed_items[10].lineno
|
421
|
+
assert_equal 78, mixed_items[11].lineno
|
422
|
+
assert_equal 79, mixed_items[12].lineno
|
423
|
+
assert_equal 80, mixed_items[13].lineno
|
424
|
+
assert_equal 81, mixed_items[14].lineno
|
425
|
+
assert_equal 82, mixed_items[15].lineno
|
426
|
+
assert_equal 83, mixed_items[16].lineno
|
427
|
+
|
428
|
+
unordered_complex_list = first_section.blocks[10]
|
429
|
+
assert_equal 86, unordered_complex_list.lineno
|
430
|
+
unordered_complex_items = unordered_complex_list.find_by :context => :list_item
|
431
|
+
assert_equal 86, unordered_complex_items[0].lineno
|
432
|
+
assert_equal 87, unordered_complex_items[1].lineno
|
433
|
+
assert_equal 88, unordered_complex_items[2].lineno
|
434
|
+
assert_equal 92, unordered_complex_items[3].lineno
|
435
|
+
assert_equal 96, unordered_complex_items[4].lineno
|
436
|
+
end
|
437
|
+
|
438
|
+
test 'should assign correct source location if section occurs on last line of input' do
|
439
|
+
input = <<-EOS
|
440
|
+
= Document Title
|
441
|
+
|
442
|
+
== Section A
|
443
|
+
|
444
|
+
content
|
445
|
+
|
446
|
+
== Section B
|
447
|
+
EOS
|
448
|
+
|
449
|
+
doc = document_from_string input, :sourcemap => true
|
450
|
+
assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
|
451
|
+
end
|
452
|
+
|
453
|
+
test 'should allow sourcemap option on document to be modified' do
|
454
|
+
doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
|
455
|
+
doc.sourcemap = true
|
456
|
+
doc = doc.parse
|
457
|
+
|
458
|
+
section_1 = doc.sections[0]
|
459
|
+
assert_equal 'Section A', section_1.title
|
460
|
+
refute_nil section_1.source_location
|
461
|
+
assert_equal 'sample.asciidoc', section_1.file
|
462
|
+
assert_equal 10, section_1.lineno
|
463
|
+
end
|
464
|
+
|
465
|
+
test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
|
466
|
+
input = <<-EOS
|
467
|
+
= Document Title
|
468
|
+
|
469
|
+
preamble
|
470
|
+
|
471
|
+
== Section A
|
472
|
+
|
473
|
+
paragraph
|
474
|
+
|
475
|
+
--
|
476
|
+
Exhibit A::
|
477
|
+
+
|
478
|
+
[#tiger.animal]
|
479
|
+
image::tiger.png[Tiger]
|
480
|
+
--
|
481
|
+
|
482
|
+
image::shoe.png[Shoe]
|
483
|
+
|
484
|
+
== Section B
|
485
|
+
|
486
|
+
paragraph
|
487
|
+
EOS
|
488
|
+
|
489
|
+
doc = Asciidoctor.load input
|
490
|
+
result = doc.find_by :context => :image
|
491
|
+
assert_equal 2, result.size
|
492
|
+
assert_equal :image, result[0].context
|
493
|
+
assert_equal 'tiger.png', result[0].attr('target')
|
494
|
+
assert_equal :image, result[1].context
|
495
|
+
assert_equal 'shoe.png', result[1].attr('target')
|
496
|
+
end
|
497
|
+
|
498
|
+
test 'find_by should return an empty Array if no matches are found' do
|
499
|
+
input = <<-EOS
|
500
|
+
paragraph
|
501
|
+
EOS
|
502
|
+
doc = Asciidoctor.load input
|
503
|
+
result = doc.find_by :context => :section
|
504
|
+
refute_nil result
|
505
|
+
assert_equal 0, result.size
|
506
|
+
end
|
507
|
+
|
508
|
+
test 'find_by should return Array of blocks that match style criteria' do
|
509
|
+
input = <<-EOS
|
510
|
+
[square]
|
511
|
+
* one
|
512
|
+
* two
|
513
|
+
* three
|
514
|
+
|
515
|
+
---
|
516
|
+
|
517
|
+
* apples
|
518
|
+
* bananas
|
519
|
+
* pears
|
520
|
+
EOS
|
521
|
+
|
522
|
+
doc = Asciidoctor.load input
|
523
|
+
result = doc.find_by :context => :ulist, :style => 'square'
|
524
|
+
assert_equal 1, result.size
|
525
|
+
assert_equal :ulist, result[0].context
|
526
|
+
end
|
527
|
+
|
528
|
+
test 'find_by should return Array of blocks that match role criteria' do
|
529
|
+
input = <<-EOS
|
530
|
+
[#tiger.animal]
|
531
|
+
image::tiger.png[Tiger]
|
532
|
+
|
533
|
+
image::shoe.png[Shoe]
|
534
|
+
EOS
|
535
|
+
|
536
|
+
doc = Asciidoctor.load input
|
537
|
+
result = doc.find_by :context => :image, :role => 'animal'
|
538
|
+
assert_equal 1, result.size
|
539
|
+
assert_equal :image, result[0].context
|
540
|
+
assert_equal 'tiger.png', result[0].attr('target')
|
541
|
+
end
|
542
|
+
|
543
|
+
test 'find_by should return the document title section if context selector is :section' do
|
544
|
+
input = <<-EOS
|
545
|
+
= Document Title
|
546
|
+
|
547
|
+
preamble
|
548
|
+
|
549
|
+
== Section One
|
550
|
+
|
551
|
+
content
|
552
|
+
EOS
|
553
|
+
doc = Asciidoctor.load input
|
554
|
+
result = doc.find_by :context => :section
|
555
|
+
refute_nil result
|
556
|
+
assert_equal 2, result.size
|
557
|
+
assert_equal :section, result[0].context
|
558
|
+
assert_equal 'Document Title', result[0].title
|
559
|
+
end
|
560
|
+
|
561
|
+
test 'find_by should only return results for which the block argument yields true' do
|
562
|
+
input = <<-EOS
|
563
|
+
== Section
|
564
|
+
|
565
|
+
content
|
566
|
+
|
567
|
+
=== Subsection
|
568
|
+
|
569
|
+
content
|
570
|
+
EOS
|
571
|
+
doc = Asciidoctor.load input
|
572
|
+
result = doc.find_by(:context => :section) {|sect| sect.level == 1 }
|
573
|
+
refute_nil result
|
574
|
+
assert_equal 1, result.size
|
575
|
+
assert_equal :section, result[0].context
|
576
|
+
assert_equal 'Section', result[0].title
|
577
|
+
end
|
578
|
+
|
579
|
+
test 'find_by should only return one result when matching by id' do
|
580
|
+
input = <<-EOS
|
581
|
+
== Section
|
582
|
+
|
583
|
+
content
|
584
|
+
|
585
|
+
[#subsection]
|
586
|
+
=== Subsection
|
587
|
+
|
588
|
+
content
|
589
|
+
EOS
|
590
|
+
doc = Asciidoctor.load input
|
591
|
+
result = doc.find_by(:context => :section, :id => 'subsection')
|
592
|
+
refute_nil result
|
593
|
+
assert_equal 1, result.size
|
594
|
+
assert_equal :section, result[0].context
|
595
|
+
assert_equal 'Subsection', result[0].title
|
596
|
+
end
|
597
|
+
|
598
|
+
test 'find_by should return an empty Array if the id criteria matches but the block argument yields false' do
|
599
|
+
input = <<-EOS
|
600
|
+
== Section
|
601
|
+
|
602
|
+
content
|
603
|
+
|
604
|
+
[#subsection]
|
605
|
+
=== Subsection
|
606
|
+
|
607
|
+
content
|
608
|
+
EOS
|
609
|
+
doc = Asciidoctor.load input
|
610
|
+
result = doc.find_by(:context => :section, :id => 'subsection') {|sect| false }
|
611
|
+
refute_nil result
|
612
|
+
assert_equal 0, result.size
|
613
|
+
end
|
614
|
+
|
615
|
+
test 'find_by should not crash if dlist entry does not have description' do
|
616
|
+
input = <<-EOS
|
617
|
+
term without description::
|
618
|
+
EOS
|
619
|
+
doc = Asciidoctor.load input
|
620
|
+
result = doc.find_by
|
621
|
+
refute_nil result
|
622
|
+
assert_equal 3, result.size
|
623
|
+
assert_kind_of Asciidoctor::Document, result[0]
|
624
|
+
assert_kind_of Asciidoctor::List, result[1]
|
625
|
+
assert_kind_of Asciidoctor::ListItem, result[2]
|
626
|
+
end
|
627
|
+
|
628
|
+
test 'timings are recorded for each step when load and convert are called separately' do
|
629
|
+
sample_input_path = fixture_path 'asciidoc_index.txt'
|
630
|
+
(Asciidoctor.load_file sample_input_path, :timings => (timings = Asciidoctor::Timings.new)).convert
|
631
|
+
refute_equal '0.00000', '%05.5f' % timings.read_parse.to_f
|
632
|
+
refute_equal '0.00000', '%05.5f' % timings.convert.to_f
|
633
|
+
refute_equal timings.read_parse, timings.total
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
context 'Convert' do
|
638
|
+
test 'render_file is aliased to convert_file' do
|
639
|
+
assert_equal Asciidoctor.method(:convert_file), Asciidoctor.method(:render_file)
|
640
|
+
end
|
641
|
+
|
642
|
+
test 'render is aliased to convert' do
|
643
|
+
assert_equal Asciidoctor.method(:convert), Asciidoctor.method(:render)
|
644
|
+
end
|
645
|
+
|
646
|
+
test 'should convert source document to string when to_file is false' do
|
647
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
648
|
+
|
649
|
+
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
650
|
+
refute_empty output
|
651
|
+
assert_xpath '/html', output, 1
|
652
|
+
assert_xpath '/html/head', output, 1
|
653
|
+
assert_xpath '/html/body', output, 1
|
654
|
+
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
655
|
+
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
656
|
+
end
|
657
|
+
|
658
|
+
test 'lines in output should be separated by line feed' do
|
659
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
660
|
+
|
661
|
+
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
662
|
+
refute_empty output
|
663
|
+
lines = output.split("\n")
|
664
|
+
assert_equal lines.size, output.split(/\r\n|\r|\n/).size
|
665
|
+
raw_lengths = lines.map(&:length)
|
666
|
+
trimmed_lengths = lines.map {|line| line.rstrip.length }
|
667
|
+
assert_equal raw_lengths, trimmed_lengths
|
668
|
+
end
|
669
|
+
|
670
|
+
test 'should accept attributes as array' do
|
671
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
672
|
+
output = Asciidoctor.convert_file sample_input_path, :attributes => %w(sectnums idprefix idseparator=-), :to_file => false
|
673
|
+
assert_css '#section-a', output, 1
|
674
|
+
end
|
675
|
+
|
676
|
+
test 'should accept attributes as string' do
|
677
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
678
|
+
output = Asciidoctor.convert_file sample_input_path, :attributes => 'sectnums idprefix idseparator=-', :to_file => false
|
679
|
+
assert_css '#section-a', output, 1
|
680
|
+
end
|
681
|
+
|
682
|
+
test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
|
683
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
684
|
+
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false
|
685
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
686
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
687
|
+
end
|
688
|
+
|
689
|
+
test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
|
690
|
+
input = <<-EOS
|
691
|
+
= Document Title
|
692
|
+
|
693
|
+
text
|
694
|
+
EOS
|
695
|
+
|
696
|
+
output = Asciidoctor.convert input, :safe => Asciidoctor::SafeMode::SERVER, :header_footer => true
|
697
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
698
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
|
699
|
+
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
700
|
+
styles = stylenode.content
|
701
|
+
refute_nil styles
|
702
|
+
refute_empty styles.strip
|
703
|
+
end
|
704
|
+
|
705
|
+
test 'should not allow linkcss be unset from document if SafeMode is SECURE or greater' do
|
706
|
+
input = <<-EOS
|
707
|
+
= Document Title
|
708
|
+
:linkcss!:
|
709
|
+
|
710
|
+
text
|
711
|
+
EOS
|
712
|
+
|
713
|
+
output = Asciidoctor.convert input, :header_footer => true
|
714
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
715
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
|
716
|
+
end
|
717
|
+
|
718
|
+
test 'should embed default stylesheet if linkcss is unset from API and SafeMode is SECURE or greater' do
|
719
|
+
input = <<-EOS
|
720
|
+
= Document Title
|
721
|
+
|
722
|
+
text
|
723
|
+
EOS
|
724
|
+
|
725
|
+
#[{ 'linkcss!' => '' }, { 'linkcss' => nil }, { 'linkcss' => false }].each do |attrs|
|
726
|
+
[{ 'linkcss!' => '' }, { 'linkcss' => nil }].each do |attrs|
|
727
|
+
output = Asciidoctor.convert input, :header_footer => true, :attributes => attrs
|
728
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
729
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
|
730
|
+
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
731
|
+
styles = stylenode.content
|
732
|
+
refute_nil styles
|
733
|
+
refute_empty styles.strip
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
test 'should embed default stylesheet if safe mode is less than SECURE and linkcss is unset from API' do
|
738
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
739
|
+
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :to_file => false,
|
740
|
+
:safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
|
741
|
+
assert_css 'html:root > head > style', output, 1
|
742
|
+
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
743
|
+
styles = stylenode.content
|
744
|
+
refute_nil styles
|
745
|
+
refute_empty styles.strip
|
746
|
+
end
|
747
|
+
|
748
|
+
test 'should not link to stylesheet if stylesheet is unset' do
|
749
|
+
input = <<-EOS
|
750
|
+
= Document Title
|
751
|
+
|
752
|
+
text
|
753
|
+
EOS
|
754
|
+
|
755
|
+
output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet!' => ''}
|
756
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
|
757
|
+
assert_css 'html:root > head > link[rel="stylesheet"]', output, 0
|
758
|
+
end
|
759
|
+
|
760
|
+
test 'should link to custom stylesheet if specified in stylesheet attribute' do
|
761
|
+
input = <<-EOS
|
762
|
+
= Document Title
|
763
|
+
|
764
|
+
text
|
765
|
+
EOS
|
766
|
+
|
767
|
+
output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => './custom.css'}
|
768
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
|
769
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./custom.css"]', output, 1
|
770
|
+
|
771
|
+
output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => 'file:///home/username/custom.css'}
|
772
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="file:///home/username/custom.css"]', output, 1
|
773
|
+
end
|
774
|
+
|
775
|
+
test 'should resolve custom stylesheet relative to stylesdir' do
|
776
|
+
input = <<-EOS
|
777
|
+
= Document Title
|
778
|
+
|
779
|
+
text
|
780
|
+
EOS
|
781
|
+
|
782
|
+
output = Asciidoctor.convert input, :header_footer => true, :attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets'}
|
783
|
+
assert_css 'html:root > head > link[rel="stylesheet"][href="./stylesheets/custom.css"]', output, 1
|
784
|
+
end
|
785
|
+
|
786
|
+
test 'should resolve custom stylesheet to embed relative to stylesdir' do
|
787
|
+
sample_input_path = fixture_path('basic.asciidoc')
|
788
|
+
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
|
789
|
+
:attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
|
790
|
+
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
791
|
+
styles = stylenode.content
|
792
|
+
refute_nil styles
|
793
|
+
refute_empty styles.strip
|
794
|
+
end
|
795
|
+
|
796
|
+
test 'should convert source file and write result to adjacent file by default' do
|
797
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
798
|
+
sample_output_path = fixture_path('sample.html')
|
799
|
+
begin
|
800
|
+
Asciidoctor.convert_file sample_input_path
|
801
|
+
assert File.exist?(sample_output_path)
|
802
|
+
output = IO.read(sample_output_path)
|
803
|
+
refute_empty output
|
804
|
+
assert_xpath '/html', output, 1
|
805
|
+
assert_xpath '/html/head', output, 1
|
806
|
+
assert_xpath '/html/body', output, 1
|
807
|
+
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
808
|
+
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
809
|
+
ensure
|
810
|
+
FileUtils.rm(sample_output_path)
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
test 'should convert source file and write to specified file' do
|
815
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
816
|
+
sample_output_path = fixture_path('result.html')
|
817
|
+
begin
|
818
|
+
Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
|
819
|
+
assert File.exist?(sample_output_path)
|
820
|
+
output = IO.read(sample_output_path)
|
821
|
+
refute_empty output
|
822
|
+
assert_xpath '/html', output, 1
|
823
|
+
assert_xpath '/html/head', output, 1
|
824
|
+
assert_xpath '/html/body', output, 1
|
825
|
+
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
826
|
+
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
827
|
+
ensure
|
828
|
+
FileUtils.rm(sample_output_path)
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
832
|
+
test 'should convert source file and write to specified file in base_dir' do
|
833
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
834
|
+
sample_output_path = fixture_path('result.html')
|
835
|
+
fixture_dir = fixture_path('')
|
836
|
+
begin
|
837
|
+
Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
|
838
|
+
assert File.exist?(sample_output_path)
|
839
|
+
output = IO.read(sample_output_path)
|
840
|
+
refute_empty output
|
841
|
+
assert_xpath '/html', output, 1
|
842
|
+
assert_xpath '/html/head', output, 1
|
843
|
+
assert_xpath '/html/body', output, 1
|
844
|
+
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
|
845
|
+
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
|
846
|
+
rescue => e
|
847
|
+
flunk e.message
|
848
|
+
ensure
|
849
|
+
FileUtils.rm(sample_output_path, :force => true)
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
test 'in_place option is ignored when to_file is specified' do
|
854
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
855
|
+
sample_output_path = fixture_path('result.html')
|
856
|
+
begin
|
857
|
+
Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path, :in_place => true
|
858
|
+
assert File.exist?(sample_output_path)
|
859
|
+
ensure
|
860
|
+
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
test 'in_place option is ignored when to_dir is specified' do
|
865
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
866
|
+
sample_output_path = fixture_path('sample.html')
|
867
|
+
begin
|
868
|
+
Asciidoctor.convert_file sample_input_path, :to_dir => File.dirname(sample_output_path), :in_place => true
|
869
|
+
assert File.exist?(sample_output_path)
|
870
|
+
ensure
|
871
|
+
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
test 'should set outfilesuffix to match file extension of target file' do
|
876
|
+
sample_input = '{outfilesuffix}'
|
877
|
+
sample_output_path = fixture_path('result.htm')
|
878
|
+
begin
|
879
|
+
Asciidoctor.convert sample_input, :to_file => sample_output_path, :header_footer => false
|
880
|
+
assert File.exist?(sample_output_path)
|
881
|
+
output = IO.read(sample_output_path)
|
882
|
+
refute_empty output
|
883
|
+
assert_includes output, '<p>.htm</p>'
|
884
|
+
ensure
|
885
|
+
FileUtils.rm(sample_output_path)
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
test 'output should be relative to to_dir option' do
|
890
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
891
|
+
output_dir = File.join(File.dirname(sample_input_path), 'test_output')
|
892
|
+
Dir.mkdir output_dir if !File.exist? output_dir
|
893
|
+
sample_output_path = File.join(output_dir, 'sample.html')
|
894
|
+
begin
|
895
|
+
Asciidoctor.convert_file sample_input_path, :to_dir => output_dir
|
896
|
+
assert File.exist? sample_output_path
|
897
|
+
ensure
|
898
|
+
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
899
|
+
FileUtils.rmdir output_dir
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
test 'missing directories should be created if mkdirs is enabled' do
|
904
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
905
|
+
output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
|
906
|
+
sample_output_path = File.join(output_dir, 'sample.html')
|
907
|
+
begin
|
908
|
+
Asciidoctor.convert_file sample_input_path, :to_dir => output_dir, :mkdirs => true
|
909
|
+
assert File.exist? sample_output_path
|
910
|
+
ensure
|
911
|
+
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
912
|
+
FileUtils.rmdir output_dir
|
913
|
+
FileUtils.rmdir File.dirname(output_dir)
|
914
|
+
end
|
915
|
+
end
|
916
|
+
|
917
|
+
# TODO need similar test for when to_dir is specified
|
918
|
+
test 'should raise exception if an attempt is made to overwrite input file' do
|
919
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
920
|
+
|
921
|
+
assert_raises IOError do
|
922
|
+
Asciidoctor.convert_file sample_input_path, :attributes => { 'outfilesuffix' => '.asciidoc' }
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
test 'to_file should be relative to to_dir when both given' do
|
927
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
928
|
+
base_dir = File.dirname(sample_input_path)
|
929
|
+
sample_rel_output_path = File.join('test_output', 'result.html')
|
930
|
+
output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
|
931
|
+
Dir.mkdir output_dir if !File.exist? output_dir
|
932
|
+
sample_output_path = File.join(base_dir, sample_rel_output_path)
|
933
|
+
begin
|
934
|
+
Asciidoctor.convert_file sample_input_path, :to_dir => base_dir, :to_file => sample_rel_output_path
|
935
|
+
assert File.exist? sample_output_path
|
936
|
+
ensure
|
937
|
+
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
|
938
|
+
FileUtils.rmdir output_dir
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
942
|
+
test 'should not modify options argument' do
|
943
|
+
options = {
|
944
|
+
:safe => Asciidoctor::SafeMode::SAFE,
|
945
|
+
:to_file => false
|
946
|
+
}
|
947
|
+
options.freeze
|
948
|
+
sample_input_path = fixture_path('sample.asciidoc')
|
949
|
+
begin
|
950
|
+
Asciidoctor.convert_file sample_input_path, options
|
951
|
+
rescue
|
952
|
+
flunk %(options argument should not be modified)
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
test 'should set to_dir option to parent directory of specified output file' do
|
957
|
+
sample_input_path = fixture_path 'basic.asciidoc'
|
958
|
+
sample_output_path = fixture_path 'basic.html'
|
959
|
+
begin
|
960
|
+
doc = Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
|
961
|
+
assert_equal File.dirname(sample_output_path), doc.options[:to_dir]
|
962
|
+
ensure
|
963
|
+
FileUtils.rm(sample_output_path)
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
test 'should set to_dir option to parent directory of specified output directory and file' do
|
968
|
+
sample_input_path = fixture_path 'basic.asciidoc'
|
969
|
+
sample_output_path = fixture_path 'basic.html'
|
970
|
+
fixture_base_path = File.dirname sample_output_path
|
971
|
+
fixture_parent_path = File.dirname fixture_base_path
|
972
|
+
sample_output_relpath = File.join 'fixtures', 'basic.html'
|
973
|
+
begin
|
974
|
+
doc = Asciidoctor.convert_file sample_input_path, :to_dir => fixture_parent_path, :to_file => sample_output_relpath
|
975
|
+
assert_equal fixture_base_path, doc.options[:to_dir]
|
976
|
+
ensure
|
977
|
+
FileUtils.rm(sample_output_path)
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
test 'timings are recorded for each step' do
|
982
|
+
sample_input_path = fixture_path 'asciidoc_index.txt'
|
983
|
+
Asciidoctor.convert_file sample_input_path, :timings => (timings = Asciidoctor::Timings.new), :to_file => false
|
984
|
+
refute_equal '0.00000', '%05.5f' % timings.read_parse.to_f
|
985
|
+
refute_equal '0.00000', '%05.5f' % timings.convert.to_f
|
986
|
+
refute_equal timings.read_parse, timings.total
|
987
|
+
end
|
988
|
+
end
|
989
|
+
|
990
|
+
context 'AST' do
|
991
|
+
test 'should not crash if nil cell text is passed to Cell constructor' do
|
992
|
+
input = <<-EOS
|
993
|
+
|===
|
994
|
+
|a
|
995
|
+
|===
|
996
|
+
EOS
|
997
|
+
table = (document_from_string input).blocks[0]
|
998
|
+
cell = Asciidoctor::Table::Cell.new table.rows.body[0][0].column, nil, {}
|
999
|
+
refute cell.style
|
1000
|
+
assert_same Asciidoctor::AbstractNode::NORMAL_SUBS, cell.subs
|
1001
|
+
assert_equal '', cell.text
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
end
|