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.

Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +330 -143
  3. data/README-fr.adoc +441 -0
  4. data/README-jp.adoc +418 -0
  5. data/README-zh_CN.adoc +430 -0
  6. data/README.adoc +454 -0
  7. data/Rakefile +57 -0
  8. data/asciidoctor.gemspec +7 -1
  9. data/data/locale/attributes-ar.adoc +22 -0
  10. data/data/locale/attributes-bg.adoc +22 -0
  11. data/data/locale/attributes-ca.adoc +22 -0
  12. data/data/locale/attributes-cs.adoc +22 -0
  13. data/data/locale/attributes-da.adoc +22 -0
  14. data/data/locale/attributes-de.adoc +22 -0
  15. data/data/locale/attributes-en.adoc +23 -0
  16. data/data/locale/attributes-es.adoc +22 -0
  17. data/data/locale/attributes-fa.adoc +22 -0
  18. data/data/locale/attributes-fi.adoc +22 -0
  19. data/data/locale/attributes-fr.adoc +22 -0
  20. data/data/locale/attributes-hu.adoc +22 -0
  21. data/data/locale/attributes-id.adoc +22 -0
  22. data/data/locale/attributes-it.adoc +22 -0
  23. data/data/locale/attributes-ja.adoc +22 -0
  24. data/data/locale/attributes-kr.adoc +22 -0
  25. data/data/locale/attributes-nb.adoc +22 -0
  26. data/data/locale/attributes-nl.adoc +22 -0
  27. data/data/locale/attributes-nn.adoc +22 -0
  28. data/data/locale/attributes-pl.adoc +22 -0
  29. data/data/locale/attributes-pt.adoc +22 -0
  30. data/data/locale/attributes-pt_BR.adoc +22 -0
  31. data/data/locale/attributes-ro.adoc +22 -0
  32. data/data/locale/attributes-ru.adoc +22 -0
  33. data/data/locale/attributes-sr.adoc +22 -0
  34. data/data/locale/attributes-sr_Latn.adoc +22 -0
  35. data/data/locale/attributes-tr.adoc +22 -0
  36. data/data/locale/attributes-uk.adoc +22 -0
  37. data/data/locale/attributes-zh_CN.adoc +22 -0
  38. data/data/locale/attributes-zh_TW.adoc +22 -0
  39. data/data/locale/attributes.adoc +8 -649
  40. data/data/stylesheets/asciidoctor-default.css +77 -72
  41. data/features/xref.feature +366 -7
  42. data/lib/asciidoctor.rb +107 -93
  43. data/lib/asciidoctor/abstract_block.rb +247 -239
  44. data/lib/asciidoctor/abstract_node.rb +56 -58
  45. data/lib/asciidoctor/block.rb +3 -3
  46. data/lib/asciidoctor/callouts.rb +1 -1
  47. data/lib/asciidoctor/cli/invoker.rb +36 -9
  48. data/lib/asciidoctor/cli/options.rb +63 -25
  49. data/lib/asciidoctor/converter.rb +23 -13
  50. data/lib/asciidoctor/converter/base.rb +4 -0
  51. data/lib/asciidoctor/converter/docbook45.rb +16 -9
  52. data/lib/asciidoctor/converter/docbook5.rb +115 -97
  53. data/lib/asciidoctor/converter/factory.rb +29 -31
  54. data/lib/asciidoctor/converter/html5.rb +229 -192
  55. data/lib/asciidoctor/converter/manpage.rb +72 -50
  56. data/lib/asciidoctor/converter/template.rb +12 -12
  57. data/lib/asciidoctor/core_ext.rb +5 -1
  58. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +6 -0
  59. data/lib/asciidoctor/document.rb +168 -77
  60. data/lib/asciidoctor/extensions.rb +79 -47
  61. data/lib/asciidoctor/helpers.rb +33 -11
  62. data/lib/asciidoctor/inline.rb +3 -2
  63. data/lib/asciidoctor/list.rb +2 -1
  64. data/lib/asciidoctor/logging.rb +122 -0
  65. data/lib/asciidoctor/parser.rb +406 -382
  66. data/lib/asciidoctor/path_resolver.rb +169 -162
  67. data/lib/asciidoctor/reader.rb +166 -121
  68. data/lib/asciidoctor/section.rb +45 -28
  69. data/lib/asciidoctor/stylesheets.rb +13 -5
  70. data/lib/asciidoctor/substitutors.rb +328 -254
  71. data/lib/asciidoctor/table.rb +105 -48
  72. data/lib/asciidoctor/timings.rb +34 -6
  73. data/lib/asciidoctor/version.rb +1 -1
  74. data/man/asciidoctor.1 +41 -23
  75. data/man/asciidoctor.adoc +14 -8
  76. data/test/api_test.rb +1004 -0
  77. data/test/attributes_test.rb +241 -50
  78. data/test/blocks_test.rb +549 -124
  79. data/test/converter_test.rb +170 -78
  80. data/test/document_test.rb +208 -767
  81. data/test/extensions_test.rb +188 -53
  82. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +1 -1
  83. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +1 -1
  84. data/test/fixtures/file-with-missing-include.adoc +1 -0
  85. data/test/fixtures/include-file.jsx +8 -0
  86. data/test/fixtures/lists.adoc +96 -0
  87. data/test/fixtures/other-chapters.adoc +11 -0
  88. data/test/fixtures/outer-include.adoc +5 -0
  89. data/test/fixtures/sample.asciidoc +5 -1
  90. data/test/fixtures/subdir/index.adoc +3 -0
  91. data/test/fixtures/subdir/inner-include.adoc +3 -0
  92. data/test/fixtures/subdir/middle-include.adoc +5 -0
  93. data/test/fixtures/tagged-class-enclosed.rb +0 -1
  94. data/test/fixtures/unclosed-tag.adoc +3 -0
  95. data/test/fixtures/unexpected-end-tag.adoc +4 -0
  96. data/test/invoker_test.rb +101 -40
  97. data/test/links_test.rb +266 -72
  98. data/test/lists_test.rb +243 -45
  99. data/test/logger_test.rb +211 -0
  100. data/test/manpage_test.rb +124 -6
  101. data/test/options_test.rb +46 -1
  102. data/test/paragraphs_test.rb +23 -10
  103. data/test/parser_test.rb +30 -1
  104. data/test/paths_test.rb +115 -33
  105. data/test/preamble_test.rb +1 -1
  106. data/test/reader_test.rb +337 -81
  107. data/test/sections_test.rb +656 -72
  108. data/test/substitutions_test.rb +182 -57
  109. data/test/tables_test.rb +324 -57
  110. data/test/test_helper.rb +77 -32
  111. data/test/text_test.rb +7 -7
  112. metadata +67 -3
@@ -5,6 +5,16 @@ unless defined? ASCIIDOCTOR_PROJECT_DIR
5
5
  end
6
6
 
7
7
  context 'Attributes' do
8
+ default_logger = Asciidoctor::LoggerManager.logger
9
+
10
+ setup do
11
+ Asciidoctor::LoggerManager.logger = (@logger = Asciidoctor::MemoryLogger.new)
12
+ end
13
+
14
+ teardown do
15
+ Asciidoctor::LoggerManager.logger = default_logger
16
+ end
17
+
8
18
  context 'Assignment' do
9
19
  test 'creates an attribute' do
10
20
  doc = document_from_string(':frog: Tanglefoot')
@@ -13,9 +23,45 @@ context 'Attributes' do
13
23
 
14
24
  test 'requires a space after colon following attribute name' do
15
25
  doc = document_from_string 'foo:bar'
16
- assert_equal nil, doc.attributes['foo']
26
+ assert_nil doc.attributes['foo']
17
27
  end
18
28
 
29
+ # NOTE AsciiDoc Python recognizes this entry
30
+ test 'does not recognize attribute entry if name contains colon' do
31
+ input = <<-EOS.chomp
32
+ :foo:bar: baz
33
+ EOS
34
+ doc = document_from_string input
35
+ refute doc.attr?('foo:bar')
36
+ assert_equal 1, doc.blocks.size
37
+ assert_equal :paragraph, doc.blocks[0].context
38
+ end
39
+
40
+ # NOTE AsciiDoc Python recognizes this entry
41
+ test 'does not recognize attribute entry if name ends with colon' do
42
+ input = <<-EOS.chomp
43
+ :foo:: bar
44
+ EOS
45
+ doc = document_from_string input
46
+ refute doc.attr?('foo:')
47
+ assert_equal 1, doc.blocks.size
48
+ assert_equal :dlist, doc.blocks[0].context
49
+ end
50
+
51
+ # NOTE AsciiDoc Python does not recognize this entry
52
+ test 'allows any word character defined by Unicode in an attribute name' do
53
+ [['café', 'a coffee shop'], ['سمن', %(سازمان مردمنهاد)]].each do |(name, value)|
54
+ str = <<-EOS
55
+ :#{name}: #{value}
56
+
57
+ {#{name}}
58
+ EOS
59
+ result = render_embedded_string str
60
+ assert_includes result, %(<p>#{value}</p>)
61
+ end
62
+
63
+ end if ::RUBY_MIN_VERSION_1_9
64
+
19
65
  test 'creates an attribute by fusing a legacy multi-line value' do
20
66
  str = <<-EOS
21
67
  :description: This is the first +
@@ -58,32 +104,32 @@ linus.torvalds@example.com
58
104
 
59
105
  test 'should delete an attribute that ends with !' do
60
106
  doc = document_from_string(":frog: Tanglefoot\n:frog!:")
61
- assert_equal nil, doc.attributes['frog']
107
+ assert_nil doc.attributes['frog']
62
108
  end
63
109
 
64
110
  test 'should delete an attribute that ends with ! set via API' do
65
111
  doc = document_from_string(":frog: Tanglefoot", :attributes => {'frog!' => ''})
66
- assert_equal nil, doc.attributes['frog']
112
+ assert_nil doc.attributes['frog']
67
113
  end
68
114
 
69
115
  test 'should delete an attribute that begins with !' do
70
116
  doc = document_from_string(":frog: Tanglefoot\n:!frog:")
71
- assert_equal nil, doc.attributes['frog']
117
+ assert_nil doc.attributes['frog']
72
118
  end
73
119
 
74
120
  test 'should delete an attribute that begins with ! set via API' do
75
121
  doc = document_from_string(":frog: Tanglefoot", :attributes => {'!frog' => ''})
76
- assert_equal nil, doc.attributes['frog']
122
+ assert_nil doc.attributes['frog']
77
123
  end
78
124
 
79
125
  test 'should delete an attribute set via API to nil value' do
80
126
  doc = document_from_string(":frog: Tanglefoot", :attributes => {'frog' => nil})
81
- assert_equal nil, doc.attributes['frog']
127
+ assert_nil doc.attributes['frog']
82
128
  end
83
129
 
84
130
  test "doesn't choke when deleting a non-existing attribute" do
85
131
  doc = document_from_string(':frog!:')
86
- assert_equal nil, doc.attributes['frog']
132
+ assert_nil doc.attributes['frog']
87
133
  end
88
134
 
89
135
  test "replaces special characters in attribute value" do
@@ -98,11 +144,8 @@ linus.torvalds@example.com
98
144
 
99
145
  test 'assigns attribute to empty string if substitution fails to resolve attribute' do
100
146
  input = ':release: Asciidoctor {version}'
101
- doc, warnings = redirect_streams do |_, err|
102
- [(document_from_string input, :attributes => { 'attribute-missing' => 'drop-line' }), err.string]
103
- end
104
- assert_equal '', doc.attributes['release']
105
- assert_includes warnings, 'dropping line containing reference to missing attribute'
147
+ document_from_string input, :attributes => { 'attribute-missing' => 'drop-line' }
148
+ assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: version'
106
149
  end
107
150
 
108
151
  test 'assigns multi-line attribute to empty string if substitution fails to resolve attribute' do
@@ -110,11 +153,9 @@ linus.torvalds@example.com
110
153
  :release: Asciidoctor +
111
154
  {version}
112
155
  EOS
113
- doc, warnings = redirect_streams do |_, err|
114
- [(document_from_string input, :attributes => { 'attribute-missing' => 'drop-line' }), err.string]
115
- end
156
+ doc = document_from_string input, :attributes => { 'attribute-missing' => 'drop-line' }
116
157
  assert_equal '', doc.attributes['release']
117
- assert_includes warnings, 'dropping line containing reference to missing attribute'
158
+ assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: version'
118
159
  end
119
160
 
120
161
  test 'resolves attributes inside attribute value within header' do
@@ -127,7 +168,7 @@ linus.torvalds@example.com
127
168
  EOS
128
169
 
129
170
  result = render_embedded_string input
130
- assert result.include? 'bigfoot'
171
+ assert_includes result, 'bigfoot'
131
172
  end
132
173
 
133
174
  test 'resolves attributes and pass macro inside attribute value outside header' do
@@ -142,7 +183,7 @@ content
142
183
  EOS
143
184
 
144
185
  result = render_embedded_string input
145
- assert result.include? '<em>big</em>foot'
186
+ assert_includes result, '<em>big</em>foot'
146
187
  end
147
188
 
148
189
  test 'should limit maximum size of attribute value if safe mode is SECURE' do
@@ -259,22 +300,60 @@ endif::holygrail[]
259
300
  assert_xpath '(//p)[2][text() = "Buggers! What happened to the grail?"]', output, 1
260
301
  end
261
302
 
262
- # Validates requirement: "Header attributes are overridden by command-line attributes."
263
- test 'attribute defined in document options overrides attribute in document' do
303
+ test 'attribute set via API overrides attribute set in document' do
264
304
  doc = document_from_string(':cash: money', :attributes => {'cash' => 'heroes'})
265
305
  assert_equal 'heroes', doc.attributes['cash']
266
306
  end
267
307
 
268
- test 'attribute defined in document options cannot be unassigned in document' do
308
+ test 'attribute set via API cannot be unset by document' do
269
309
  doc = document_from_string(':cash!:', :attributes => {'cash' => 'heroes'})
270
310
  assert_equal 'heroes', doc.attributes['cash']
271
311
  end
272
312
 
273
- test 'attribute undefined in document options cannot be assigned in document' do
274
- doc = document_from_string(':cash: money', :attributes => {'cash!' => '' })
275
- assert_equal nil, doc.attributes['cash']
276
- doc = document_from_string(':cash: money', :attributes => {'cash' => nil })
277
- assert_equal nil, doc.attributes['cash']
313
+ test 'attribute soft set via API using modifier on name can be overridden by document' do
314
+ doc = document_from_string(':cash: money', :attributes => {'cash@' => 'heroes'})
315
+ assert_equal 'money', doc.attributes['cash']
316
+ end
317
+
318
+ test 'attribute soft set via API using modifier on value can be overridden by document' do
319
+ doc = document_from_string(':cash: money', :attributes => {'cash' => 'heroes@'})
320
+ assert_equal 'money', doc.attributes['cash']
321
+ end
322
+
323
+ test 'attribute soft set via API using modifier on name can be unset by document' do
324
+ doc = document_from_string(':cash!:', :attributes => {'cash@' => 'heroes'})
325
+ assert_nil doc.attributes['cash']
326
+ doc = document_from_string(':cash!:', :attributes => {'cash@' => true})
327
+ assert_nil doc.attributes['cash']
328
+ end
329
+
330
+ test 'attribute soft set via API using modifier on value can be unset by document' do
331
+ doc = document_from_string(':cash!:', :attributes => {'cash' => 'heroes@'})
332
+ assert_nil doc.attributes['cash']
333
+ end
334
+
335
+ test 'attribute unset via API cannot be set by document' do
336
+ [
337
+ { 'cash!' => '' },
338
+ { '!cash' => '' },
339
+ { 'cash' => nil },
340
+ ].each do |attributes|
341
+ doc = document_from_string(':cash: money', :attributes => attributes)
342
+ assert_nil doc.attributes['cash']
343
+ end
344
+ end
345
+
346
+ test 'attribute soft unset via API can be set by document' do
347
+ [
348
+ { 'cash!@' => '' },
349
+ { '!cash@' => '' },
350
+ { 'cash!' => '@' },
351
+ { '!cash' => '@' },
352
+ { 'cash' => false },
353
+ ].each do |attributes|
354
+ doc = document_from_string(':cash: money', :attributes => attributes)
355
+ assert_equal 'money', doc.attributes['cash']
356
+ end
278
357
  end
279
358
 
280
359
  test 'backend and doctype attributes are set by default in default configuration' do
@@ -378,6 +457,13 @@ content
378
457
  assert doc.attributes.has_key? 'basebackend-html'
379
458
  end
380
459
 
460
+ test 'can only access a positional attribute from the attributes hash' do
461
+ node = Asciidoctor::Block.new nil, :paragraph, :attributes => { 1 => 'position 1' }
462
+ assert_nil node.attr(1)
463
+ refute node.attr?(1)
464
+ assert_equal 'position 1', node.attributes[1]
465
+ end
466
+
381
467
  test 'set_attr should set value to empty string if no value is specified' do
382
468
  node = Asciidoctor::Block.new nil, :paragraph, :attributes => {}
383
469
  node.set_attr 'foo'
@@ -522,16 +608,16 @@ This is
522
608
  blah blah {foobarbaz}
523
609
  all there is.
524
610
  EOS
525
- output, warnings = redirect_streams {|_, err| [(render_embedded_string input), err.string] }
611
+ output = render_embedded_string input
526
612
  para = xmlnodes_at_css 'p', output, 1
527
613
  refute_includes 'blah blah', para.content
528
- assert_includes warnings, 'dropping line containing reference to missing attribute'
614
+ assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: foobarbaz'
529
615
  end
530
616
 
531
617
  test "attribute value gets interpretted when rendering" do
532
618
  doc = document_from_string(":google: http://google.com[Google]\n\n{google}")
533
619
  assert_equal 'http://google.com[Google]', doc.attributes['google']
534
- output = doc.render
620
+ output = doc.convert
535
621
  assert_xpath '//a[@href="http://google.com"][text() = "Google"]', output, 1
536
622
  end
537
623
 
@@ -543,10 +629,10 @@ Line 1: This line should appear in the output.
543
629
  Line 2: Oh no, a {bogus-attribute}! This line should not appear in the output.
544
630
  EOS
545
631
 
546
- output, warnings = redirect_streams {|_, err| [(render_embedded_string input), err.string] }
632
+ output = render_embedded_string input
547
633
  assert_match(/Line 1/, output)
548
634
  refute_match(/Line 2/, output)
549
- assert_includes warnings, 'dropping line containing reference to missing attribute'
635
+ assert_message @logger, :WARN, 'dropping line containing reference to missing attribute: bogus-attribute'
550
636
  end
551
637
 
552
638
  test 'should not drop line with reference to missing attribute by default' do
@@ -589,6 +675,28 @@ Line 2: {set:a!}This line should appear in the output.
589
675
  refute_match(/\{set:a!\}/, output)
590
676
  end
591
677
 
678
+ test 'should drop line that only contains attribute assignment' do
679
+ input = <<-EOS
680
+ Line 1
681
+ {set:a}
682
+ Line 2
683
+ EOS
684
+
685
+ output = render_embedded_string input
686
+ assert_xpath %(//p[text()="Line 1\nLine 2"]), output, 1
687
+ end
688
+
689
+ test 'should drop line that only contains unresolved attribute when attribute-missing is drop' do
690
+ input = <<-EOS
691
+ Line 1
692
+ {unresolved}
693
+ Line 2
694
+ EOS
695
+
696
+ output = render_embedded_string input, :attributes => { 'attribute-missing' => 'drop' }
697
+ assert_xpath %(//p[text()="Line 1\nLine 2"]), output, 1
698
+ end
699
+
592
700
  test "substitutes inside unordered list items" do
593
701
  html = render_string(":foo: bar\n* snort at the {foo}\n* yawn")
594
702
  result = Nokogiri::HTML(html)
@@ -660,9 +768,23 @@ v1.0, 2010-01-01: First release!
660
768
  assert_equal 'value', doc.attr('a')
661
769
  assert_equal 'value', doc.attr('a2')
662
770
 
663
- output = doc.render
664
- assert output.include?('value == value')
665
- assert output.include?('2010-01-01 == 2010-01-01')
771
+ output = doc.convert
772
+ assert_includes output, 'value == value'
773
+ assert_includes output, '2010-01-01 == 2010-01-01'
774
+ end
775
+
776
+ test 'should warn if unterminated block comment is detected in document header' do
777
+ input = <<-EOS
778
+ = Document Title
779
+ :foo: bar
780
+ ////
781
+ :hey: there
782
+
783
+ content
784
+ EOS
785
+ doc = document_from_string input
786
+ assert_nil doc.attr('hey')
787
+ assert_message @logger, :WARN, '<stdin>: line 3: unterminated comment block', Hash
666
788
  end
667
789
 
668
790
  test 'substitutes inside block title' do
@@ -749,14 +871,14 @@ puts 'The forecast for today is {forecast}'
749
871
  end
750
872
 
751
873
  test 'does not substitute attributes inside literal blocks' do
752
- input = <<-EOS
874
+ input = <<-EOS
753
875
  :foo: bar
754
876
 
755
877
  ....
756
878
  You insert the text {foo} to expand the value
757
879
  of the attribute named foo in your document.
758
880
  ....
759
- EOS
881
+ EOS
760
882
  output = render_string(input)
761
883
  assert_match(/\{foo\}/, output)
762
884
  end
@@ -816,7 +938,7 @@ of the attribute named foo in your document.
816
938
  {set:foo!}
817
939
  {foo}yes
818
940
  EOS
819
- output = redirect_streams { render_embedded_string input }
941
+ output = render_embedded_string input
820
942
  assert_xpath '//p', output, 1
821
943
  assert_xpath '//p/child::text()', output, 0
822
944
  end
@@ -848,7 +970,7 @@ of the attribute named foo in your document.
848
970
  EOS
849
971
 
850
972
  doc = document_from_string input
851
- output = doc.render
973
+ output = doc.convert
852
974
  assert_equal 1, doc.attributes['mycounter']
853
975
  assert_xpath '//p[text()="1"]', output, 1
854
976
  end
@@ -859,7 +981,7 @@ of the attribute named foo in your document.
859
981
  EOS
860
982
 
861
983
  doc = document_from_string input
862
- output = doc.render
984
+ output = doc.convert
863
985
  assert_equal 1, doc.attributes['mycounter']
864
986
  assert_xpath '//p[text()="1"]', output, 0
865
987
  end
@@ -870,7 +992,7 @@ of the attribute named foo in your document.
870
992
  EOS
871
993
 
872
994
  doc = document_from_string input
873
- doc.render
995
+ doc.convert
874
996
  assert_equal 10, doc.attributes['mycounter']
875
997
  end
876
998
 
@@ -880,7 +1002,7 @@ of the attribute named foo in your document.
880
1002
  EOS
881
1003
 
882
1004
  doc = document_from_string input
883
- doc.render
1005
+ doc.convert
884
1006
  assert_equal 'A', doc.attributes['mycounter']
885
1007
  end
886
1008
 
@@ -894,7 +1016,7 @@ of the attribute named foo in your document.
894
1016
  EOS
895
1017
 
896
1018
  doc = document_from_string input
897
- output = doc.render
1019
+ output = doc.convert
898
1020
  assert_equal 2, doc.attributes['mycounter']
899
1021
  assert_xpath '//p[text()="2"]', output, 2
900
1022
  end
@@ -909,7 +1031,7 @@ of the attribute named foo in your document.
909
1031
  EOS
910
1032
 
911
1033
  doc = document_from_string input
912
- output = doc.render
1034
+ output = doc.convert
913
1035
  assert_equal 'A', doc.attributes['mycounter']
914
1036
  assert_xpath '//p[text()="A"]', output, 2
915
1037
  end
@@ -924,7 +1046,7 @@ of the attribute named foo in your document.
924
1046
  EOS
925
1047
 
926
1048
  doc = document_from_string input
927
- output = doc.render :header_footer => false
1049
+ output = doc.convert :header_footer => false
928
1050
  assert_equal 1, doc.attributes['mycounter']
929
1051
  assert_xpath '//p[text()="1"]', output, 2
930
1052
  end
@@ -941,7 +1063,7 @@ after: {counter:mycounter}
941
1063
  EOS
942
1064
 
943
1065
  doc = document_from_string input
944
- output = doc.render :header_footer => false
1066
+ output = doc.convert :header_footer => false
945
1067
  assert_equal 1, doc.attributes['mycounter']
946
1068
  assert_xpath '//p[text()="before: 1 2 3"]', output, 1
947
1069
  assert_xpath '//p[text()="after: 1"]', output, 1
@@ -1190,11 +1312,29 @@ A paragraph
1190
1312
 
1191
1313
  test 'id, role and options attributes can be specified on block style using shorthand syntax' do
1192
1314
  input = <<-EOS
1193
- [normal#first.lead%step]
1194
- A normal paragraph.
1315
+ [literal#first.lead%step]
1316
+ A literal paragraph.
1195
1317
  EOS
1196
1318
  doc = document_from_string(input)
1197
1319
  para = doc.blocks.first
1320
+ assert_equal :literal, para.context
1321
+ assert_equal 'first', para.attributes['id']
1322
+ assert_equal 'lead', para.attributes['role']
1323
+ assert_equal 'step', para.attributes['options']
1324
+ assert para.attributes.has_key?('step-option')
1325
+ end
1326
+
1327
+ test 'id, role and options attributes can be specified using shorthand syntax on block style using multiple block attribute lines' do
1328
+ input = <<-EOS
1329
+ [literal]
1330
+ [#first]
1331
+ [.lead]
1332
+ [%step]
1333
+ A literal paragraph.
1334
+ EOS
1335
+ doc = document_from_string(input)
1336
+ para = doc.blocks.first
1337
+ assert_equal :literal, para.context
1198
1338
  assert_equal 'first', para.attributes['id']
1199
1339
  assert_equal 'lead', para.attributes['role']
1200
1340
  assert_equal 'step', para.attributes['options']
@@ -1215,6 +1355,58 @@ Text
1215
1355
  assert para.attributes.has_key?('option2-option')
1216
1356
  end
1217
1357
 
1358
+ test 'options specified using shorthand syntax on block style across multiple lines should be additive' do
1359
+ input = <<-EOS
1360
+ [%option1]
1361
+ [%option2]
1362
+ Text
1363
+ EOS
1364
+
1365
+ doc = document_from_string input
1366
+ para = doc.blocks.first
1367
+ assert_equal 'option1,option2', para.attributes['options']
1368
+ assert para.attributes.has_key?('option1-option')
1369
+ assert para.attributes.has_key?('option2-option')
1370
+ end
1371
+
1372
+ test 'roles specified using shorthand syntax on block style across multiple lines should be additive' do
1373
+ input = <<-EOS
1374
+ [.role1]
1375
+ [.role2.role3]
1376
+ Text
1377
+ EOS
1378
+
1379
+ doc = document_from_string input
1380
+ para = doc.blocks.first
1381
+ assert_equal 'role1 role2 role3', para.attributes['role']
1382
+ end
1383
+
1384
+ test 'setting a role using the role attribute replaces any existing roles' do
1385
+ input = <<-EOS
1386
+ [.role1]
1387
+ [role=role2]
1388
+ [.role3]
1389
+ Text
1390
+ EOS
1391
+
1392
+ doc = document_from_string input
1393
+ para = doc.blocks.first
1394
+ assert_equal 'role2 role3', para.attributes['role']
1395
+ end
1396
+
1397
+ test 'setting a role using the shorthand syntax on block style should not clear the ID' do
1398
+ input = <<-EOS
1399
+ [#id]
1400
+ [.role]
1401
+ Text
1402
+ EOS
1403
+
1404
+ doc = document_from_string input
1405
+ para = doc.blocks.first
1406
+ assert_equal 'id', para.id
1407
+ assert_equal 'role', para.role
1408
+ end
1409
+
1218
1410
  test 'a role can be added using add_role when the node has no roles' do
1219
1411
  input = <<-EOS
1220
1412
  A normal paragraph
@@ -1278,7 +1470,7 @@ A normal paragraph
1278
1470
  res = para.remove_role 'role1'
1279
1471
  assert res
1280
1472
  refute para.role?
1281
- assert_equal nil, para.attributes['role']
1473
+ assert_nil para.attributes['role']
1282
1474
  refute para.has_role? 'role1'
1283
1475
  end
1284
1476
 
@@ -1304,7 +1496,7 @@ A normal paragraph
1304
1496
  para = doc.blocks.first
1305
1497
  res = para.remove_role 'role1'
1306
1498
  refute res
1307
- assert_equal nil, para.attributes['role']
1499
+ assert_nil para.attributes['role']
1308
1500
  refute para.has_role?('role1')
1309
1501
  end
1310
1502
 
@@ -1318,7 +1510,6 @@ A normal paragraph
1318
1510
  list = doc.blocks.first
1319
1511
  assert_equal 'interactive', list.attributes['options']
1320
1512
  assert list.attributes.has_key?('interactive-option')
1321
- assert list.attributes[1] == '%interactive'
1322
1513
  end
1323
1514
 
1324
1515
  test 'id and role attributes can be specified on section style using shorthand syntax' do