asciidoctor 1.5.5 → 1.5.6
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 +216 -1
- data/CONTRIBUTING.adoc +2 -2
- data/Gemfile +20 -1
- data/LICENSE.adoc +1 -1
- data/README-fr.adoc +4 -3
- data/README-jp.adoc +11 -10
- data/README-zh_CN.adoc +4 -3
- data/README.adoc +17 -202
- data/Rakefile +41 -25
- data/asciidoctor.gemspec +9 -10
- data/data/locale/attributes.adoc +216 -34
- data/data/stylesheets/asciidoctor-default.css +23 -16
- data/features/step_definitions.rb +15 -19
- data/features/xref.feature +584 -20
- data/lib/asciidoctor.rb +292 -278
- data/lib/asciidoctor/abstract_block.rb +155 -94
- data/lib/asciidoctor/abstract_node.rb +108 -94
- data/lib/asciidoctor/attribute_list.rb +30 -22
- data/lib/asciidoctor/block.rb +7 -7
- data/lib/asciidoctor/cli/invoker.rb +47 -34
- data/lib/asciidoctor/cli/options.rb +22 -11
- data/lib/asciidoctor/converter.rb +3 -3
- data/lib/asciidoctor/converter/base.rb +2 -2
- data/lib/asciidoctor/converter/composite.rb +1 -1
- data/lib/asciidoctor/converter/docbook45.rb +2 -2
- data/lib/asciidoctor/converter/docbook5.rb +132 -87
- data/lib/asciidoctor/converter/factory.rb +0 -1
- data/lib/asciidoctor/converter/html5.rb +116 -98
- data/lib/asciidoctor/converter/manpage.rb +51 -52
- data/lib/asciidoctor/converter/template.rb +47 -36
- data/lib/asciidoctor/core_ext.rb +8 -2
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +4 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +5 -0
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +1 -1
- data/lib/asciidoctor/core_ext/1.8.7/string/{limit.rb → limit_bytesize.rb} +7 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +6 -0
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +1 -1
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +5 -5
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +3 -0
- data/lib/asciidoctor/core_ext/string/{limit.rb → limit_bytesize.rb} +2 -2
- data/lib/asciidoctor/document.rb +216 -213
- data/lib/asciidoctor/extensions.rb +318 -185
- data/lib/asciidoctor/helpers.rb +35 -35
- data/lib/asciidoctor/inline.rb +32 -1
- data/lib/asciidoctor/list.rb +22 -6
- data/lib/asciidoctor/parser.rb +1008 -1038
- data/lib/asciidoctor/path_resolver.rb +46 -50
- data/lib/asciidoctor/reader.rb +275 -251
- data/lib/asciidoctor/section.rb +86 -58
- data/lib/asciidoctor/stylesheets.rb +6 -6
- data/lib/asciidoctor/substitutors.rb +567 -649
- data/lib/asciidoctor/table.rb +163 -108
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +18 -16
- data/man/asciidoctor.adoc +15 -13
- data/test/attributes_test.rb +138 -22
- data/test/blocks_test.rb +377 -97
- data/test/converter_test.rb +13 -0
- data/test/document_test.rb +244 -34
- data/test/extensions_test.rb +409 -42
- data/test/fixtures/asciidoc_index.txt +521 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +5 -0
- data/test/fixtures/chapter-a.adoc +3 -0
- data/test/fixtures/child-include.adoc +5 -0
- data/test/fixtures/circle.svg +9 -0
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +6 -0
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +1 -0
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +3 -0
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +5 -0
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +6 -0
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +3 -0
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +5 -0
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +1 -0
- data/test/fixtures/custom-docinfodir/docinfo.html +1 -0
- data/test/fixtures/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +3 -0
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +13 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/hello-asciidoctor.pdf +69 -0
- data/test/fixtures/include-file.asciidoc +24 -0
- data/test/fixtures/include-file.ml +3 -0
- data/test/fixtures/include-file.xml +5 -0
- data/test/fixtures/master.adoc +5 -0
- data/test/fixtures/mismatched-end-tag.adoc +7 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/fixtures/sample.asciidoc +26 -0
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/fixtures/subs-docinfo.html +2 -0
- data/test/fixtures/subs.adoc +7 -0
- data/test/fixtures/tagged-class-enclosed.rb +26 -0
- data/test/fixtures/tagged-class.rb +23 -0
- data/test/fixtures/tip.gif +0 -0
- data/test/invoker_test.rb +82 -4
- data/test/links_test.rb +312 -37
- data/test/lists_test.rb +204 -25
- data/test/manpage_test.rb +191 -4
- data/test/options_test.rb +18 -1
- data/test/paragraphs_test.rb +32 -7
- data/test/parser_test.rb +150 -30
- data/test/paths_test.rb +47 -13
- data/test/preamble_test.rb +1 -1
- data/test/reader_test.rb +366 -126
- data/test/sections_test.rb +203 -56
- data/test/substitutions_test.rb +339 -131
- data/test/tables_test.rb +315 -15
- data/test/test_helper.rb +400 -0
- data/test/text_test.rb +5 -5
- metadata +110 -22
data/test/converter_test.rb
CHANGED
@@ -26,6 +26,19 @@ context 'Converter' do
|
|
26
26
|
assert_equal :xhtml, selected.templates['paragraph'].options[:format]
|
27
27
|
end
|
28
28
|
|
29
|
+
test 'should configure Slim to resolve includes in specified template dirs' do
|
30
|
+
template_dirs = [
|
31
|
+
File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'),
|
32
|
+
File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim-overrides'),
|
33
|
+
]
|
34
|
+
doc = Asciidoctor::Document.new [], :template_dirs => template_dirs, :template_cache => false
|
35
|
+
assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
|
36
|
+
selected = doc.converter.find_converter('paragraph')
|
37
|
+
assert selected.is_a? Asciidoctor::Converter::TemplateConverter
|
38
|
+
assert selected.templates['paragraph'].is_a? Slim::Template
|
39
|
+
assert_equal template_dirs.reverse.map {|dir| File.expand_path dir }, selected.templates['paragraph'].options[:include_dirs]
|
40
|
+
end
|
41
|
+
|
29
42
|
test 'should set Slim format to html for html5 backend' do
|
30
43
|
doc = Asciidoctor::Document.new [], :template_dir => File.join(File.dirname(__FILE__), 'fixtures', 'custom-backends', 'slim'), :template_cache => false
|
31
44
|
assert doc.converter.is_a?(Asciidoctor::Converter::CompositeConverter)
|
data/test/document_test.rb
CHANGED
@@ -13,6 +13,9 @@ context 'Document' do
|
|
13
13
|
doc = example_document(:asciidoc_index)
|
14
14
|
assert_equal 'AsciiDoc Home Page', doc.doctitle
|
15
15
|
assert_equal 'AsciiDoc Home Page', doc.name
|
16
|
+
refute_nil doc.header
|
17
|
+
assert_equal :section, doc.header.context
|
18
|
+
assert_equal 'header', doc.header.sectname
|
16
19
|
assert_equal 14, doc.blocks.size
|
17
20
|
assert_equal :preamble, doc.blocks[0].context
|
18
21
|
assert doc.blocks[1].context == :section
|
@@ -106,6 +109,18 @@ context 'Document' do
|
|
106
109
|
assert !doc.attr?('sectnums')
|
107
110
|
end
|
108
111
|
|
112
|
+
test 'noheader attribute should suppress info element when converting to DocBook' do
|
113
|
+
input = <<-EOS
|
114
|
+
= Document Title
|
115
|
+
:noheader:
|
116
|
+
|
117
|
+
content
|
118
|
+
EOS
|
119
|
+
result = render_string input, :backend => 'docbook'
|
120
|
+
assert_xpath '/article', result, 1
|
121
|
+
assert_xpath '/article/info', result, 0
|
122
|
+
end
|
123
|
+
|
109
124
|
test 'should be able to disable section numbering using numbered attribute in document header for DocBook backend' do
|
110
125
|
input = <<-EOS
|
111
126
|
= Document Title
|
@@ -119,10 +134,11 @@ context 'Document' do
|
|
119
134
|
context 'Load APIs' do
|
120
135
|
test 'should load input file' do
|
121
136
|
sample_input_path = fixture_path('sample.asciidoc')
|
122
|
-
doc =
|
137
|
+
doc = File.open(sample_input_path) {|file| Asciidoctor.load file, :safe => Asciidoctor::SafeMode::SAFE }
|
123
138
|
assert_equal 'Document Title', doc.doctitle
|
124
139
|
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
125
140
|
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
141
|
+
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
126
142
|
end
|
127
143
|
|
128
144
|
test 'should load input file from filename' do
|
@@ -131,6 +147,7 @@ context 'Document' do
|
|
131
147
|
assert_equal 'Document Title', doc.doctitle
|
132
148
|
assert_equal File.expand_path(sample_input_path), doc.attr('docfile')
|
133
149
|
assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir')
|
150
|
+
assert_equal '.asciidoc', doc.attr('docfilesuffix')
|
134
151
|
end
|
135
152
|
|
136
153
|
test 'should not load invalid file' do
|
@@ -204,8 +221,10 @@ preamble
|
|
204
221
|
end
|
205
222
|
|
206
223
|
test 'should accept attributes as string' do
|
207
|
-
|
208
|
-
|
224
|
+
doc = Asciidoctor.load('text', :attributes => 'toc sectnums
|
225
|
+
source-highlighter=coderay
|
226
|
+
idprefix
|
227
|
+
idseparator=-')
|
209
228
|
assert doc.attributes.is_a?(Hash)
|
210
229
|
assert doc.attr?('toc')
|
211
230
|
assert_equal '', doc.attr('toc')
|
@@ -220,15 +239,14 @@ preamble
|
|
220
239
|
end
|
221
240
|
|
222
241
|
test 'should accept values containing spaces in attributes string' do
|
223
|
-
|
224
|
-
doc = Asciidoctor.load('text', :attributes => 'idprefix idseparator=- note-caption=Note\ to\ self: toc')
|
242
|
+
doc = Asciidoctor.load('text', :attributes => %(idprefix idseparator=- note-caption=Note\\ to\\\tself toc))
|
225
243
|
assert doc.attributes.is_a?(Hash)
|
226
244
|
assert doc.attr?('idprefix')
|
227
245
|
assert_equal '', doc.attr('idprefix')
|
228
246
|
assert doc.attr?('idseparator')
|
229
247
|
assert_equal '-', doc.attr('idseparator')
|
230
248
|
assert doc.attr?('note-caption')
|
231
|
-
assert_equal "Note to
|
249
|
+
assert_equal "Note to\tself", doc.attr('note-caption')
|
232
250
|
end
|
233
251
|
|
234
252
|
test 'should accept attributes as empty string' do
|
@@ -343,6 +361,33 @@ preamble
|
|
343
361
|
assert_equal 1, section_1.lineno
|
344
362
|
end
|
345
363
|
|
364
|
+
test 'should assign correct source location if section occurs on last line of input' do
|
365
|
+
input = <<-EOS
|
366
|
+
= Document Title
|
367
|
+
|
368
|
+
== Section A
|
369
|
+
|
370
|
+
content
|
371
|
+
|
372
|
+
== Section B
|
373
|
+
EOS
|
374
|
+
|
375
|
+
doc = document_from_string input, :sourcemap => true
|
376
|
+
assert_equal [1, 3, 7], (doc.find_by :context => :section).map(&:lineno)
|
377
|
+
end
|
378
|
+
|
379
|
+
test 'should allow sourcemap option on document to be modified' do
|
380
|
+
doc = Asciidoctor.load_file fixture_path('sample.asciidoc'), :parse => false
|
381
|
+
doc.sourcemap = true
|
382
|
+
doc = doc.parse
|
383
|
+
|
384
|
+
section_1 = doc.sections[0]
|
385
|
+
assert_equal 'Section A', section_1.title
|
386
|
+
refute_nil section_1.source_location
|
387
|
+
assert_equal 'sample.asciidoc', section_1.file
|
388
|
+
assert_equal 10, section_1.lineno
|
389
|
+
end
|
390
|
+
|
346
391
|
test 'find_by should return Array of blocks anywhere in document tree that match criteria' do
|
347
392
|
input = <<-EOS
|
348
393
|
= Document Title
|
@@ -562,7 +607,7 @@ text
|
|
562
607
|
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
|
563
608
|
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
|
564
609
|
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
565
|
-
styles = stylenode.
|
610
|
+
styles = stylenode.content
|
566
611
|
assert !styles.nil?
|
567
612
|
assert !styles.strip.empty?
|
568
613
|
end
|
@@ -598,7 +643,7 @@ text
|
|
598
643
|
:safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss!' => ''}
|
599
644
|
assert_css 'html:root > head > style', output, 1
|
600
645
|
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
601
|
-
styles = stylenode.
|
646
|
+
styles = stylenode.content
|
602
647
|
assert !styles.nil?
|
603
648
|
assert !styles.strip.empty?
|
604
649
|
end
|
@@ -646,7 +691,7 @@ text
|
|
646
691
|
output = Asciidoctor.convert_file sample_input_path, :header_footer => true, :safe => Asciidoctor::SafeMode::SAFE, :to_file => false,
|
647
692
|
:attributes => {'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => ''}
|
648
693
|
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
|
649
|
-
styles = stylenode.
|
694
|
+
styles = stylenode.content
|
650
695
|
assert !styles.nil?
|
651
696
|
assert !styles.strip.empty?
|
652
697
|
end
|
@@ -657,7 +702,7 @@ text
|
|
657
702
|
begin
|
658
703
|
Asciidoctor.convert_file sample_input_path
|
659
704
|
assert File.exist?(sample_output_path)
|
660
|
-
output =
|
705
|
+
output = IO.read(sample_output_path)
|
661
706
|
assert !output.empty?
|
662
707
|
assert_xpath '/html', output, 1
|
663
708
|
assert_xpath '/html/head', output, 1
|
@@ -675,7 +720,7 @@ text
|
|
675
720
|
begin
|
676
721
|
Asciidoctor.convert_file sample_input_path, :to_file => sample_output_path
|
677
722
|
assert File.exist?(sample_output_path)
|
678
|
-
output =
|
723
|
+
output = IO.read(sample_output_path)
|
679
724
|
assert !output.empty?
|
680
725
|
assert_xpath '/html', output, 1
|
681
726
|
assert_xpath '/html/head', output, 1
|
@@ -694,7 +739,7 @@ text
|
|
694
739
|
begin
|
695
740
|
Asciidoctor.convert_file sample_input_path, :to_file => 'result.html', :base_dir => fixture_dir
|
696
741
|
assert File.exist?(sample_output_path)
|
697
|
-
output =
|
742
|
+
output = IO.read(sample_output_path)
|
698
743
|
assert !output.empty?
|
699
744
|
assert_xpath '/html', output, 1
|
700
745
|
assert_xpath '/html/head', output, 1
|
@@ -1001,14 +1046,32 @@ text
|
|
1001
1046
|
assert_css 'copyright', output, 0
|
1002
1047
|
end
|
1003
1048
|
|
1004
|
-
test 'should
|
1005
|
-
sample_input_path = fixture_path
|
1049
|
+
test 'should substitute attributes in docinfo files by default' do
|
1050
|
+
sample_input_path = fixture_path 'subs.adoc'
|
1051
|
+
output, warnings = redirect_streams do |_, err|
|
1052
|
+
output = Asciidoctor.convert_file sample_input_path,
|
1053
|
+
:to_file => false,
|
1054
|
+
:header_footer => true,
|
1055
|
+
:safe => :server,
|
1056
|
+
:attributes => { 'docinfo' => '', 'bootstrap-version' => nil, 'linkcss' => '', 'attribute-missing' => 'drop-line' }
|
1057
|
+
[output, err.string]
|
1058
|
+
end
|
1059
|
+
refute output.empty?
|
1060
|
+
assert_css 'script', output, 0
|
1061
|
+
assert_xpath %(//meta[@name="copyright"][@content="(C) OpenDevise"]), output, 1
|
1062
|
+
assert_includes warnings, 'dropping line containing reference to missing attribute'
|
1063
|
+
end
|
1006
1064
|
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1065
|
+
test 'should apply explicit substitutions to docinfo files' do
|
1066
|
+
sample_input_path = fixture_path 'subs.adoc'
|
1067
|
+
output = Asciidoctor.convert_file sample_input_path,
|
1068
|
+
:to_file => false,
|
1069
|
+
:header_footer => true,
|
1070
|
+
:safe => :server,
|
1071
|
+
:attributes => { 'docinfo' => '', 'docinfosubs' => 'attributes,replacements', 'linkcss' => '' }
|
1072
|
+
refute output.empty?
|
1010
1073
|
assert_css 'script[src="bootstrap.3.2.0.min.js"]', output, 1
|
1011
|
-
assert_xpath %(//meta[@name="copyright"][@content="#{
|
1074
|
+
assert_xpath %(//meta[@name="copyright"][@content="#{decode_char 169} OpenDevise"]), output, 1
|
1012
1075
|
end
|
1013
1076
|
end
|
1014
1077
|
|
@@ -1063,6 +1126,19 @@ text
|
|
1063
1126
|
assert converter.respond_to? element
|
1064
1127
|
end
|
1065
1128
|
end
|
1129
|
+
|
1130
|
+
test 'should add favicon if favicon attribute is set' do
|
1131
|
+
{
|
1132
|
+
'' => %w(favicon.ico image/x-icon),
|
1133
|
+
'/favicon.ico' => %w(/favicon.ico image/x-icon),
|
1134
|
+
'/img/favicon.png' => %w(/img/favicon.png image/png)
|
1135
|
+
}.each {|val, (href, type)|
|
1136
|
+
result = render_string %(= Untitled), :attributes => { 'favicon' => val }
|
1137
|
+
assert_css 'link[rel="shortcut icon"]', result, 1
|
1138
|
+
assert_css %(link[rel="shortcut icon"][href="#{href}"]), result, 1
|
1139
|
+
assert_css %(link[rel="shortcut icon"][type="#{type}"]), result, 1
|
1140
|
+
}
|
1141
|
+
end
|
1066
1142
|
end
|
1067
1143
|
|
1068
1144
|
context 'Structure' do
|
@@ -1074,6 +1150,50 @@ text
|
|
1074
1150
|
assert_nil doc.header
|
1075
1151
|
end
|
1076
1152
|
|
1153
|
+
test 'should enable compat mode for document with legacy doctitle' do
|
1154
|
+
input = <<-EOS
|
1155
|
+
Document Title
|
1156
|
+
==============
|
1157
|
+
|
1158
|
+
+content+
|
1159
|
+
EOS
|
1160
|
+
|
1161
|
+
doc = document_from_string input
|
1162
|
+
assert(doc.attr? 'compat-mode')
|
1163
|
+
result = doc.convert
|
1164
|
+
assert_xpath '//code[text()="content"]', result, 1
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
test 'should not enable compat mode for document with legacy doctitle if compat mode disable by header' do
|
1168
|
+
input = <<-EOS
|
1169
|
+
Document Title
|
1170
|
+
==============
|
1171
|
+
:compat-mode!:
|
1172
|
+
|
1173
|
+
+content+
|
1174
|
+
EOS
|
1175
|
+
|
1176
|
+
doc = document_from_string input
|
1177
|
+
assert_nil(doc.attr 'compat-mode')
|
1178
|
+
result = doc.convert
|
1179
|
+
assert_xpath '//code[text()="content"]', result, 0
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
test 'should not enable compat mode for document with legacy doctitle if compat mode is locked by API' do
|
1183
|
+
input = <<-EOS
|
1184
|
+
Document Title
|
1185
|
+
==============
|
1186
|
+
|
1187
|
+
+content+
|
1188
|
+
EOS
|
1189
|
+
|
1190
|
+
doc = document_from_string input, :attributes => { 'compat-mode' => nil }
|
1191
|
+
assert(doc.attribute_locked? 'compat-mode')
|
1192
|
+
assert_nil(doc.attr 'compat-mode')
|
1193
|
+
result = doc.convert
|
1194
|
+
assert_xpath '//code[text()="content"]', result, 0
|
1195
|
+
end
|
1196
|
+
|
1077
1197
|
test 'title partition API with default separator' do
|
1078
1198
|
title = Asciidoctor::Document::Title.new 'Main Title: And More: Subtitle'
|
1079
1199
|
assert_equal 'Main Title: And More', title.main
|
@@ -1119,6 +1239,23 @@ content
|
|
1119
1239
|
assert_equal 'Subtitle', title.subtitle
|
1120
1240
|
end
|
1121
1241
|
|
1242
|
+
test 'should not honor custom separator for doctitle if attribute is locked by API' do
|
1243
|
+
input = <<-EOS
|
1244
|
+
[separator=::]
|
1245
|
+
= Main Title - *Subtitle*
|
1246
|
+
Author Name
|
1247
|
+
|
1248
|
+
content
|
1249
|
+
EOS
|
1250
|
+
|
1251
|
+
doc = document_from_string input, :attributes => { 'title-separator' => ' -' }
|
1252
|
+
title = doc.doctitle :partition => true, :sanitize => true
|
1253
|
+
assert title.subtitle?
|
1254
|
+
assert title.sanitized?
|
1255
|
+
assert_equal 'Main Title', title.main
|
1256
|
+
assert_equal 'Subtitle', title.subtitle
|
1257
|
+
end
|
1258
|
+
|
1122
1259
|
test 'document with doctitle defined as attribute entry' do
|
1123
1260
|
input = <<-EOS
|
1124
1261
|
:doctitle: Document Title
|
@@ -1251,7 +1388,7 @@ content
|
|
1251
1388
|
|
1252
1389
|
output = render_string input
|
1253
1390
|
assert_xpath '/html/head/title[text()="Document Title"]', output, 1
|
1254
|
-
nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output
|
1391
|
+
nodes = xmlnodes_at_xpath('//*[@id="header"]/h1', output)
|
1255
1392
|
assert_equal 1, nodes.size
|
1256
1393
|
assert_match('<h1><strong>Document</strong> <span class="image"><img src="logo.png" alt="logo"></span> <em>Title</em> <span class="image"><img src="another-logo.png" alt="another logo"></span></h1>', output)
|
1257
1394
|
end
|
@@ -1404,6 +1541,18 @@ content
|
|
1404
1541
|
assert_xpath '//articleinfo/authorinitials[text() = "DW"]', output, 1
|
1405
1542
|
end
|
1406
1543
|
|
1544
|
+
test 'should sanitize content of HTML meta authors tag' do
|
1545
|
+
input = <<-EOS
|
1546
|
+
= Document Title
|
1547
|
+
:author: pass:n[http://example.org/community/team.html[Ze *Product* team]]
|
1548
|
+
|
1549
|
+
content
|
1550
|
+
EOS
|
1551
|
+
|
1552
|
+
output = render_string input
|
1553
|
+
assert_xpath '//meta[@name="author"][@content="Ze Product team"]', output, 1
|
1554
|
+
end
|
1555
|
+
|
1407
1556
|
test 'should include multiple authors in HTML output' do
|
1408
1557
|
input = <<-EOS
|
1409
1558
|
= Document Title
|
@@ -1564,11 +1713,11 @@ finally a reference to the second footnote footnoteref:[note2].
|
|
1564
1713
|
assert_css '#footnotes .footnote', output, 2
|
1565
1714
|
assert_css '#footnotes .footnote#_footnote_1', output, 1
|
1566
1715
|
assert_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
|
1567
|
-
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
|
1716
|
+
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
|
1568
1717
|
assert_equal '. An example footnote.', text.text.strip
|
1569
1718
|
assert_css '#footnotes .footnote#_footnote_2', output, 1
|
1570
1719
|
assert_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/a[@href="#_footnoteref_2"][text()="2"]', output, 1
|
1571
|
-
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/text()', output
|
1720
|
+
text = xmlnodes_at_xpath '//div[@id="footnotes"]/div[@id="_footnote_2"]/text()', output
|
1572
1721
|
assert_equal '. Second footnote.', text.text.strip
|
1573
1722
|
end
|
1574
1723
|
|
@@ -1582,7 +1731,7 @@ Text that has supporting information{empty}footnote:[An example footnote.].
|
|
1582
1731
|
assert_css '#footnotes .footnote', output, 1
|
1583
1732
|
assert_css '#footnotes .footnote#_footnote_1', output, 1
|
1584
1733
|
assert_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/a[@href="#_footnoteref_1"][text()="1"]', output, 1
|
1585
|
-
text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
|
1734
|
+
text = xmlnodes_at_xpath '/div[@id="footnotes"]/div[@id="_footnote_1"]/text()', output
|
1586
1735
|
assert_equal '. An example footnote.', text.text.strip
|
1587
1736
|
end
|
1588
1737
|
|
@@ -1596,6 +1745,30 @@ Text that has supporting information{empty}footnote:[An example footnote.].
|
|
1596
1745
|
end
|
1597
1746
|
end
|
1598
1747
|
|
1748
|
+
context 'Catalog' do
|
1749
|
+
test 'document catalog is aliased as references' do
|
1750
|
+
input = <<-EOS
|
1751
|
+
= Document Title
|
1752
|
+
|
1753
|
+
== Section A
|
1754
|
+
|
1755
|
+
content
|
1756
|
+
|
1757
|
+
== Section B
|
1758
|
+
|
1759
|
+
content{blank}footnote:[commentary]
|
1760
|
+
EOS
|
1761
|
+
|
1762
|
+
doc = document_from_string input
|
1763
|
+
refute_nil doc.catalog
|
1764
|
+
assert_equal [:footnotes, :ids, :images, :includes, :indexterms, :links, :refs].to_set, doc.catalog.keys.to_set
|
1765
|
+
assert_same doc.catalog, doc.references
|
1766
|
+
assert_same doc.catalog[:footnotes], doc.references[:footnotes]
|
1767
|
+
assert_same doc.catalog[:ids], doc.references[:ids]
|
1768
|
+
assert_equal 'Section A', doc.references[:ids]['_section_a']
|
1769
|
+
end
|
1770
|
+
end
|
1771
|
+
|
1599
1772
|
context 'Backends and Doctypes' do
|
1600
1773
|
test 'html5 backend doctype article' do
|
1601
1774
|
result = render_string("= Title\n\nparagraph", :attributes => {'backend' => 'html5'})
|
@@ -1850,14 +2023,14 @@ section body
|
|
1850
2023
|
EOS
|
1851
2024
|
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5'})
|
1852
2025
|
assert_xpath '/xmlns:article', result, 1
|
1853
|
-
doc = xmlnodes_at_xpath('/xmlns:article', result, 1)
|
2026
|
+
doc = xmlnodes_at_xpath('/xmlns:article', result, 1)
|
1854
2027
|
assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
|
1855
2028
|
assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
|
1856
2029
|
assert_xpath '/xmlns:article[@version="5.0"]', result, 1
|
1857
2030
|
assert_xpath '/xmlns:article/xmlns:info/xmlns:title[text() = "Title"]', result, 1
|
1858
2031
|
assert_xpath '/xmlns:article/xmlns:simpara[text() = "preamble"]', result, 1
|
1859
2032
|
assert_xpath '/xmlns:article/xmlns:section', result, 1
|
1860
|
-
section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1)
|
2033
|
+
section = xmlnodes_at_xpath('/xmlns:article/xmlns:section', result, 1)
|
1861
2034
|
# nokogiri can't make up its mind
|
1862
2035
|
id_attr = section.attribute('id') || section.attribute('xml:id')
|
1863
2036
|
refute_nil id_attr
|
@@ -1884,7 +2057,7 @@ section body
|
|
1884
2057
|
EOS
|
1885
2058
|
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'manpage'})
|
1886
2059
|
assert_xpath '/xmlns:refentry', result, 1
|
1887
|
-
doc = xmlnodes_at_xpath('/xmlns:refentry', result, 1)
|
2060
|
+
doc = xmlnodes_at_xpath('/xmlns:refentry', result, 1)
|
1888
2061
|
assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
|
1889
2062
|
assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
|
1890
2063
|
assert_xpath '/xmlns:refentry[@version="5.0"]', result, 1
|
@@ -1896,7 +2069,7 @@ section body
|
|
1896
2069
|
assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv', result, 1
|
1897
2070
|
assert_xpath '/xmlns:refentry/xmlns:refsynopsisdiv/xmlns:simpara[text() = "some text"]', result, 1
|
1898
2071
|
assert_xpath '/xmlns:refentry/xmlns:refsection', result, 1
|
1899
|
-
section = xmlnodes_at_xpath('/xmlns:refentry/xmlns:refsection', result, 1)
|
2072
|
+
section = xmlnodes_at_xpath('/xmlns:refentry/xmlns:refsection', result, 1)
|
1900
2073
|
# nokogiri can't make up its mind
|
1901
2074
|
id_attr = section.attribute('id') || section.attribute('xml:id')
|
1902
2075
|
refute_nil id_attr
|
@@ -1918,14 +2091,14 @@ chapter body
|
|
1918
2091
|
EOS
|
1919
2092
|
result = render_string(input, :keep_namespaces => true, :attributes => {'backend' => 'docbook5', 'doctype' => 'book'})
|
1920
2093
|
assert_xpath '/xmlns:book', result, 1
|
1921
|
-
doc = xmlnodes_at_xpath('/xmlns:book', result, 1)
|
2094
|
+
doc = xmlnodes_at_xpath('/xmlns:book', result, 1)
|
1922
2095
|
assert_equal 'http://docbook.org/ns/docbook', doc.namespaces['xmlns']
|
1923
2096
|
assert_equal 'http://www.w3.org/1999/xlink', doc.namespaces['xmlns:xl']
|
1924
2097
|
assert_xpath '/xmlns:book[@version="5.0"]', result, 1
|
1925
2098
|
assert_xpath '/xmlns:book/xmlns:info/xmlns:title[text() = "Title"]', result, 1
|
1926
2099
|
assert_xpath '/xmlns:book/xmlns:preface/xmlns:simpara[text() = "preamble"]', result, 1
|
1927
2100
|
assert_xpath '/xmlns:book/xmlns:chapter', result, 1
|
1928
|
-
chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1)
|
2101
|
+
chapter = xmlnodes_at_xpath('/xmlns:book/xmlns:chapter', result, 1)
|
1929
2102
|
# nokogiri can't make up its mind
|
1930
2103
|
id_attr = chapter.attribute('id') || chapter.attribute('xml:id')
|
1931
2104
|
refute_nil id_attr
|
@@ -1934,6 +2107,28 @@ chapter body
|
|
1934
2107
|
assert_equal '_first_chapter', id_attr.value
|
1935
2108
|
end
|
1936
2109
|
|
2110
|
+
test 'adds a front and back cover image to DocBook 5 when doctype is book' do
|
2111
|
+
input = <<-EOS
|
2112
|
+
= Title
|
2113
|
+
:doctype: book
|
2114
|
+
:imagesdir: images
|
2115
|
+
:front-cover-image: image:front-cover.jpg[scaledwidth=210mm]
|
2116
|
+
:back-cover-image: image:back-cover.jpg[scaledwidth=210mm]
|
2117
|
+
|
2118
|
+
preamble
|
2119
|
+
|
2120
|
+
== First Chapter
|
2121
|
+
|
2122
|
+
chapter body
|
2123
|
+
EOS
|
2124
|
+
|
2125
|
+
result = render_string input, :attributes => {'backend' => 'docbook5'}
|
2126
|
+
assert_xpath '//info/cover[@role="front"]', result, 1
|
2127
|
+
assert_xpath '//info/cover[@role="front"]//imagedata[@fileref="images/front-cover.jpg"]', result, 1
|
2128
|
+
assert_xpath '//info/cover[@role="back"]', result, 1
|
2129
|
+
assert_xpath '//info/cover[@role="back"]//imagedata[@fileref="images/back-cover.jpg"]', result, 1
|
2130
|
+
end
|
2131
|
+
|
1937
2132
|
test 'should be able to set backend using :backend option key' do
|
1938
2133
|
doc = empty_document :backend => 'html5'
|
1939
2134
|
assert_equal 'html5', doc.attributes['backend']
|
@@ -2115,7 +2310,7 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2115
2310
|
*asciidoctor* ['OPTION']... 'FILE'..
|
2116
2311
|
EOS
|
2117
2312
|
|
2118
|
-
output =
|
2313
|
+
output = render_embedded_string input
|
2119
2314
|
assert_xpath '/h1[text()="asciidoctor(1) Manual Page"]', output, 1
|
2120
2315
|
assert_xpath '/h1/following-sibling::h2[text()="NAME"]', output, 1
|
2121
2316
|
assert_xpath '/h2[text()="NAME"]/following-sibling::*[@class="sectionbody"]', output, 1
|
@@ -2141,20 +2336,35 @@ asciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats
|
|
2141
2336
|
test 'keeps naughty relative paths from getting outside' do
|
2142
2337
|
naughty_path = 'safe/ok/../../../../../etc/passwd'
|
2143
2338
|
doc = empty_document
|
2144
|
-
secure_path = doc.normalize_asset_path(naughty_path)
|
2339
|
+
secure_path = redirect_streams { doc.normalize_asset_path(naughty_path) }
|
2145
2340
|
assert naughty_path != secure_path
|
2146
2341
|
assert_match(/^#{doc.base_dir}/, secure_path)
|
2147
2342
|
end
|
2148
2343
|
|
2149
|
-
test 'should raise an exception when a converter cannot be resolved' do
|
2344
|
+
test 'should raise an exception when a converter cannot be resolved before conversion' do
|
2345
|
+
input = <<-EOS
|
2346
|
+
= Document Title
|
2347
|
+
|
2348
|
+
text
|
2349
|
+
EOS
|
2350
|
+
exception = assert_raises NotImplementedError do
|
2351
|
+
Asciidoctor.convert input, :backend => 'unknownBackend'
|
2352
|
+
end
|
2353
|
+
assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
|
2354
|
+
end
|
2355
|
+
|
2356
|
+
test 'should raise an exception when a converter cannot be resolved while parsing' do
|
2150
2357
|
input = <<-EOS
|
2151
2358
|
= Document Title
|
2359
|
+
|
2360
|
+
== A _Big_ Section
|
2361
|
+
|
2152
2362
|
text
|
2153
2363
|
EOS
|
2154
|
-
exception = assert_raises
|
2155
|
-
Asciidoctor.
|
2364
|
+
exception = assert_raises NotImplementedError do
|
2365
|
+
Asciidoctor.convert input, :backend => 'unknownBackend'
|
2156
2366
|
end
|
2157
|
-
|
2367
|
+
assert_includes exception.message, 'missing converter for backend \'unknownBackend\''
|
2158
2368
|
end
|
2159
2369
|
end
|
2160
2370
|
|