asciidoctor 1.5.8 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.adoc +628 -45
  4. data/LICENSE +2 -1
  5. data/README-de.adoc +28 -38
  6. data/README-fr.adoc +30 -43
  7. data/README-jp.adoc +255 -201
  8. data/README-zh_CN.adoc +40 -44
  9. data/README.adoc +170 -143
  10. data/asciidoctor.gemspec +22 -34
  11. data/bin/asciidoctor +5 -4
  12. data/data/locale/attributes-ar.adoc +4 -3
  13. data/data/locale/attributes-be.adoc +23 -0
  14. data/data/locale/attributes-bg.adoc +4 -3
  15. data/data/locale/attributes-ca.adoc +6 -5
  16. data/data/locale/attributes-cs.adoc +4 -3
  17. data/data/locale/attributes-da.adoc +6 -5
  18. data/data/locale/attributes-de.adoc +6 -5
  19. data/data/locale/attributes-en.adoc +4 -4
  20. data/data/locale/attributes-es.adoc +6 -5
  21. data/data/locale/attributes-fa.adoc +4 -3
  22. data/data/locale/attributes-fi.adoc +4 -3
  23. data/data/locale/attributes-fr.adoc +8 -7
  24. data/data/locale/attributes-hu.adoc +4 -3
  25. data/data/locale/attributes-id.adoc +4 -3
  26. data/data/locale/attributes-it.adoc +6 -5
  27. data/data/locale/attributes-ja.adoc +4 -3
  28. data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
  29. data/data/locale/attributes-nb.adoc +4 -3
  30. data/data/locale/attributes-nl.adoc +6 -5
  31. data/data/locale/attributes-nn.adoc +4 -3
  32. data/data/locale/attributes-pl.adoc +8 -7
  33. data/data/locale/attributes-pt.adoc +6 -5
  34. data/data/locale/attributes-pt_BR.adoc +6 -5
  35. data/data/locale/attributes-ro.adoc +4 -3
  36. data/data/locale/attributes-ru.adoc +6 -5
  37. data/data/locale/attributes-sr.adoc +4 -4
  38. data/data/locale/attributes-sr_Latn.adoc +4 -4
  39. data/data/locale/attributes-sv.adoc +4 -4
  40. data/data/locale/attributes-th.adoc +23 -0
  41. data/data/locale/attributes-tr.adoc +4 -3
  42. data/data/locale/attributes-uk.adoc +6 -5
  43. data/data/locale/attributes-vi.adoc +23 -0
  44. data/data/locale/attributes-zh_CN.adoc +4 -3
  45. data/data/locale/attributes-zh_TW.adoc +4 -3
  46. data/data/reference/syntax.adoc +296 -0
  47. data/data/stylesheets/asciidoctor-default.css +120 -114
  48. data/data/stylesheets/coderay-asciidoctor.css +15 -17
  49. data/lib/asciidoctor/abstract_block.rb +146 -140
  50. data/lib/asciidoctor/abstract_node.rb +152 -170
  51. data/lib/asciidoctor/attribute_list.rb +77 -89
  52. data/lib/asciidoctor/block.rb +29 -28
  53. data/lib/asciidoctor/callouts.rb +4 -2
  54. data/lib/asciidoctor/cli/invoker.rb +20 -24
  55. data/lib/asciidoctor/cli/options.rb +107 -96
  56. data/lib/asciidoctor/cli.rb +3 -2
  57. data/lib/asciidoctor/convert.rb +199 -0
  58. data/lib/asciidoctor/converter/composite.rb +40 -48
  59. data/lib/asciidoctor/converter/docbook5.rb +627 -644
  60. data/lib/asciidoctor/converter/html5.rb +1053 -951
  61. data/lib/asciidoctor/converter/manpage.rb +581 -532
  62. data/lib/asciidoctor/converter/template.rb +232 -271
  63. data/lib/asciidoctor/converter.rb +370 -185
  64. data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
  65. data/lib/asciidoctor/core_ext/hash/merge.rb +8 -0
  66. data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
  67. data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
  68. data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
  69. data/lib/asciidoctor/core_ext.rb +8 -17
  70. data/lib/asciidoctor/document.rb +503 -461
  71. data/lib/asciidoctor/extensions.rb +127 -174
  72. data/lib/asciidoctor/helpers.rb +184 -107
  73. data/lib/asciidoctor/inline.rb +9 -12
  74. data/lib/asciidoctor/list.rb +11 -29
  75. data/lib/asciidoctor/load.rb +119 -0
  76. data/lib/asciidoctor/logging.rb +22 -17
  77. data/lib/asciidoctor/parser.rb +673 -719
  78. data/lib/asciidoctor/path_resolver.rb +48 -33
  79. data/lib/asciidoctor/reader.rb +383 -338
  80. data/lib/asciidoctor/rouge_ext.rb +39 -0
  81. data/lib/asciidoctor/rx.rb +723 -0
  82. data/lib/asciidoctor/section.rb +17 -16
  83. data/lib/asciidoctor/stylesheets.rb +19 -37
  84. data/lib/asciidoctor/substitutors.rb +926 -1022
  85. data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
  86. data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
  87. data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
  88. data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
  89. data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
  90. data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
  91. data/lib/asciidoctor/syntax_highlighter.rb +253 -0
  92. data/lib/asciidoctor/table.rb +152 -114
  93. data/lib/asciidoctor/timings.rb +7 -5
  94. data/lib/asciidoctor/version.rb +2 -1
  95. data/lib/asciidoctor/writer.rb +30 -0
  96. data/lib/asciidoctor.rb +266 -1340
  97. data/man/asciidoctor.1 +49 -47
  98. data/man/asciidoctor.adoc +54 -45
  99. metadata +50 -245
  100. data/CONTRIBUTING.adoc +0 -185
  101. data/Gemfile +0 -60
  102. data/Rakefile +0 -129
  103. data/bin/asciidoctor-safe +0 -15
  104. data/features/open_block.feature +0 -92
  105. data/features/pass_block.feature +0 -66
  106. data/features/step_definitions.rb +0 -49
  107. data/features/text_formatting.feature +0 -57
  108. data/features/xref.feature +0 -1039
  109. data/lib/asciidoctor/converter/base.rb +0 -59
  110. data/lib/asciidoctor/converter/docbook45.rb +0 -93
  111. data/lib/asciidoctor/converter/factory.rb +0 -226
  112. data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
  113. data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
  114. data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
  115. data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
  116. data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
  117. data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
  118. data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
  119. data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
  120. data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
  121. data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
  122. data/test/api_test.rb +0 -1240
  123. data/test/attribute_list_test.rb +0 -242
  124. data/test/attributes_test.rb +0 -1623
  125. data/test/blocks_test.rb +0 -3870
  126. data/test/converter_test.rb +0 -470
  127. data/test/document_test.rb +0 -1853
  128. data/test/extensions_test.rb +0 -1560
  129. data/test/fixtures/asciidoc_index.txt +0 -521
  130. data/test/fixtures/basic-docinfo-footer.html +0 -6
  131. data/test/fixtures/basic-docinfo-footer.xml +0 -8
  132. data/test/fixtures/basic-docinfo.html +0 -1
  133. data/test/fixtures/basic-docinfo.xml +0 -4
  134. data/test/fixtures/basic.asciidoc +0 -5
  135. data/test/fixtures/chapter-a.adoc +0 -3
  136. data/test/fixtures/child-include.adoc +0 -5
  137. data/test/fixtures/circle.svg +0 -9
  138. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
  139. data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
  140. data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
  141. data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
  142. data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
  143. data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
  144. data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
  145. data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
  146. data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
  147. data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
  148. data/test/fixtures/docinfo-footer.html +0 -1
  149. data/test/fixtures/docinfo-footer.xml +0 -9
  150. data/test/fixtures/docinfo.html +0 -1
  151. data/test/fixtures/docinfo.xml +0 -3
  152. data/test/fixtures/doctime-localtime.adoc +0 -2
  153. data/test/fixtures/dot.gif +0 -0
  154. data/test/fixtures/encoding.asciidoc +0 -13
  155. data/test/fixtures/file-with-missing-include.adoc +0 -1
  156. data/test/fixtures/grandchild-include.adoc +0 -3
  157. data/test/fixtures/hello-asciidoctor.pdf +0 -69
  158. data/test/fixtures/include-file.asciidoc +0 -24
  159. data/test/fixtures/include-file.jsx +0 -8
  160. data/test/fixtures/include-file.ml +0 -3
  161. data/test/fixtures/include-file.xml +0 -5
  162. data/test/fixtures/lists.adoc +0 -96
  163. data/test/fixtures/master.adoc +0 -5
  164. data/test/fixtures/mismatched-end-tag.adoc +0 -7
  165. data/test/fixtures/other-chapters.adoc +0 -11
  166. data/test/fixtures/outer-include.adoc +0 -5
  167. data/test/fixtures/parent-include-restricted.adoc +0 -5
  168. data/test/fixtures/parent-include.adoc +0 -5
  169. data/test/fixtures/sample.asciidoc +0 -30
  170. data/test/fixtures/section-a.adoc +0 -4
  171. data/test/fixtures/stylesheets/custom.css +0 -3
  172. data/test/fixtures/subdir/index.adoc +0 -3
  173. data/test/fixtures/subdir/inner-include.adoc +0 -3
  174. data/test/fixtures/subdir/middle-include.adoc +0 -5
  175. data/test/fixtures/subs-docinfo.html +0 -2
  176. data/test/fixtures/subs.adoc +0 -6
  177. data/test/fixtures/tagged-class-enclosed.rb +0 -25
  178. data/test/fixtures/tagged-class.rb +0 -23
  179. data/test/fixtures/tip.gif +0 -0
  180. data/test/fixtures/unclosed-tag.adoc +0 -3
  181. data/test/fixtures/unexpected-end-tag.adoc +0 -4
  182. data/test/invoker_test.rb +0 -745
  183. data/test/links_test.rb +0 -855
  184. data/test/lists_test.rb +0 -5151
  185. data/test/logger_test.rb +0 -211
  186. data/test/manpage_test.rb +0 -660
  187. data/test/options_test.rb +0 -262
  188. data/test/paragraphs_test.rb +0 -562
  189. data/test/parser_test.rb +0 -742
  190. data/test/paths_test.rb +0 -395
  191. data/test/preamble_test.rb +0 -173
  192. data/test/reader_test.rb +0 -2161
  193. data/test/sections_test.rb +0 -3575
  194. data/test/substitutions_test.rb +0 -2066
  195. data/test/tables_test.rb +0 -2036
  196. data/test/test_helper.rb +0 -447
  197. data/test/text_test.rb +0 -309
@@ -1,34 +1,35 @@
1
- # encoding: UTF-8
1
+ # frozen_string_literal: true
2
2
  module Asciidoctor
3
3
  class AbstractBlock < AbstractNode
4
- # Public: Get the Array of Asciidoctor::AbstractBlock sub-blocks for this block
4
+ # Public: Get the Array of {AbstractBlock} child blocks for this block. Only applies if content model is :compound.
5
5
  attr_reader :blocks
6
6
 
7
- # Public: Set the caption for this block
7
+ # Public: Set the caption for this block.
8
8
  attr_writer :caption
9
9
 
10
- # Public: The types of content that this block can accomodate
10
+ # Public: Describes the type of content this block accepts and how it should be converted. Acceptable values are:
11
+ # * :compound - this block contains other blocks
12
+ # * :simple - this block holds a paragraph of prose that receives normal substitutions
13
+ # * :verbatim - this block holds verbatim text (displayed "as is") that receives verbatim substitutions
14
+ # * :raw - this block holds unprocessed content passed directly to the output with no substitutions applied
15
+ # * :empty - this block has no content
11
16
  attr_accessor :content_model
12
17
 
13
- # Public: Set the Integer level of this Section or the Section level in which this Block resides
18
+ # Public: Set the Integer level of this {Section} or the level of the Section to which this {AbstractBlock} belongs.
14
19
  attr_accessor :level
15
20
 
16
- # Public: Get/Set the numeral of this block (if section, relative to parent, otherwise absolute)
17
- # Only assigned to section if automatic section numbering is enabled
18
- # Only assigned to formal block (block with title) if corresponding caption attribute is present
21
+ # Public: Get/Set the String numeral of this block (if section, relative to parent, otherwise absolute).
22
+ # Only assigned to section if automatic section numbering is enabled.
23
+ # Only assigned to formal block (block with title) if corresponding caption attribute is present.
19
24
  attr_accessor :numeral
20
25
 
21
- # Deprecated: Legacy property to get/set the numeral of this block
22
- alias number numeral
23
- alias number= numeral=
24
-
25
- # Public: Gets/Sets the location in the AsciiDoc source where this block begins
26
+ # Public: Gets/Sets the location in the AsciiDoc source where this block begins.
26
27
  attr_accessor :source_location
27
28
 
28
29
  # Public: Get/Set the String style (block type qualifier) for this block.
29
30
  attr_accessor :style
30
31
 
31
- # Public: Substitutions to be applied to content in this block
32
+ # Public: Substitutions to be applied to content in this block.
32
33
  attr_reader :subs
33
34
 
34
35
  def initialize parent, context, opts = {}
@@ -36,16 +37,15 @@ class AbstractBlock < AbstractNode
36
37
  @content_model = :compound
37
38
  @blocks = []
38
39
  @subs = []
39
- @id = @title = @title_converted = @caption = @numeral = @style = @default_subs = @source_location = nil
40
- if context == :document
41
- @level = 0
42
- elsif parent && context != :section
40
+ @id = @title = @caption = @numeral = @style = @default_subs = @source_location = nil
41
+ if context == :document || context == :section
42
+ @level = @next_section_index = 0
43
+ @next_section_ordinal = 1
44
+ elsif AbstractBlock === parent
43
45
  @level = parent.level
44
46
  else
45
47
  @level = nil
46
48
  end
47
- @next_section_index = 0
48
- @next_section_ordinal = 1
49
49
  end
50
50
 
51
51
  def block?
@@ -75,7 +75,7 @@ class AbstractBlock < AbstractNode
75
75
  converter.convert self
76
76
  end
77
77
 
78
- # Alias render to convert to maintain backwards compatibility
78
+ # Deprecated: Use {AbstractBlock#convert} instead.
79
79
  alias render convert
80
80
 
81
81
  # Public: Get the converted result of the child blocks by converting the
@@ -90,7 +90,7 @@ class AbstractBlock < AbstractNode
90
90
  #
91
91
  # context - the context Symbol context to assign to this block
92
92
  #
93
- # Returns the new context Symbol assigned to this block
93
+ # Returns the specified Symbol context
94
94
  def context= context
95
95
  @node_name = (@context = context).to_s
96
96
  end
@@ -101,10 +101,10 @@ class AbstractBlock < AbstractNode
101
101
  #
102
102
  # Examples
103
103
  #
104
- # block = Block.new(parent, :preamble, :content_model => :compound)
104
+ # block = Block.new(parent, :preamble, content_model: :compound)
105
105
  #
106
- # block << Block.new(block, :paragraph, :source => 'p1')
107
- # block << Block.new(block, :paragraph, :source => 'p2')
106
+ # block << Block.new(block, :paragraph, source: 'p1')
107
+ # block << Block.new(block, :paragraph, source: 'p2')
108
108
  # block.blocks?
109
109
  # # => true
110
110
  # block.blocks.size
@@ -124,28 +124,38 @@ class AbstractBlock < AbstractNode
124
124
  #
125
125
  # Returns A Boolean indicating whether this Block has block content
126
126
  def blocks?
127
- !@blocks.empty?
127
+ @blocks.empty? ? false : true
128
128
  end
129
129
 
130
130
  # Public: Check whether this block has any child Section objects.
131
131
  #
132
- # Only applies to Document and Section instances
132
+ # Acts an an abstract method that always returns false unless this block is an
133
+ # instance of Document or Section.
134
+ # Both Document and Section provide overrides for this method.
133
135
  #
134
- # Returns A [Boolean] to indicate whether this block has child Section objects
136
+ # Returns false
135
137
  def sections?
136
- @next_section_index > 0
138
+ false
137
139
  end
138
140
 
139
- # Public: Walk the document tree and find all block-level nodes that match
140
- # the specified selector (context, style, id, role, and/or custom filter).
141
+ # Deprecated: Legacy property to get the String or Integer numeral of this section.
142
+ def number
143
+ (Integer @numeral) rescue @numeral
144
+ end
145
+
146
+ # Deprecated: Legacy property to set the numeral of this section by coercing the value to a String.
147
+ def number= val
148
+ @numeral = val.to_s
149
+ end
150
+
151
+ # Public: Walk the document tree and find all block-level nodes that match the specified selector (context, style, id,
152
+ # role, and/or custom filter).
141
153
  #
142
- # If a Ruby block is given, it's treated as an supplemental filter. If the
143
- # filter returns true, the node is accepted and traversal continues. If the
144
- # filter returns false, the node is rejected, but traversal continues. If the
145
- # filter returns :skip, the node and all its descendants are rejected. If the
146
- # filter returns :skip_children, the node is accepted, but its descendants
147
- # are rejected. If no selector or filter block is supplied, all block-level
148
- # nodes in the tree are returned.
154
+ # If a Ruby block is given, it's applied as a supplemental filter. If the filter returns true (which implies :accept),
155
+ # the node is accepted and node traversal continues. If the filter returns false (which implies :skip), the node is
156
+ # skipped, but its children are still visited. If the filter returns :reject, the node and all its descendants are
157
+ # rejected. If the filter returns :prune, the node is accepted, but its descendants are rejected. If no selector
158
+ # or filter block is supplied, all block-level nodes in the tree are returned.
149
159
  #
150
160
  # Examples
151
161
  #
@@ -170,60 +180,16 @@ class AbstractBlock < AbstractNode
170
180
 
171
181
  alias query find_by
172
182
 
173
- # Internal: Performs the work for find_by, but does not handle the StopIteration exception.
174
- def find_by_internal selector = {}, result = [], &block
175
- if ((any_context = !(context_selector = selector[:context])) || context_selector == @context) &&
176
- (!(style_selector = selector[:style]) || style_selector == @style) &&
177
- (!(role_selector = selector[:role]) || (has_role? role_selector)) &&
178
- (!(id_selector = selector[:id]) || id_selector == @id)
179
- if id_selector
180
- result.replace block_given? ? ((yield self) ? [self] : []) : [self]
181
- raise ::StopIteration
182
- elsif block_given?
183
- if (verdict = yield self)
184
- case verdict
185
- when :skip_children
186
- result << self
187
- return result
188
- when :skip
189
- return result
190
- else
191
- result << self
192
- end
193
- end
194
- else
195
- result << self
196
- end
197
- end
198
-
199
- # process document header as a section if present
200
- if @context == :document && (any_context || context_selector == :section) && header?
201
- @header.find_by_internal selector, result, &block
202
- end
203
-
204
- unless context_selector == :document # optimization
205
- # yuck, dlist is a special case
206
- if @context == :dlist
207
- if any_context || context_selector != :section # optimization
208
- @blocks.flatten.each do |li|
209
- # NOTE the list item of a dlist can be nil, so we have to check
210
- li.find_by_internal selector, result, &block if li
211
- end
212
- end
213
- elsif
214
- @blocks.each do |b|
215
- next if (context_selector == :section && b.context != :section) # optimization
216
- b.find_by_internal selector, result, &block
217
- end
218
- end
219
- end
220
- result
221
- end
222
-
223
183
  # Move to the next adjacent block in document order. If the current block is the last
224
184
  # item in a list, this method will return the following sibling of the list block.
225
185
  def next_adjacent_block
226
- (sib = (p = parent).blocks[(p.blocks.find_index self) + 1]) ? sib : p.next_adjacent_block unless @context == :document
186
+ unless @context == :document
187
+ if (p = @parent).context == :dlist && @context == :list_item
188
+ (sib = p.items[(p.items.find_index {|terms, desc| (terms.include? self) || desc == self }) + 1]) ? sib : p.next_adjacent_block
189
+ else
190
+ (sib = p.blocks[(p.blocks.find_index self) + 1]) ? sib : p.next_adjacent_block
191
+ end
192
+ end
227
193
  end
228
194
 
229
195
  # Public: Get the Array of child Section objects
@@ -234,12 +200,12 @@ class AbstractBlock < AbstractNode
234
200
  #
235
201
  # doc << (sect1 = Section.new doc, 1)
236
202
  # sect1.title = 'Section 1'
237
- # para1 = Block.new sect1, :paragraph, :source => 'Paragraph 1'
238
- # para2 = Block.new sect1, :paragraph, :source => 'Paragraph 2'
203
+ # para1 = Block.new sect1, :paragraph, source: 'Paragraph 1'
204
+ # para2 = Block.new sect1, :paragraph, source: 'Paragraph 2'
239
205
  # sect1 << para1 << para2
240
206
  # sect1 << (sect1_1 = Section.new sect1, 2)
241
207
  # sect1_1.title = 'Section 1.1'
242
- # sect1_1 << (Block.new sect1_1, :paragraph, :source => 'Paragraph 3')
208
+ # sect1_1 << (Block.new sect1_1, :paragraph, source: 'Paragraph 3')
243
209
  # sect1.blocks?
244
210
  # # => true
245
211
  # sect1.blocks.size
@@ -264,6 +230,8 @@ class AbstractBlock < AbstractNode
264
230
  text = sub_specialchars text
265
231
  (ReplaceableTextRx.match? text) ? (sub_replacements text) : text
266
232
  end
233
+ else
234
+ ''
267
235
  end
268
236
  end
269
237
 
@@ -303,7 +271,7 @@ class AbstractBlock < AbstractNode
303
271
  ORDERED_LIST_KEYWORDS[list_type || @style]
304
272
  end
305
273
 
306
- # Public: Get the String title of this Block with title substitions applied
274
+ # Public: Get the String title of this Block with title substitutions applied
307
275
  #
308
276
  # The following substitutions are applied to block and section titles:
309
277
  #
@@ -318,7 +286,7 @@ class AbstractBlock < AbstractNode
318
286
  # Returns the converted String title for this Block, or nil if the source title is falsy
319
287
  def title
320
288
  # prevent substitutions from being applied to title multiple times
321
- @title_converted ? @converted_title : (@converted_title = (@title_converted = true) && @title && (apply_title_subs @title))
289
+ @converted_title ||= @title && (apply_title_subs @title)
322
290
  end
323
291
 
324
292
  # Public: A convenience method that checks whether the title of this block is defined.
@@ -330,9 +298,10 @@ class AbstractBlock < AbstractNode
330
298
 
331
299
  # Public: Set the String block title.
332
300
  #
333
- # Returns the new String title assigned to this Block
301
+ # Returns the specified String title
334
302
  def title= val
335
- @title, @title_converted = val, nil
303
+ @converted_title = nil
304
+ @title = val
336
305
  end
337
306
 
338
307
  # Public: A convenience method that checks whether the specified
@@ -376,17 +345,17 @@ class AbstractBlock < AbstractNode
376
345
  if (val = reftext) && !val.empty?
377
346
  val
378
347
  # NOTE xrefstyle only applies to blocks with a title and a caption or number
379
- elsif xrefstyle && @title && @caption
348
+ elsif xrefstyle && @title && !@caption.nil_or_empty?
380
349
  case xrefstyle
381
350
  when 'full'
382
- quoted_title = sprintf sub_quotes(@document.compat_mode ? %q(``%s'') : '"`%s`"'), title
383
- if @numeral && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
351
+ quoted_title = sub_placeholder (sub_quotes @document.compat_mode ? %q(``%s'') : '"`%s`"'), title
352
+ if @numeral && (caption_attr_name = CAPTION_ATTRIBUTE_NAMES[@context]) && (prefix = @document.attributes[caption_attr_name])
384
353
  %(#{prefix} #{@numeral}, #{quoted_title})
385
354
  else
386
355
  %(#{@caption.chomp '. '}, #{quoted_title})
387
356
  end
388
357
  when 'short'
389
- if @numeral && (prefix = @document.attributes[@context == :image ? 'figure-caption' : %(#{@context}-caption)])
358
+ if @numeral && (caption_attr_name = CAPTION_ATTRIBUTE_NAMES[@context]) && (prefix = @document.attributes[caption_attr_name])
390
359
  %(#{prefix} #{@numeral})
391
360
  else
392
361
  @caption.chomp '. '
@@ -410,16 +379,16 @@ class AbstractBlock < AbstractNode
410
379
  # The parts of a complete caption are: <prefix> <number>. <title>
411
380
  # This partial caption represents the part the precedes the title.
412
381
  #
413
- # value - The explicit String caption to assign to this block (default: nil).
414
- # key - The String prefix for the caption and counter attribute names.
415
- # If not provided, the name of the context for this block is used.
416
- # (default: nil)
382
+ # value - The String caption to assign to this block or nil to use document attribute.
383
+ # caption_context - The Symbol context to use when resolving caption-related attributes. If not provided, the name of
384
+ # the context for this block is used. Only certain contexts allow the caption to be looked up.
385
+ # (default: @context)
417
386
  #
418
387
  # Returns nothing.
419
- def assign_caption value = nil, key = nil
388
+ def assign_caption value, caption_context = @context
420
389
  unless @caption || !@title || (@caption = value || @document.attributes['caption'])
421
- if (prefix = @document.attributes[%(#{key ||= @context}-caption)])
422
- @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter "#{key}-number", self}. )
390
+ if (attr_name = CAPTION_ATTRIBUTE_NAMES[caption_context]) && (prefix = @document.attributes[attr_name])
391
+ @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter %(#{caption_context}-number), self}. )
423
392
  nil
424
393
  end
425
394
  end
@@ -440,16 +409,12 @@ class AbstractBlock < AbstractNode
440
409
  if (like = section.numbered)
441
410
  if (sectname = section.sectname) == 'appendix'
442
411
  section.numeral = @document.counter 'appendix-number', 'A'
443
- if (caption = @document.attributes['appendix-caption'])
444
- section.caption = %(#{caption} #{section.numeral}: )
445
- else
446
- section.caption = %(#{section.numeral}. )
447
- end
412
+ section.caption = (caption = @document.attributes['appendix-caption']) ? %(#{caption} #{section.numeral}: ) : %(#{section.numeral}. )
448
413
  # NOTE currently chapters in a book doctype are sequential even for multi-part books (see #979)
449
414
  elsif sectname == 'chapter' || like == :chapter
450
- section.numeral = @document.counter 'chapter-number', 1
415
+ section.numeral = (@document.counter 'chapter-number', 1).to_s
451
416
  else
452
- section.numeral = @next_section_ordinal
417
+ section.numeral = sectname == 'part' ? (Helpers.int_to_roman @next_section_ordinal) : @next_section_ordinal.to_s
453
418
  @next_section_ordinal += 1
454
419
  end
455
420
  end
@@ -477,35 +442,76 @@ class AbstractBlock < AbstractNode
477
442
  end
478
443
  end
479
444
 
480
- # stage the Enumerable mixin until we're sure we've got it right
481
- =begin
482
- include ::Enumerable
445
+ protected
483
446
 
484
- # Public: Yield the block on this block node and all its descendant
485
- # block node children to satisfy the Enumerable contract.
486
- #
487
- # Returns nothing
488
- def each &block
489
- # yucky, dlist is a special case
490
- if @context == :dlist
491
- @blocks.flatten.each &block
492
- else
493
- #yield self.header if @context == :document && header?
494
- @blocks.each &block
447
+ # Internal: Performs the work for find_by, but does not handle the StopIteration exception.
448
+ def find_by_internal selector = {}, result = [], &block
449
+ if ((any_context = (context_selector = selector[:context]) ? nil : true) || context_selector == @context) &&
450
+ (!(style_selector = selector[:style]) || style_selector == @style) &&
451
+ (!(role_selector = selector[:role]) || (has_role? role_selector)) &&
452
+ (!(id_selector = selector[:id]) || id_selector == @id)
453
+ if block_given?
454
+ if (verdict = yield self)
455
+ case verdict
456
+ when :prune
457
+ result << self
458
+ raise ::StopIteration if id_selector
459
+ return result
460
+ when :reject
461
+ raise ::StopIteration if id_selector
462
+ return result
463
+ when :stop
464
+ raise ::StopIteration
465
+ else
466
+ result << self
467
+ raise ::StopIteration if id_selector
468
+ end
469
+ elsif id_selector
470
+ raise ::StopIteration
471
+ end
472
+ else
473
+ result << self
474
+ raise ::StopIteration if id_selector
475
+ end
495
476
  end
496
- end
497
-
498
- #--
499
- # TODO is there a way to make this lazy?
500
- def each_recursive &block
501
- block = lambda {|node| node } unless block_given?
502
- results = []
503
- self.each do |node|
504
- results << block.call(node)
505
- results.concat(node.each_recursive(&block)) if ::Enumerable === node
477
+ case @context
478
+ when :document
479
+ unless context_selector == :document
480
+ # process document header as a section, if present
481
+ if header? && (any_context || context_selector == :section)
482
+ @header.find_by_internal selector, result, &block
483
+ end
484
+ @blocks.each do |b|
485
+ next if context_selector == :section && b.context != :section # optimization
486
+ b.find_by_internal selector, result, &block
487
+ end
488
+ end
489
+ when :dlist
490
+ # dlist has different structure than other blocks
491
+ if any_context || context_selector != :section # optimization
492
+ # NOTE the list item of a dlist can be nil, so we have to check
493
+ @blocks.flatten.each {|b| b.find_by_internal selector, result, &block if b }
494
+ end
495
+ when :table
496
+ if selector[:traverse_documents]
497
+ rows.head.each {|r| r.each {|c| c.find_by_internal selector, result, &block } }
498
+ selector = selector.merge context: :document if context_selector == :inner_document
499
+ (rows.body + rows.foot).each do |r|
500
+ r.each do |c|
501
+ c.find_by_internal selector, result, &block
502
+ c.inner_document.find_by_internal selector, result, &block if c.style == :asciidoc
503
+ end
504
+ end
505
+ else
506
+ (rows.head + rows.body + rows.foot).each {|r| r.each {|c| c.find_by_internal selector, result, &block } }
507
+ end
508
+ else
509
+ @blocks.each do |b|
510
+ next if context_selector == :section && b.context != :section # optimization
511
+ b.find_by_internal selector, result, &block
512
+ end
506
513
  end
507
- block_given? ? results : results.to_enum
514
+ result
508
515
  end
509
- =end
510
516
  end
511
517
  end