asciidoctor 0.1.3 → 0.1.4
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 +387 -0
- data/README.adoc +358 -348
- data/asciidoctor.gemspec +30 -9
- data/bin/asciidoctor +3 -0
- data/bin/asciidoctor-safe +3 -0
- data/compat/asciidoc.conf +76 -4
- data/lib/asciidoctor.rb +174 -79
- data/lib/asciidoctor/abstract_block.rb +131 -101
- data/lib/asciidoctor/abstract_node.rb +108 -26
- data/lib/asciidoctor/attribute_list.rb +1 -1
- data/lib/asciidoctor/backends/_stylesheets.rb +204 -62
- data/lib/asciidoctor/backends/base_template.rb +11 -22
- data/lib/asciidoctor/backends/docbook45.rb +158 -163
- data/lib/asciidoctor/backends/docbook5.rb +103 -0
- data/lib/asciidoctor/backends/html5.rb +662 -445
- data/lib/asciidoctor/block.rb +54 -44
- data/lib/asciidoctor/cli/invoker.rb +41 -20
- data/lib/asciidoctor/cli/options.rb +66 -20
- data/lib/asciidoctor/debug.rb +1 -1
- data/lib/asciidoctor/document.rb +265 -100
- data/lib/asciidoctor/extensions.rb +443 -0
- data/lib/asciidoctor/helpers.rb +38 -6
- data/lib/asciidoctor/inline.rb +5 -5
- data/lib/asciidoctor/lexer.rb +532 -250
- data/lib/asciidoctor/{list_item.rb → list.rb} +33 -13
- data/lib/asciidoctor/path_resolver.rb +28 -2
- data/lib/asciidoctor/reader.rb +814 -455
- data/lib/asciidoctor/renderer.rb +128 -42
- data/lib/asciidoctor/section.rb +55 -41
- data/lib/asciidoctor/substituters.rb +380 -107
- data/lib/asciidoctor/table.rb +40 -30
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +32 -96
- data/man/{asciidoctor.ad → asciidoctor.adoc} +57 -48
- data/test/attributes_test.rb +200 -27
- data/test/blocks_test.rb +361 -22
- data/test/document_test.rb +496 -81
- data/test/extensions_test.rb +448 -0
- data/test/fixtures/basic-docinfo-footer.html +6 -0
- data/test/fixtures/basic-docinfo-footer.xml +8 -0
- data/test/fixtures/basic-docinfo.xml +3 -3
- data/test/fixtures/basic.asciidoc +1 -0
- data/test/fixtures/child-include.adoc +5 -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/docinfo-footer.html +1 -0
- data/test/fixtures/docinfo-footer.xml +9 -0
- data/test/fixtures/docinfo.xml +1 -0
- data/test/fixtures/grandchild-include.adoc +3 -0
- data/test/fixtures/parent-include-restricted.adoc +5 -0
- data/test/fixtures/parent-include.adoc +5 -0
- data/test/invoker_test.rb +82 -8
- data/test/lexer_test.rb +21 -3
- data/test/links_test.rb +34 -2
- data/test/lists_test.rb +304 -7
- data/test/options_test.rb +19 -3
- data/test/paragraphs_test.rb +13 -0
- data/test/paths_test.rb +22 -0
- data/test/preamble_test.rb +20 -0
- data/test/reader_test.rb +1096 -644
- data/test/renderer_test.rb +152 -12
- data/test/sections_test.rb +417 -76
- data/test/substitutions_test.rb +339 -138
- data/test/tables_test.rb +109 -4
- data/test/test_helper.rb +79 -13
- data/test/text_test.rb +111 -11
- metadata +54 -18
data/test/attributes_test.rb
CHANGED
@@ -22,11 +22,31 @@ context 'Attributes' do
|
|
22
22
|
assert_equal 'This is the first Ruby implementation of AsciiDoc.', doc.attributes['description']
|
23
23
|
end
|
24
24
|
|
25
|
-
test '
|
25
|
+
test 'should delete an attribute that ends with !' do
|
26
26
|
doc = document_from_string(":frog: Tanglefoot\n:frog!:")
|
27
27
|
assert_equal nil, doc.attributes['frog']
|
28
28
|
end
|
29
29
|
|
30
|
+
test 'should delete an attribute that ends with ! set via API' do
|
31
|
+
doc = document_from_string(":frog: Tanglefoot", :attributes => {'frog!' => ''})
|
32
|
+
assert_equal nil, doc.attributes['frog']
|
33
|
+
end
|
34
|
+
|
35
|
+
test 'should delete an attribute that begins with !' do
|
36
|
+
doc = document_from_string(":frog: Tanglefoot\n:!frog:")
|
37
|
+
assert_equal nil, doc.attributes['frog']
|
38
|
+
end
|
39
|
+
|
40
|
+
test 'should delete an attribute that begins with ! set via API' do
|
41
|
+
doc = document_from_string(":frog: Tanglefoot", :attributes => {'!frog' => ''})
|
42
|
+
assert_equal nil, doc.attributes['frog']
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'should delete an attribute set via API to nil value' do
|
46
|
+
doc = document_from_string(":frog: Tanglefoot", :attributes => {'frog' => nil})
|
47
|
+
assert_equal nil, doc.attributes['frog']
|
48
|
+
end
|
49
|
+
|
30
50
|
test "doesn't choke when deleting a non-existing attribute" do
|
31
51
|
doc = document_from_string(':frog!:')
|
32
52
|
assert_equal nil, doc.attributes['frog']
|
@@ -43,12 +63,12 @@ context 'Attributes' do
|
|
43
63
|
end
|
44
64
|
|
45
65
|
test "assigns attribute to empty string if substitution fails to resolve attribute" do
|
46
|
-
doc = document_from_string
|
66
|
+
doc = document_from_string ":release: Asciidoctor {version}", :attributes => { 'attribute-missing' => 'drop-line' }
|
47
67
|
assert_equal '', doc.attributes['release']
|
48
68
|
end
|
49
69
|
|
50
70
|
test "assigns multi-line attribute to empty string if substitution fails to resolve attribute" do
|
51
|
-
doc = document_from_string
|
71
|
+
doc = document_from_string ":release: Asciidoctor +\n {version}", :attributes => { 'attribute-missing' => 'drop-line' }
|
52
72
|
assert_equal '', doc.attributes['release']
|
53
73
|
end
|
54
74
|
|
@@ -124,8 +144,16 @@ endif::holygrail[]
|
|
124
144
|
end
|
125
145
|
|
126
146
|
test 'attribute lookup is not case sensitive' do
|
127
|
-
|
128
|
-
|
147
|
+
input = <<-EOS
|
148
|
+
:He-Man: The most powerful man in the universe
|
149
|
+
|
150
|
+
He-Man: {He-Man}
|
151
|
+
|
152
|
+
She-Ra: {She-Ra}
|
153
|
+
EOS
|
154
|
+
result = render_embedded_string input, :attributes => {'She-Ra' => 'The Princess of Power'}
|
155
|
+
assert_xpath '//p[text()="He-Man: The most powerful man in the universe"]', result, 1
|
156
|
+
assert_xpath '//p[text()="She-Ra: The Princess of Power"]', result, 1
|
129
157
|
end
|
130
158
|
|
131
159
|
test "render properly with single character name" do
|
@@ -134,7 +162,7 @@ endif::holygrail[]
|
|
134
162
|
assert_equal 'R is for Ruby!', result.css("p").first.content.strip
|
135
163
|
end
|
136
164
|
|
137
|
-
test "
|
165
|
+
test "collapses spaces in attribute names" do
|
138
166
|
input = <<-EOS
|
139
167
|
Main Header
|
140
168
|
===========
|
@@ -146,8 +174,15 @@ Yo, {myfrog}!
|
|
146
174
|
assert_xpath '(//p)[1][text()="Yo, Tanglefoot!"]', output, 1
|
147
175
|
end
|
148
176
|
|
149
|
-
test "ignores lines with bad attributes" do
|
150
|
-
|
177
|
+
test "ignores lines with bad attributes if attribute-missing is drop-line" do
|
178
|
+
input = <<-EOS
|
179
|
+
:attribute-missing: drop-line
|
180
|
+
|
181
|
+
This is
|
182
|
+
blah blah {foobarbaz}
|
183
|
+
all there is.
|
184
|
+
EOS
|
185
|
+
html = render_embedded_string input
|
151
186
|
result = Nokogiri::HTML(html)
|
152
187
|
assert_no_match(/blah blah/m, result.css("p").first.content.strip)
|
153
188
|
end
|
@@ -159,14 +194,58 @@ Yo, {myfrog}!
|
|
159
194
|
assert_xpath '//a[@href="http://google.com"][text() = "Google"]', output, 1
|
160
195
|
end
|
161
196
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
197
|
+
test 'should drop line with reference to missing attribute if attribute-missing attribute is drop-line' do
|
198
|
+
input = <<-EOS
|
199
|
+
:attribute-missing: drop-line
|
200
|
+
|
201
|
+
Line 1: This line should appear in the output.
|
202
|
+
Line 2: Oh no, a {bogus-attribute}! This line should not appear in the output.
|
203
|
+
EOS
|
204
|
+
|
205
|
+
output = render_embedded_string input
|
206
|
+
assert_match(/Line 1/, output)
|
207
|
+
assert_no_match(/Line 2/, output)
|
208
|
+
end
|
209
|
+
|
210
|
+
test 'should not drop line with reference to missing attribute by default' do
|
211
|
+
input = <<-EOS
|
212
|
+
Line 1: This line should appear in the output.
|
213
|
+
Line 2: A {bogus-attribute}! This time, this line should appear in the output.
|
214
|
+
EOS
|
215
|
+
|
216
|
+
output = render_embedded_string input
|
217
|
+
assert_match(/Line 1/, output)
|
218
|
+
assert_match(/Line 2/, output)
|
219
|
+
assert_match(/\{bogus-attribute\}/, output)
|
220
|
+
end
|
221
|
+
|
222
|
+
test 'should drop line with attribute unassignment by default' do
|
223
|
+
input = <<-EOS
|
224
|
+
:a:
|
225
|
+
|
226
|
+
Line 1: This line should appear in the output.
|
227
|
+
Line 2: {set:a!}This line should not appear in the output.
|
228
|
+
EOS
|
229
|
+
|
230
|
+
output = render_embedded_string input
|
231
|
+
assert_match(/Line 1/, output)
|
232
|
+
assert_no_match(/Line 2/, output)
|
233
|
+
end
|
234
|
+
|
235
|
+
test 'should not drop line with attribute unassignment if attribute-undefined is drop' do
|
236
|
+
input = <<-EOS
|
237
|
+
:attribute-undefined: drop
|
238
|
+
:a:
|
239
|
+
|
240
|
+
Line 1: This line should appear in the output.
|
241
|
+
Line 2: {set:a!}This line should not appear in the output.
|
242
|
+
EOS
|
243
|
+
|
244
|
+
output = render_embedded_string input
|
245
|
+
assert_match(/Line 1/, output)
|
246
|
+
assert_match(/Line 2/, output)
|
247
|
+
assert_no_match(/\{set:a!\}/, output)
|
248
|
+
end
|
170
249
|
|
171
250
|
test "substitutes inside unordered list items" do
|
172
251
|
html = render_string(":foo: bar\n* snort at the {foo}\n* yawn")
|
@@ -355,7 +434,13 @@ of the attribute named foo in your document.
|
|
355
434
|
end
|
356
435
|
|
357
436
|
test 'unassigns attribute defined in attribute reference with set prefix' do
|
358
|
-
input =
|
437
|
+
input = <<-EOS
|
438
|
+
:attribute-missing: drop-line
|
439
|
+
:foo:
|
440
|
+
|
441
|
+
{set:foo!}
|
442
|
+
{foo}yes
|
443
|
+
EOS
|
359
444
|
output = render_embedded_string input
|
360
445
|
assert_xpath '//p', output, 1
|
361
446
|
assert_xpath '//p/child::text()', output, 0
|
@@ -466,8 +551,9 @@ ____
|
|
466
551
|
EOS
|
467
552
|
doc = document_from_string(input)
|
468
553
|
qb = doc.blocks.first
|
469
|
-
assert_equal 'quote', qb.
|
470
|
-
assert_equal '
|
554
|
+
assert_equal 'quote', qb.style
|
555
|
+
assert_equal 'author', qb.attr('attribution')
|
556
|
+
assert_equal 'author', qb.attr(:attribution)
|
471
557
|
assert_equal 'author', qb.attributes['attribution']
|
472
558
|
assert_equal 'source', qb.attributes['citetitle']
|
473
559
|
end
|
@@ -481,8 +567,9 @@ ____
|
|
481
567
|
EOS
|
482
568
|
doc = document_from_string(input)
|
483
569
|
qb = doc.blocks.first
|
484
|
-
assert_equal 'quote', qb.
|
485
|
-
assert_equal '
|
570
|
+
assert_equal 'quote', qb.style
|
571
|
+
assert_equal 'author', qb.attr('attribution')
|
572
|
+
assert_equal 'author', qb.attr(:attribution)
|
486
573
|
assert_equal 'author', qb.attributes['attribution']
|
487
574
|
assert_equal '<a href="http://wikipedia.org">source</a>', qb.attributes['citetitle']
|
488
575
|
end
|
@@ -497,7 +584,7 @@ ____
|
|
497
584
|
|
498
585
|
doc = document_from_string input
|
499
586
|
qb = doc.blocks.first
|
500
|
-
assert_equal 'quote', qb.
|
587
|
+
assert_equal 'quote', qb.style
|
501
588
|
end
|
502
589
|
|
503
590
|
test 'attribute list may begin with comma' do
|
@@ -510,7 +597,7 @@ ____
|
|
510
597
|
|
511
598
|
doc = document_from_string input
|
512
599
|
qb = doc.blocks.first
|
513
|
-
assert_equal 'quote', qb.
|
600
|
+
assert_equal 'quote', qb.style
|
514
601
|
assert_equal 'author', qb.attributes['attribution']
|
515
602
|
assert_equal 'source', qb.attributes['citetitle']
|
516
603
|
end
|
@@ -525,7 +612,7 @@ ____
|
|
525
612
|
|
526
613
|
doc = document_from_string input
|
527
614
|
qb = doc.blocks.first
|
528
|
-
assert_equal 'quote', qb.
|
615
|
+
assert_equal 'quote', qb.style
|
529
616
|
assert_equal 'author', qb.attributes['attribution']
|
530
617
|
assert_equal 'source', qb.attributes['citetitle']
|
531
618
|
assert_equal 'famous', qb.attributes['role']
|
@@ -541,12 +628,69 @@ ____
|
|
541
628
|
|
542
629
|
doc = document_from_string input
|
543
630
|
qb = doc.blocks.first
|
544
|
-
assert_equal 'quote', qb.
|
631
|
+
assert_equal 'quote', qb.style
|
545
632
|
assert_equal 'author', qb.attributes['attribution']
|
546
633
|
assert_equal 'source', qb.attributes['citetitle']
|
547
634
|
assert_equal 'famous', qb.attributes['role']
|
548
635
|
end
|
549
636
|
|
637
|
+
test 'role? returns true if role is assigned' do
|
638
|
+
input = <<-EOS
|
639
|
+
[role="lead"]
|
640
|
+
A paragraph
|
641
|
+
EOS
|
642
|
+
|
643
|
+
doc = document_from_string input
|
644
|
+
p = doc.blocks.first
|
645
|
+
assert p.role?
|
646
|
+
end
|
647
|
+
|
648
|
+
test 'role? can check for exact role name match' do
|
649
|
+
input = <<-EOS
|
650
|
+
[role="lead"]
|
651
|
+
A paragraph
|
652
|
+
EOS
|
653
|
+
|
654
|
+
doc = document_from_string input
|
655
|
+
p = doc.blocks.first
|
656
|
+
assert p.role?('lead')
|
657
|
+
p2 = doc.blocks.last
|
658
|
+
assert !p2.role?('final')
|
659
|
+
end
|
660
|
+
|
661
|
+
test 'has_role? can check for precense of role name' do
|
662
|
+
input = <<-EOS
|
663
|
+
[role="lead abstract"]
|
664
|
+
A paragraph
|
665
|
+
EOS
|
666
|
+
|
667
|
+
doc = document_from_string input
|
668
|
+
p = doc.blocks.first
|
669
|
+
assert !p.role?('lead')
|
670
|
+
assert p.has_role?('lead')
|
671
|
+
end
|
672
|
+
|
673
|
+
test 'roles returns array of role names' do
|
674
|
+
input = <<-EOS
|
675
|
+
[role="story lead"]
|
676
|
+
A paragraph
|
677
|
+
EOS
|
678
|
+
|
679
|
+
doc = document_from_string input
|
680
|
+
p = doc.blocks.first
|
681
|
+
assert_equal ['story', 'lead'], p.roles
|
682
|
+
end
|
683
|
+
|
684
|
+
test 'roles returns empty array if role attribute is not set' do
|
685
|
+
input = <<-EOS
|
686
|
+
A paragraph
|
687
|
+
EOS
|
688
|
+
|
689
|
+
doc = document_from_string input
|
690
|
+
p = doc.blocks.first
|
691
|
+
assert_equal [], p.roles
|
692
|
+
end
|
693
|
+
|
550
694
|
test "Attribute substitutions are performed on attribute list before parsing attributes" do
|
551
695
|
input = <<-EOS
|
552
696
|
:lead: role="lead"
|
@@ -559,15 +703,44 @@ A paragraph
|
|
559
703
|
assert_equal 'lead', para.attributes['role']
|
560
704
|
end
|
561
705
|
|
562
|
-
test 'id and
|
706
|
+
test 'id, role and options attributes can be specified on block style using shorthand syntax' do
|
563
707
|
input = <<-EOS
|
564
|
-
[normal#first.lead]
|
708
|
+
[normal#first.lead%step]
|
565
709
|
A normal paragraph.
|
566
710
|
EOS
|
567
711
|
doc = document_from_string(input)
|
568
712
|
para = doc.blocks.first
|
569
713
|
assert_equal 'first', para.attributes['id']
|
570
714
|
assert_equal 'lead', para.attributes['role']
|
715
|
+
assert_equal 'step', para.attributes['options']
|
716
|
+
assert para.attributes.has_key?('step-option')
|
717
|
+
end
|
718
|
+
|
719
|
+
test 'multiple roles and options can be specified in block style using shorthand syntax' do
|
720
|
+
input = <<-EOS
|
721
|
+
[.role1%option1.role2%option2]
|
722
|
+
Text
|
723
|
+
EOS
|
724
|
+
|
725
|
+
doc = document_from_string input
|
726
|
+
para = doc.blocks.first
|
727
|
+
assert_equal 'role1 role2', para.attributes['role']
|
728
|
+
assert_equal 'option1,option2', para.attributes['options']
|
729
|
+
assert para.attributes.has_key?('option1-option')
|
730
|
+
assert para.attributes.has_key?('option2-option')
|
731
|
+
end
|
732
|
+
|
733
|
+
test 'option can be specified in first position of block style using shorthand syntax' do
|
734
|
+
input = <<-EOS
|
735
|
+
[%interactive]
|
736
|
+
- [x] checked
|
737
|
+
EOS
|
738
|
+
|
739
|
+
doc = document_from_string input
|
740
|
+
list = doc.blocks.first
|
741
|
+
assert_equal 'interactive', list.attributes['options']
|
742
|
+
assert list.attributes.has_key?('interactive-option')
|
743
|
+
assert list.attributes[1] == '%interactive'
|
571
744
|
end
|
572
745
|
|
573
746
|
test 'id and role attributes can be specified on section style using shorthand syntax' do
|
data/test/blocks_test.rb
CHANGED
@@ -18,9 +18,9 @@ context "Blocks" do
|
|
18
18
|
|
19
19
|
test "page break" do
|
20
20
|
output = render_embedded_string("page 1\n\n<<<\n\npage 2")
|
21
|
-
assert_xpath '/*[@style="page-break-after: always
|
22
|
-
assert_xpath '/*[@style="page-break-after: always
|
23
|
-
assert_xpath '/*[@style="page-break-after: always
|
21
|
+
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]', output, 1
|
22
|
+
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]/preceding-sibling::div/p[text()="page 1"]', output, 1
|
23
|
+
assert_xpath '/*[translate(@style, ";", "")="page-break-after: always"]/following-sibling::div/p[text()="page 2"]', output, 1
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -115,6 +115,108 @@ block comment
|
|
115
115
|
output = render_embedded_string input
|
116
116
|
assert !output.strip.empty?, "Line should be emitted => #{input.rstrip}"
|
117
117
|
end
|
118
|
+
|
119
|
+
test 'preprocessor directives should not be processed within comment block within block metadata' do
|
120
|
+
input = <<-EOS
|
121
|
+
.sample title
|
122
|
+
////
|
123
|
+
ifdef::asciidoctor[////]
|
124
|
+
////
|
125
|
+
line should be rendered
|
126
|
+
EOS
|
127
|
+
|
128
|
+
output = render_embedded_string input
|
129
|
+
assert_xpath '//p[text() = "line should be rendered"]', output, 1
|
130
|
+
end
|
131
|
+
|
132
|
+
test 'preprocessor directives should not be processed within comment block' do
|
133
|
+
input = <<-EOS
|
134
|
+
dummy line
|
135
|
+
|
136
|
+
////
|
137
|
+
ifdef::asciidoctor[////]
|
138
|
+
////
|
139
|
+
|
140
|
+
line should be rendered
|
141
|
+
EOS
|
142
|
+
|
143
|
+
output = render_embedded_string input
|
144
|
+
assert_xpath '//p[text() = "line should be rendered"]', output, 1
|
145
|
+
end
|
146
|
+
|
147
|
+
# WARNING if first line of content is a directive, it will get interpretted before we know it's a comment block
|
148
|
+
# it happens because we always look a line ahead...not sure what we can do about it
|
149
|
+
test 'preprocessor directives should not be processed within comment open block' do
|
150
|
+
input = <<-EOS
|
151
|
+
[comment]
|
152
|
+
--
|
153
|
+
first line of comment
|
154
|
+
ifdef::asciidoctor[--]
|
155
|
+
line should not be rendered
|
156
|
+
--
|
157
|
+
|
158
|
+
EOS
|
159
|
+
|
160
|
+
output = render_embedded_string input
|
161
|
+
assert_xpath '//p', output, 0
|
162
|
+
end
|
163
|
+
|
164
|
+
# WARNING if first line of content is a directive, it will get interpretted before we know it's a comment block
|
165
|
+
# it happens because we always look a line ahead...not sure what we can do about it
|
166
|
+
test 'preprocessor directives should not be processed within comment paragraph' do
|
167
|
+
input = <<-EOS
|
168
|
+
[comment]
|
169
|
+
first line of content
|
170
|
+
ifdef::asciidoctor[////]
|
171
|
+
|
172
|
+
this line should be rendered
|
173
|
+
EOS
|
174
|
+
|
175
|
+
output = render_embedded_string input
|
176
|
+
assert_xpath '//p[text() = "this line should be rendered"]', output, 1
|
177
|
+
end
|
178
|
+
|
179
|
+
test 'comment style on open block should only skip block' do
|
180
|
+
input = <<-EOS
|
181
|
+
[comment]
|
182
|
+
--
|
183
|
+
skip
|
184
|
+
|
185
|
+
this block
|
186
|
+
--
|
187
|
+
|
188
|
+
not this text
|
189
|
+
EOS
|
190
|
+
result = render_embedded_string input
|
191
|
+
assert_xpath '//p', result, 1
|
192
|
+
assert_xpath '//p[text()="not this text"]', result, 1
|
193
|
+
end
|
194
|
+
|
195
|
+
test 'comment style on paragraph should only skip paragraph' do
|
196
|
+
input = <<-EOS
|
197
|
+
[comment]
|
198
|
+
skip
|
199
|
+
this paragraph
|
200
|
+
|
201
|
+
not this text
|
202
|
+
EOS
|
203
|
+
result = render_embedded_string input
|
204
|
+
assert_xpath '//p', result, 1
|
205
|
+
assert_xpath '//p[text()="not this text"]', result, 1
|
206
|
+
end
|
207
|
+
|
208
|
+
test 'comment style on paragraph should not cause adjacent block to be skipped' do
|
209
|
+
input = <<-EOS
|
210
|
+
[comment]
|
211
|
+
skip
|
212
|
+
this paragraph
|
213
|
+
[example]
|
214
|
+
not this text
|
215
|
+
EOS
|
216
|
+
result = render_embedded_string input
|
217
|
+
assert_xpath '/*[@class="exampleblock"]', result, 1
|
218
|
+
assert_xpath '/*[@class="exampleblock"]//*[normalize-space(text())="not this text"]', result, 1
|
219
|
+
end
|
118
220
|
end
|
119
221
|
|
120
222
|
context 'Quote and Verse Blocks' do
|
@@ -256,7 +358,7 @@ Some more inspiring words.
|
|
256
358
|
input = <<-EOS
|
257
359
|
> A famous quote.
|
258
360
|
> Some more inspiring words.
|
259
|
-
> -- Famous Person, Famous Source (1999)
|
361
|
+
> -- Famous Person, Famous Source, Volume 1 (1999)
|
260
362
|
EOS
|
261
363
|
output = render_string input
|
262
364
|
assert_css '.quoteblock', output, 1
|
@@ -266,7 +368,7 @@ Some more inspiring words.
|
|
266
368
|
assert_css '.quoteblock > .attribution', output, 1
|
267
369
|
assert_css '.quoteblock > .attribution > cite', output, 1
|
268
370
|
assert_css '.quoteblock > .attribution > cite + br', output, 1
|
269
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source (1999)"]', output, 1
|
371
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
|
270
372
|
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
271
373
|
author = attribution.children.last
|
272
374
|
assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
|
@@ -276,7 +378,7 @@ Some more inspiring words.
|
|
276
378
|
input = <<-EOS
|
277
379
|
"A famous quote.
|
278
380
|
Some more inspiring words."
|
279
|
-
-- Famous Person, Famous Source (1999)
|
381
|
+
-- Famous Person, Famous Source, Volume 1 (1999)
|
280
382
|
EOS
|
281
383
|
output = render_string input
|
282
384
|
assert_css '.quoteblock', output, 1
|
@@ -285,7 +387,7 @@ Some more inspiring words."
|
|
285
387
|
assert_css '.quoteblock > .attribution', output, 1
|
286
388
|
assert_css '.quoteblock > .attribution > cite', output, 1
|
287
389
|
assert_css '.quoteblock > .attribution > cite + br', output, 1
|
288
|
-
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source (1999)"]', output, 1
|
390
|
+
assert_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]/cite[text() = "Famous Source, Volume 1 (1999)"]', output, 1
|
289
391
|
attribution = xmlnodes_at_xpath '//*[@class = "quoteblock"]/*[@class = "attribution"]', output, 1
|
290
392
|
author = attribution.children.last
|
291
393
|
assert_equal "#{expand_entity 8212} Famous Person", author.text.strip
|
@@ -360,7 +462,31 @@ ____
|
|
360
462
|
assert_css '.verseblock p', output, 0
|
361
463
|
assert_css '.verseblock .literalblock', output, 0
|
362
464
|
end
|
363
|
-
|
465
|
+
|
466
|
+
test 'verse should only have specialcharacters subs' do
|
467
|
+
input = <<-EOS
|
468
|
+
[verse]
|
469
|
+
____
|
470
|
+
A famous verse
|
471
|
+
____
|
472
|
+
EOS
|
473
|
+
|
474
|
+
verse = block_from_string input
|
475
|
+
assert_equal [:specialcharacters], verse.subs
|
476
|
+
end
|
477
|
+
|
478
|
+
test 'should not recognize callouts in a verse' do
|
479
|
+
input = <<-EOS
|
480
|
+
[verse]
|
481
|
+
____
|
482
|
+
La la la <1>
|
483
|
+
____
|
484
|
+
<1> Not pointing to a callout
|
485
|
+
EOS
|
486
|
+
|
487
|
+
output = render_embedded_string input
|
488
|
+
assert_xpath '//pre[text()="La la la <1>"]', output, 1
|
489
|
+
end
|
364
490
|
end
|
365
491
|
|
366
492
|
context "Example Blocks" do
|
@@ -564,7 +690,7 @@ EOS
|
|
564
690
|
if compact
|
565
691
|
assert_equal 2, blank_lines
|
566
692
|
else
|
567
|
-
assert blank_lines
|
693
|
+
assert blank_lines >= 2
|
568
694
|
end
|
569
695
|
}
|
570
696
|
end
|
@@ -593,7 +719,7 @@ EOS
|
|
593
719
|
if compact
|
594
720
|
assert_equal 2, blank_lines
|
595
721
|
else
|
596
|
-
assert blank_lines
|
722
|
+
assert blank_lines >= 2
|
597
723
|
end
|
598
724
|
}
|
599
725
|
end
|
@@ -622,7 +748,7 @@ EOS
|
|
622
748
|
if compact
|
623
749
|
assert_equal 2, blank_lines
|
624
750
|
else
|
625
|
-
assert blank_lines
|
751
|
+
assert blank_lines >= 2
|
626
752
|
end
|
627
753
|
}
|
628
754
|
end
|
@@ -714,6 +840,31 @@ end
|
|
714
840
|
assert_equal expected.chomp, result
|
715
841
|
end
|
716
842
|
|
843
|
+
test 'literal block should honor nowrap option' do
|
844
|
+
input = <<-EOS
|
845
|
+
[options="nowrap"]
|
846
|
+
----
|
847
|
+
Do not wrap me if I get too long.
|
848
|
+
----
|
849
|
+
EOS
|
850
|
+
|
851
|
+
output = render_embedded_string input
|
852
|
+
assert_css 'pre.nowrap', output, 1
|
853
|
+
end
|
854
|
+
|
855
|
+
test 'literal block should set nowrap class if prewrap document attribute is disabled' do
|
856
|
+
input = <<-EOS
|
857
|
+
:prewrap!:
|
858
|
+
|
859
|
+
----
|
860
|
+
Do not wrap me if I get too long.
|
861
|
+
----
|
862
|
+
EOS
|
863
|
+
|
864
|
+
output = render_embedded_string input
|
865
|
+
assert_css 'pre.nowrap', output, 1
|
866
|
+
end
|
867
|
+
|
717
868
|
test 'literal block should honor explicit subs list' do
|
718
869
|
input = <<-EOS
|
719
870
|
[subs="verbatim,quotes"]
|
@@ -722,9 +873,24 @@ Map<String, String> *attributes*; //<1>
|
|
722
873
|
----
|
723
874
|
EOS
|
724
875
|
|
725
|
-
|
876
|
+
block = block_from_string input
|
877
|
+
assert_equal [:specialcharacters,:callouts,:quotes], block.subs
|
878
|
+
output = block.render
|
726
879
|
assert output.include?('Map<String, String> <strong>attributes</strong>;')
|
727
|
-
|
880
|
+
assert_xpath '//pre/b[text()="(1)"]', output, 1
|
881
|
+
end
|
882
|
+
|
883
|
+
test 'should be able to disable callouts for literal block' do
|
884
|
+
input = <<-EOS
|
885
|
+
[subs="specialcharacters"]
|
886
|
+
----
|
887
|
+
No callout here <1>
|
888
|
+
----
|
889
|
+
EOS
|
890
|
+
block = block_from_string input
|
891
|
+
assert_equal [:specialcharacters], block.subs
|
892
|
+
output = block.render
|
893
|
+
assert_xpath '//pre/b[text()="(1)"]', output, 0
|
728
894
|
end
|
729
895
|
|
730
896
|
test 'listing block should honor explicit subs list' do
|
@@ -758,7 +924,7 @@ AssertionError
|
|
758
924
|
|
759
925
|
output2 = render_embedded_string input2
|
760
926
|
# FIXME JRuby is adding extra trailing endlines in the second document,
|
761
|
-
#
|
927
|
+
# for now, rstrip is necessary
|
762
928
|
assert_equal output.rstrip, output2.rstrip
|
763
929
|
end
|
764
930
|
|
@@ -858,8 +1024,8 @@ This is a passthrough block.
|
|
858
1024
|
|
859
1025
|
block = block_from_string input
|
860
1026
|
assert !block.nil?
|
861
|
-
assert_equal 1, block.
|
862
|
-
assert_equal 'This is a passthrough block.', block.
|
1027
|
+
assert_equal 1, block.lines.size
|
1028
|
+
assert_equal 'This is a passthrough block.', block.source
|
863
1029
|
end
|
864
1030
|
|
865
1031
|
test 'performs passthrough subs on a passthrough block' do
|
@@ -918,7 +1084,7 @@ section paragraph
|
|
918
1084
|
output, errors = nil
|
919
1085
|
redirect_streams do |stdout, stderr|
|
920
1086
|
output = render_string input
|
921
|
-
errors =
|
1087
|
+
errors = stderr.string
|
922
1088
|
end
|
923
1089
|
assert_xpath '//*[@id="header"]/*', output, 0
|
924
1090
|
assert_xpath '//*[@id="preamble"]/*', output, 0
|
@@ -1063,8 +1229,32 @@ image::images/tiger.png[Tiger]
|
|
1063
1229
|
assert !doc.attributes.has_key?('figure-number')
|
1064
1230
|
end
|
1065
1231
|
|
1066
|
-
test '
|
1232
|
+
test 'keeps line unprocessed if image target is missing attribute reference and attribute-missing is skip' do
|
1067
1233
|
input = <<-EOS
|
1234
|
+
:attribute-missing: skip
|
1235
|
+
|
1236
|
+
image::{bogus}[]
|
1237
|
+
EOS
|
1238
|
+
|
1239
|
+
output = render_embedded_string input
|
1240
|
+
assert output.include?('image::{bogus}[]')
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
test 'drops line if image target is missing attribute reference and attribute-missing is drop' do
|
1244
|
+
input = <<-EOS
|
1245
|
+
:attribute-missing: drop
|
1246
|
+
|
1247
|
+
image::{bogus}[]
|
1248
|
+
EOS
|
1249
|
+
|
1250
|
+
output = render_embedded_string input
|
1251
|
+
assert output.strip.empty?
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
test 'drops line if image target is missing attribute reference and attribute-missing is drop-line' do
|
1255
|
+
input = <<-EOS
|
1256
|
+
:attribute-missing: drop-line
|
1257
|
+
|
1068
1258
|
image::{bogus}[]
|
1069
1259
|
EOS
|
1070
1260
|
|
@@ -1072,8 +1262,10 @@ image::{bogus}[]
|
|
1072
1262
|
assert output.strip.empty?
|
1073
1263
|
end
|
1074
1264
|
|
1075
|
-
test 'dropped image does not break processing of following section' do
|
1265
|
+
test 'dropped image does not break processing of following section and attribute-missing is drop-line' do
|
1076
1266
|
input = <<-EOS
|
1267
|
+
:attribute-missing: drop-line
|
1268
|
+
|
1077
1269
|
image::{bogus}[]
|
1078
1270
|
|
1079
1271
|
== Section Title
|
@@ -1217,6 +1409,30 @@ video::http://example.org/videos/cats-vs-dogs.avi[]
|
|
1217
1409
|
assert_css 'video', output, 1
|
1218
1410
|
assert_css 'video[src="http://example.org/videos/cats-vs-dogs.avi"]', output, 1
|
1219
1411
|
end
|
1412
|
+
|
1413
|
+
test 'video macro should output custom HTML with iframe for vimeo service' do
|
1414
|
+
input = <<-EOS
|
1415
|
+
video::67480300[vimeo, 400, 300, start=60, options=autoplay]
|
1416
|
+
EOS
|
1417
|
+
output = render_embedded_string input
|
1418
|
+
assert_css 'video', output, 0
|
1419
|
+
assert_css 'iframe', output, 1
|
1420
|
+
assert_css 'iframe[src="//player.vimeo.com/video/67480300#at=60?autoplay=1"]', output, 1
|
1421
|
+
assert_css 'iframe[width="400"]', output, 1
|
1422
|
+
assert_css 'iframe[height="300"]', output, 1
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
test 'video macro should output custom HTML with iframe for youtube service' do
|
1426
|
+
input = <<-EOS
|
1427
|
+
video::rPQoq7ThGAU[youtube, 640, 360, start=60, options=autoplay]
|
1428
|
+
EOS
|
1429
|
+
output = render_embedded_string input
|
1430
|
+
assert_css 'video', output, 0
|
1431
|
+
assert_css 'iframe', output, 1
|
1432
|
+
assert_css 'iframe[src="//www.youtube.com/embed/rPQoq7ThGAU?rel=0&start=60&autoplay=1"]', output, 1
|
1433
|
+
assert_css 'iframe[width="640"]', output, 1
|
1434
|
+
assert_css 'iframe[height="360"]', output, 1
|
1435
|
+
end
|
1220
1436
|
|
1221
1437
|
test 'should detect and render audio macro' do
|
1222
1438
|
input = <<-EOS
|
@@ -1336,7 +1552,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
1336
1552
|
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/img[@src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="][@alt="Tip"]', output, 1
|
1337
1553
|
end
|
1338
1554
|
|
1339
|
-
test '
|
1555
|
+
test 'should import Font Awesome and use font-based icons when value of icons attribute is font' do
|
1340
1556
|
input = <<-EOS
|
1341
1557
|
:icons: font
|
1342
1558
|
|
@@ -1345,6 +1561,7 @@ You can use icons for admonitions by setting the 'icons' attribute.
|
|
1345
1561
|
EOS
|
1346
1562
|
|
1347
1563
|
output = render_string input, :safe => Asciidoctor::SafeMode::SERVER
|
1564
|
+
assert_css 'html > head > link[rel="stylesheet"][href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.min.css"]', output, 1
|
1348
1565
|
assert_xpath '//*[@class="admonitionblock tip"]//*[@class="icon"]/i[@class="icon-tip"]', output, 1
|
1349
1566
|
end
|
1350
1567
|
end
|
@@ -1408,6 +1625,21 @@ puts "Hello, World!"
|
|
1408
1625
|
assert_css '.listingblock pre code', output, 1
|
1409
1626
|
assert_css '.listingblock pre code:not([class])', output, 1
|
1410
1627
|
end
|
1628
|
+
|
1629
|
+
test 'should not recognize fenced code blocks with more than three delimiters' do
|
1630
|
+
input = <<-EOS
|
1631
|
+
````ruby
|
1632
|
+
puts "Hello, World!"
|
1633
|
+
````
|
1634
|
+
|
1635
|
+
~~~~ javascript
|
1636
|
+
alert("Hello, World!")
|
1637
|
+
~~~~
|
1638
|
+
EOS
|
1639
|
+
|
1640
|
+
output = render_embedded_string input
|
1641
|
+
assert_css '.listingblock', output, 0
|
1642
|
+
end
|
1411
1643
|
|
1412
1644
|
test 'should support fenced code blocks with languages' do
|
1413
1645
|
input = <<-EOS
|
@@ -1426,6 +1658,23 @@ alert("Hello, World!")
|
|
1426
1658
|
assert_css '.listingblock pre code.javascript', output, 1
|
1427
1659
|
end
|
1428
1660
|
|
1661
|
+
test 'should support fenced code blocks with languages and numbering' do
|
1662
|
+
input = <<-EOS
|
1663
|
+
```ruby,numbered
|
1664
|
+
puts "Hello, World!"
|
1665
|
+
```
|
1666
|
+
|
1667
|
+
~~~ javascript, numbered
|
1668
|
+
alert("Hello, World!")
|
1669
|
+
~~~
|
1670
|
+
EOS
|
1671
|
+
|
1672
|
+
output = render_embedded_string input
|
1673
|
+
assert_css '.listingblock', output, 2
|
1674
|
+
assert_css '.listingblock pre code.ruby', output, 1
|
1675
|
+
assert_css '.listingblock pre code.javascript', output, 1
|
1676
|
+
end
|
1677
|
+
|
1429
1678
|
test 'should highlight source if source-highlighter attribute is coderay' do
|
1430
1679
|
input = <<-EOS
|
1431
1680
|
:source-highlighter: coderay
|
@@ -1437,11 +1686,80 @@ require 'coderay'
|
|
1437
1686
|
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
1438
1687
|
----
|
1439
1688
|
EOS
|
1440
|
-
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1689
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
|
1441
1690
|
assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
1442
1691
|
assert_match(/\.CodeRay \{/, output)
|
1443
1692
|
end
|
1444
1693
|
|
1694
|
+
test 'should replace callout marks but not highlight them if source-highlighter attribute is coderay' do
|
1695
|
+
input = <<-EOS
|
1696
|
+
:source-highlighter: coderay
|
1697
|
+
|
1698
|
+
[source, ruby]
|
1699
|
+
----
|
1700
|
+
require 'coderay' # <1>
|
1701
|
+
|
1702
|
+
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <2>
|
1703
|
+
puts html # <3> <4>
|
1704
|
+
exit 0 # <5><6>
|
1705
|
+
----
|
1706
|
+
<1> Load library
|
1707
|
+
<2> Highlight source
|
1708
|
+
<3> Print to stdout
|
1709
|
+
<4> Redirect to a file to capture output
|
1710
|
+
<5> Exit program
|
1711
|
+
<6> Reports success
|
1712
|
+
EOS
|
1713
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1714
|
+
assert_match(/<span class="content">coderay<\/span>.* <b>\(1\)<\/b>$/, output)
|
1715
|
+
assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b>\(2\)<\/b>$/, output)
|
1716
|
+
assert_match(/puts html * <b>\(3\)<\/b> <b>\(4\)<\/b>$/, output)
|
1717
|
+
assert_match(/exit.* <b>\(5\)<\/b> <b>\(6\)<\/b><\/code>/, output)
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
test 'should restore callout marks to correct lines if source highlighter is coderay and table line numbering is enabled' do
|
1721
|
+
input = <<-EOS
|
1722
|
+
:source-highlighter: coderay
|
1723
|
+
:coderay-linenums-mode: table
|
1724
|
+
|
1725
|
+
[source, ruby, numbered]
|
1726
|
+
----
|
1727
|
+
require 'coderay' # <1>
|
1728
|
+
|
1729
|
+
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) # <2>
|
1730
|
+
puts html # <3> <4>
|
1731
|
+
exit 0 # <5><6>
|
1732
|
+
----
|
1733
|
+
<1> Load library
|
1734
|
+
<2> Highlight source
|
1735
|
+
<3> Print to stdout
|
1736
|
+
<4> Redirect to a file to capture output
|
1737
|
+
<5> Exit program
|
1738
|
+
<6> Reports success
|
1739
|
+
EOS
|
1740
|
+
output = render_embedded_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1741
|
+
assert_match(/<span class="content">coderay<\/span>.* <b>\(1\)<\/b>$/, output)
|
1742
|
+
assert_match(/<span class="content">puts 'Hello, world!'<\/span>.* <b>\(2\)<\/b>$/, output)
|
1743
|
+
assert_match(/puts html * <b>\(3\)<\/b> <b>\(4\)<\/b>$/, output)
|
1744
|
+
assert_match(/exit.* <b>\(5\)<\/b> <b>\(6\)<\/b><\/pre>/, output)
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
test 'should link to CodeRay stylesheet if source-highlighter is coderay and linkcss is set' do
|
1748
|
+
input = <<-EOS
|
1749
|
+
:source-highlighter: coderay
|
1750
|
+
|
1751
|
+
[source, ruby]
|
1752
|
+
----
|
1753
|
+
require 'coderay'
|
1754
|
+
|
1755
|
+
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
1756
|
+
----
|
1757
|
+
EOS
|
1758
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :attributes => {'linkcss' => ''}
|
1759
|
+
assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@class = "constant"][text() = "CodeRay"]', output, 1
|
1760
|
+
assert_css 'link[rel="stylesheet"][href="./asciidoctor-coderay.css"]', output, 1
|
1761
|
+
end
|
1762
|
+
|
1445
1763
|
test 'should highlight source inline if source-highlighter attribute is coderay and coderay-css is style' do
|
1446
1764
|
input = <<-EOS
|
1447
1765
|
:source-highlighter: coderay
|
@@ -1454,7 +1772,7 @@ require 'coderay'
|
|
1454
1772
|
html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
1455
1773
|
----
|
1456
1774
|
EOS
|
1457
|
-
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE
|
1775
|
+
output = render_string input, :safe => Asciidoctor::SafeMode::SAFE, :linkcss_default => true
|
1458
1776
|
assert_xpath '//pre[@class="CodeRay"]/code[@class="ruby language-ruby"]//span[@style = "color:#036;font-weight:bold"][text() = "CodeRay"]', output, 1
|
1459
1777
|
assert_no_match(/\.CodeRay \{/, output)
|
1460
1778
|
end
|
@@ -1476,6 +1794,27 @@ html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
|
|
1476
1794
|
assert_match(/hljs.initHighlightingOnLoad/, output)
|
1477
1795
|
end
|
1478
1796
|
|
1797
|
+
test 'should set lang attribute on pre when source-highlighter is html-pipeline' do
|
1798
|
+
input = <<-EOS
|
1799
|
+
[source,ruby]
|
1800
|
+
----
|
1801
|
+
filters = [
|
1802
|
+
HTML::Pipeline::AsciiDocFilter,
|
1803
|
+
HTML::Pipeline::SanitizationFilter,
|
1804
|
+
HTML::Pipeline::SyntaxHighlightFilter
|
1805
|
+
]
|
1806
|
+
|
1807
|
+
puts HTML::Pipeline.new(filters, {}).call(input)[:output]
|
1808
|
+
----
|
1809
|
+
EOS
|
1810
|
+
|
1811
|
+
output = render_string input, :attributes => {'source-highlighter' => 'html-pipeline'}
|
1812
|
+
assert_css 'pre[lang="ruby"]', output, 1
|
1813
|
+
assert_css 'pre[lang="ruby"] > code', output, 1
|
1814
|
+
assert_css 'pre[class]', output, 0
|
1815
|
+
assert_css 'code[class]', output, 0
|
1816
|
+
end
|
1817
|
+
|
1479
1818
|
test 'document cannot turn on source highlighting if safe mode is at least SERVER' do
|
1480
1819
|
input = <<-EOS
|
1481
1820
|
:source-highlighter: coderay
|