asciidoctor 0.1.0 → 0.1.1

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 (40) hide show
  1. data/README.asciidoc +11 -2
  2. data/asciidoctor.gemspec +3 -2
  3. data/lib/asciidoctor.rb +95 -62
  4. data/lib/asciidoctor/abstract_block.rb +7 -5
  5. data/lib/asciidoctor/abstract_node.rb +63 -15
  6. data/lib/asciidoctor/attribute_list.rb +3 -1
  7. data/lib/asciidoctor/backends/base_template.rb +17 -7
  8. data/lib/asciidoctor/backends/docbook45.rb +182 -150
  9. data/lib/asciidoctor/backends/html5.rb +138 -110
  10. data/lib/asciidoctor/block.rb +21 -18
  11. data/lib/asciidoctor/callouts.rb +3 -1
  12. data/lib/asciidoctor/cli/invoker.rb +3 -3
  13. data/lib/asciidoctor/cli/options.rb +6 -6
  14. data/lib/asciidoctor/debug.rb +7 -6
  15. data/lib/asciidoctor/document.rb +197 -25
  16. data/lib/asciidoctor/errors.rb +1 -1
  17. data/lib/asciidoctor/helpers.rb +29 -0
  18. data/lib/asciidoctor/inline.rb +11 -4
  19. data/lib/asciidoctor/lexer.rb +338 -182
  20. data/lib/asciidoctor/list_item.rb +14 -12
  21. data/lib/asciidoctor/reader.rb +423 -206
  22. data/lib/asciidoctor/renderer.rb +59 -15
  23. data/lib/asciidoctor/section.rb +7 -4
  24. data/lib/asciidoctor/substituters.rb +536 -511
  25. data/lib/asciidoctor/table.rb +473 -472
  26. data/lib/asciidoctor/version.rb +1 -1
  27. data/man/asciidoctor.1 +23 -14
  28. data/man/asciidoctor.ad +13 -7
  29. data/test/attributes_test.rb +42 -8
  30. data/test/blocks_test.rb +161 -1
  31. data/test/document_test.rb +134 -16
  32. data/test/invoker_test.rb +14 -6
  33. data/test/lexer_test.rb +45 -18
  34. data/test/lists_test.rb +79 -0
  35. data/test/paragraphs_test.rb +9 -1
  36. data/test/reader_test.rb +456 -19
  37. data/test/sections_test.rb +19 -0
  38. data/test/substitutions_test.rb +14 -12
  39. data/test/tables_test.rb +10 -10
  40. metadata +3 -5
@@ -1,9 +1,10 @@
1
+ module Asciidoctor
1
2
  # Public: An abstract base class that provides state and methods for managing a
2
3
  # node of AsciiDoc content. The state and methods on this class are comment to
3
4
  # all content segments in an AsciiDoc document.
4
- class Asciidoctor::AbstractNode
5
+ class AbstractNode
5
6
 
6
- include Asciidoctor::Substituters
7
+ include Substituters
7
8
 
8
9
  # Public: Get the element which is the parent of this node
9
10
  attr_reader :parent
@@ -24,7 +25,7 @@ class Asciidoctor::AbstractNode
24
25
  @parent = (context != :document ? parent : nil)
25
26
 
26
27
  if !parent.nil?
27
- @document = parent.is_a?(Asciidoctor::Document) ? parent : parent.document
28
+ @document = parent.is_a?(Document) ? parent : parent.document
28
29
  else
29
30
  @document = nil
30
31
  end
@@ -34,20 +35,62 @@ class Asciidoctor::AbstractNode
34
35
  @passthroughs = []
35
36
  end
36
37
 
38
+ # Public: Get the value of the specified attribute
39
+ #
40
+ # Get the value for the specified attribute. First look in the attributes on
41
+ # this node and return the value of the attribute if found. Otherwise, if
42
+ # this node is a child of the Document node, look in the attributes of the
43
+ # Document node and return the value of the attribute if found. Otherwise,
44
+ # return the default value, which defaults to nil.
45
+ #
46
+ # name - the name of the attribute to lookup as a String or Symbol
47
+ # default - the value to return if the attribute is not found (default: nil)
48
+ #
49
+ # return the value of the attribute or the default value if the attribute
50
+ # is not found in the attributes of this node or the document node
37
51
  def attr(name, default = nil)
52
+ name = name.to_s if name.is_a?(Symbol)
38
53
  if self == @document
39
- default.nil? ? @attributes[name.to_s] : @attributes.fetch(name.to_s, default)
54
+ default.nil? ? @attributes[name] : @attributes.fetch(name, default)
40
55
  else
41
- default.nil? ? @attributes.fetch(name.to_s, @document.attr(name)) :
42
- @attributes.fetch(name.to_s, @document.attr(name, default))
56
+ default.nil? ? @attributes.fetch(name, @document.attr(name)) :
57
+ @attributes.fetch(name, @document.attr(name, default))
43
58
  end
44
59
  end
45
60
 
46
- def attr?(name)
47
- if self == @document
48
- @attributes.has_key? name.to_s
61
+ # Public: Check if the attribute is defined, optionally performing a
62
+ # comparison of its value
63
+ #
64
+ # Check if the attribute is defined. First look in the attributes on this
65
+ # node. If not found, and this node is a child of the Document node, look in
66
+ # the attributes of the Document node. If the attribute is found and a
67
+ # comparison value is specified, return whether the two values match.
68
+ # Otherwise, return whether the attribute was found.
69
+ #
70
+ # name - the name of the attribute to lookup as a String or Symbol
71
+ # expect - the expected value of the attribute (default: nil)
72
+ #
73
+ # return a Boolean indicating whether the attribute exists and, if a
74
+ # comparison value is specified, whether the value of the attribute matches
75
+ # the comparison value
76
+ def attr?(name, expect = nil)
77
+ name = name.to_s if name.is_a?(Symbol)
78
+ if expect.nil?
79
+ if @attributes.has_key? name
80
+ true
81
+ elsif self != @document
82
+ @document.attributes.has_key? name
83
+ else
84
+ false
85
+ end
49
86
  else
50
- @attributes.has_key?(name.to_s) || @document.attr?(name)
87
+ if @attributes.has_key? name
88
+ @attributes[name] == expect
89
+ elsif self != @document && @document.attributes.has_key?(name)
90
+ @document.attributes[name] == expect
91
+ else
92
+ false
93
+ end
51
94
  end
52
95
  end
53
96
 
@@ -119,6 +162,8 @@ class Asciidoctor::AbstractNode
119
162
 
120
163
  # Public: Construct a reference or data URI to the target image.
121
164
  #
165
+ # If the target image is a URI reference, then leave it untouched.
166
+ #
122
167
  # The target image is resolved relative to the directory retrieved from the
123
168
  # specified attribute key, if provided.
124
169
  #
@@ -135,7 +180,9 @@ class Asciidoctor::AbstractNode
135
180
  #
136
181
  # Returns A String reference or data URI for the target image
137
182
  def image_uri(target_image, asset_dir_key = 'imagesdir')
138
- if @document.safe < Asciidoctor::SafeMode::SECURE && @document.attr?('data-uri')
183
+ if target_image.include?(':') && target_image.match(Asciidoctor::REGEXP[:uri_sniff])
184
+ target_image
185
+ elsif @document.safe < Asciidoctor::SafeMode::SECURE && @document.attr?('data-uri')
139
186
  generate_data_uri(target_image, asset_dir_key)
140
187
  elsif asset_dir_key && attr?(asset_dir_key)
141
188
  File.join(@document.attr(asset_dir_key), target_image)
@@ -157,7 +204,7 @@ class Asciidoctor::AbstractNode
157
204
  #
158
205
  # Returns A String data URI containing the content of the target image
159
206
  def generate_data_uri(target_image, asset_dir_key = nil)
160
- Asciidoctor.require_library 'base64'
207
+ Helpers.require_library 'base64'
161
208
 
162
209
  mimetype = 'image/' + File.extname(target_image)[1..-1]
163
210
  if asset_dir_key
@@ -225,7 +272,7 @@ class Asciidoctor::AbstractNode
225
272
  # of this method are still doing a File.join to finish the task
226
273
  def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true)
227
274
  # TODO we may use pathname enough to make it a top-level require
228
- Asciidoctor.require_library 'pathname'
275
+ Helpers.require_library 'pathname'
229
276
 
230
277
  input_path = @document.base_dir
231
278
  asset_path = Pathname.new(asset_ref)
@@ -236,11 +283,11 @@ class Asciidoctor::AbstractNode
236
283
  asset_path = asset_path.cleanpath.to_s
237
284
  end
238
285
 
239
- if @document.safe >= Asciidoctor::SafeMode::SAFE
286
+ if @document.safe >= SafeMode::SAFE
240
287
  relative_asset_path = Pathname.new(asset_path).relative_path_from(Pathname.new(input_path)).to_s
241
288
  if relative_asset_path.start_with?('..')
242
289
  if autocorrect
243
- puts 'asciidoctor: WARNING: ' + asset_name + ' has illegal reference to ancestor of base directory'
290
+ puts "asciidoctor: WARNING: #{asset_name} has illegal reference to ancestor of base directory"
244
291
  else
245
292
  raise SecurityError, "#{asset_name} has reference to path outside of base directory, disallowed in safe mode: #{asset_path}"
246
293
  end
@@ -257,3 +304,4 @@ class Asciidoctor::AbstractNode
257
304
  end
258
305
 
259
306
  end
307
+ end
@@ -1,3 +1,4 @@
1
+ module Asciidoctor
1
2
  # Public: Handles parsing AsciiDoc attribute lists into a Hash of key/value
2
3
  # pairs. By default, attributes must each be separated by a comma and quotes
3
4
  # may be used around the value. If a key is not detected, the value is assigned
@@ -19,7 +20,7 @@
19
20
  # attrlist.parse(['style', 'attribution', 'citetitle'])
20
21
  # => {'style' => 'quote', 'attribution' => 'Famous Person', 'citetitle' => 'Famous Book (2001)'}
21
22
  #
22
- class Asciidoctor::AttributeList
23
+ class AttributeList
23
24
 
24
25
  # Public: Regular expressions for detecting the boundary of a value
25
26
  BOUNDARY_PATTERNS = {
@@ -215,3 +216,4 @@ class Asciidoctor::AttributeList
215
216
  end
216
217
 
217
218
  end
219
+ end
@@ -1,10 +1,11 @@
1
+ module Asciidoctor
1
2
  # An abstract base class that provides methods for definining and rendering the
2
3
  # backend templates. Concrete subclasses must implement the template method.
3
4
  #
4
5
  # NOTE we must use double quotes for attribute values in the HTML/XML output to
5
6
  # prevent quote processing. This requirement seems hackish, but AsciiDoc has
6
7
  # this same issue.
7
- class Asciidoctor::BaseTemplate
8
+ class BaseTemplate
8
9
 
9
10
  attr_reader :view
10
11
  attr_reader :eruby
@@ -38,11 +39,19 @@ class Asciidoctor::BaseTemplate
38
39
  # node - The concrete instance of AsciiDoctor::AbstractNode to render
39
40
  # locals - A Hash of additional variables. Not currently in use.
40
41
  def render(node = Object.new, locals = {})
41
- # this is hot code, so we inline both calls rather than capture output to a local variable
42
- if node.renderer.compact && (@view == 'document' || @view == 'embedded')
43
- compact(template.result(node.get_binding(self)))
42
+ tmpl = template
43
+ if tmpl.equal? :content
44
+ result = node.content
45
+ #elsif tmpl.is_a?(String)
46
+ # result = tmpl
44
47
  else
45
- template.result(node.get_binding(self))
48
+ result = tmpl.result(node.get_binding(self))
49
+ end
50
+
51
+ if (@view == 'document' || @view == 'embedded') && node.renderer.compact
52
+ compact result
53
+ else
54
+ result
46
55
  end
47
56
  end
48
57
 
@@ -54,7 +63,7 @@ class Asciidoctor::BaseTemplate
54
63
  # returns the text with blank lines removed and HTML line feed entities
55
64
  # converted to an endline character.
56
65
  def compact(str)
57
- str.gsub(Asciidoctor::BLANK_LINES_PATTERN, '').gsub(Asciidoctor::LINE_FEED_ENTITY, "\n")
66
+ str.gsub(BLANK_LINES_PATTERN, '').gsub(LINE_FEED_ENTITY, "\n")
58
67
  end
59
68
 
60
69
  # Public: Preserve endlines by replacing them with the HTML line feed entity.
@@ -65,7 +74,7 @@ class Asciidoctor::BaseTemplate
65
74
  # text - the String to process
66
75
  # node - the concrete instance of Asciidoctor::AbstractNode being rendered
67
76
  def preserve_endlines(str, node)
68
- node.renderer.compact ? str.gsub("\n", Asciidoctor::LINE_FEED_ENTITY) : str
77
+ node.renderer.compact ? str.gsub("\n", LINE_FEED_ENTITY) : str
69
78
  end
70
79
 
71
80
  def template
@@ -96,3 +105,4 @@ class Asciidoctor::BaseTemplate
96
105
  attribute('id', '@id')
97
106
  end
98
107
  end
108
+ end
@@ -1,35 +1,40 @@
1
- class Asciidoctor::BaseTemplate
2
- def role
3
- attribute('role', :role)
4
- end
1
+ module Asciidoctor
2
+ class BaseTemplate
3
+ def tag(name, key)
4
+ type = key.is_a?(Symbol) ? :attr : :var
5
+ key = key.to_s
6
+ if type == :attr
7
+ # example: <% if attr? 'foo' %><bar><%= attr 'foo' %></bar><% end %>
8
+ %(<% if attr? '#{key}' %><#{name}><%= attr '#{key}' %></#{name}><% end %>)
9
+ else
10
+ # example: <% unless foo.to_s.empty? %><bar><%= foo %></bar><% end %>
11
+ %(<% unless #{key}.to_s.empty? %><#{name}><%= #{key} %></#{name}><% end %>)
12
+ end
13
+ end
5
14
 
6
- def xreflabel
7
- attribute('xreflabel', :reftext)
8
- end
15
+ def title_tag(optional = true)
16
+ if optional
17
+ %q{<%= title? ? "<title>#{title}</title>" : '' %>}
18
+ else
19
+ %q{<title><%= title %></title>}
20
+ end
21
+ end
9
22
 
10
- def title
11
- tag('title', 'title')
12
- end
23
+ def common_attrs(id, role, reftext)
24
+ %(#{id && " id=\"#{id}\""}#{role && " role=\"#{role}\""}#{reftext && " xreflabel=\"#{reftext}\""})
25
+ end
13
26
 
14
- def tag(name, key)
15
- type = key.is_a?(Symbol) ? :attr : :var
16
- key = key.to_s
17
- if type == :attr
18
- # example: <% if attr? 'foo' %><bar><%= attr 'foo' %></bar><% end %>
19
- %(<% if attr? '#{key}' %><#{name}><%= attr '#{key}' %></#{name}><% end %>)
20
- else
21
- # example: <% unless foo.to_s.empty? %><bar><%= foo %></bar><% end %>
22
- %(<% unless #{key}.to_s.empty? %><#{name}><%= #{key} %></#{name}><% end %>)
27
+ def common_attrs_erb
28
+ %q{<%= template.common_attrs(@id, (attr 'role'), (attr 'reftext')) %>}
23
29
  end
24
30
  end
25
- end
26
31
 
27
- module Asciidoctor::DocBook45
28
- class DocumentTemplate < ::Asciidoctor::BaseTemplate
32
+ module DocBook45
33
+ class DocumentTemplate < BaseTemplate
29
34
  def docinfo
30
35
  <<-EOF
31
36
  <% if has_header? && !notitle %>
32
- #{tag 'title', '@header.name'}
37
+ #{tag 'title', '@header.title'}
33
38
  <% end %>
34
39
  <% if attr? :revdate %>
35
40
  <date><%= attr :revdate %></date>
@@ -65,14 +70,14 @@ class DocumentTemplate < ::Asciidoctor::BaseTemplate
65
70
  <% if attr? :toc %><?asciidoc-toc?><% end %>
66
71
  <% if attr? :numbered %><?asciidoc-numbered?><% end %>
67
72
  <% if doctype == 'book' %>
68
- <book lang="en">
73
+ <book<% unless attr? :nolang %> lang="<%= attr :lang, 'en' %>"<% end %>>
69
74
  <bookinfo>
70
75
  #{docinfo}
71
76
  </bookinfo>
72
77
  <%= content %>
73
78
  </book>
74
79
  <% else %>
75
- <article lang="en">
80
+ <article<% unless attr? :nolang %> lang="<%= attr :lang, 'en' %>"<% end %>>
76
81
  <articleinfo>
77
82
  #{docinfo}
78
83
  </articleinfo>
@@ -83,19 +88,17 @@ class DocumentTemplate < ::Asciidoctor::BaseTemplate
83
88
  end
84
89
  end
85
90
 
86
- class EmbeddedTemplate < ::Asciidoctor::BaseTemplate
91
+ class EmbeddedTemplate < BaseTemplate
87
92
  def template
88
- @template ||= @eruby.new <<-EOS
89
- <%#encoding:UTF-8%><%= content %>
90
- EOS
93
+ :content
91
94
  end
92
95
  end
93
96
 
94
- class BlockPreambleTemplate < ::Asciidoctor::BaseTemplate
97
+ class BlockPreambleTemplate < BaseTemplate
95
98
  def template
96
99
  @template ||= @eruby.new <<-EOF
97
- <%#encoding:UTF-8%><% if document.doctype == 'book' %>
98
- <preface#{id}#{role}#{xreflabel}>
100
+ <%#encoding:UTF-8%><% if @document.doctype == 'book' %>
101
+ <preface#{common_attrs_erb}>
99
102
  <title><%= title %></title>
100
103
  <%= content %>
101
104
  </preface>
@@ -106,46 +109,62 @@ class BlockPreambleTemplate < ::Asciidoctor::BaseTemplate
106
109
  end
107
110
  end
108
111
 
109
- class SectionTemplate < ::Asciidoctor::BaseTemplate
112
+ class SectionTemplate < BaseTemplate
113
+ def section(sec)
114
+ if sec.special
115
+ tag = sec.level <= 1 ? sec.sectname : 'section'
116
+ else
117
+ tag = sec.document.doctype == 'book' && sec.level <= 1 ? 'chapter' : 'section'
118
+ end
119
+ %(<#{tag}#{common_attrs(sec.id, (sec.attr 'role'), (sec.attr 'reftext'))}>
120
+ #{sec.title? ? "<title>#{sec.title}</title>" : nil}
121
+ #{sec.content}
122
+ </#{tag}>)
123
+ end
124
+
110
125
  def template
126
+ # hot piece of code, optimized for speed
111
127
  @template ||= @eruby.new <<-EOF
112
- <%#encoding:UTF-8%><<%= @special ? @sectname : (document.doctype == 'book' && @level <= 1 ? 'chapter' : 'section') %>#{id}#{role}#{xreflabel}>
113
- #{title}
114
- <%= content %>
115
- </<%= @special ? @sectname : (document.doctype == 'book' && @level <= 1 ? 'chapter' : 'section') %>>
128
+ <%#encoding:UTF-8%><%= template.section(self) %>
116
129
  EOF
117
130
  end
118
131
  end
119
132
 
120
- class BlockFloatingTitleTemplate < ::Asciidoctor::BaseTemplate
133
+ class BlockFloatingTitleTemplate < BaseTemplate
121
134
  def template
122
135
  @template ||= @eruby.new <<-EOS
123
- <%#encoding:UTF-8%><bridgehead#{id}#{role}#{xreflabel} renderas="sect<%= @level %>"><%= title %></bridgehead>
136
+ <%#encoding:UTF-8%><bridgehead#{common_attrs_erb} renderas="sect<%= @level %>"><%= title %></bridgehead>
124
137
  EOS
125
138
  end
126
139
  end
127
140
 
128
141
 
129
- class BlockParagraphTemplate < ::Asciidoctor::BaseTemplate
142
+ class BlockParagraphTemplate < BaseTemplate
143
+
144
+ def paragraph(id, role, reftext, title, content)
145
+ if title
146
+ %(<formalpara#{common_attrs(id, role, reftext)}>
147
+ <title>#{title}</title>
148
+ <para>#{content}</para>
149
+ </formalpara>)
150
+ else
151
+ %(<simpara#{common_attrs(id, role, reftext)}>#{content}</simpara>)
152
+ end
153
+ end
154
+
130
155
  def template
156
+ # very hot piece of code, optimized for speed
131
157
  @template ||= @eruby.new <<-EOF
132
- <%#encoding:UTF-8%><% if !title? %>
133
- <simpara#{id}#{role}#{xreflabel}><%= content %></simpara>
134
- <% else %>
135
- <formalpara#{id}#{role}#{xreflabel}>
136
- <title><%= title %></title>
137
- <para><%= content %></para>
138
- </formalpara>
139
- <% end %>
158
+ <%#encoding:UTF-8%><%= template.paragraph(@id, (attr 'role'), (attr 'reftext'), title? ? title : nil, content) %>
140
159
  EOF
141
160
  end
142
161
  end
143
162
 
144
- class BlockAdmonitionTemplate < ::Asciidoctor::BaseTemplate
163
+ class BlockAdmonitionTemplate < BaseTemplate
145
164
  def template
146
165
  @template ||= @eruby.new <<-EOF
147
- <%#encoding:UTF-8%><<%= attr :name %>#{id}#{role}#{xreflabel}>
148
- #{title}
166
+ <%#encoding:UTF-8%><<%= attr :name %>#{common_attrs_erb}>
167
+ #{title_tag}
149
168
  <% if blocks? %>
150
169
  <%= content %>
151
170
  <% else %>
@@ -156,12 +175,12 @@ class BlockAdmonitionTemplate < ::Asciidoctor::BaseTemplate
156
175
  end
157
176
  end
158
177
 
159
- class BlockUlistTemplate < ::Asciidoctor::BaseTemplate
178
+ class BlockUlistTemplate < BaseTemplate
160
179
  def template
161
180
  @template ||= @eruby.new <<-EOF
162
- <%#encoding:UTF-8%><% if (attr :style) == 'bibliography' %>
163
- <bibliodiv#{id}#{role}#{xreflabel}>
164
- #{title}
181
+ <%#encoding:UTF-8%><% if attr? :style, 'bibliography' %>
182
+ <bibliodiv#{common_attrs_erb}>
183
+ #{title_tag}
165
184
  <% content.each do |li| %>
166
185
  <bibliomixed>
167
186
  <bibliomisc><%= li.text %></bibliomisc>
@@ -172,8 +191,8 @@ class BlockUlistTemplate < ::Asciidoctor::BaseTemplate
172
191
  <% end %>
173
192
  </bibliodiv>
174
193
  <% else %>
175
- <itemizedlist#{id}#{role}#{xreflabel}>
176
- #{title}
194
+ <itemizedlist#{common_attrs_erb}>
195
+ #{title_tag}
177
196
  <% content.each do |li| %>
178
197
  <listitem>
179
198
  <simpara><%= li.text %></simpara>
@@ -188,11 +207,11 @@ class BlockUlistTemplate < ::Asciidoctor::BaseTemplate
188
207
  end
189
208
  end
190
209
 
191
- class BlockOlistTemplate < ::Asciidoctor::BaseTemplate
210
+ class BlockOlistTemplate < BaseTemplate
192
211
  def template
193
212
  @template ||= @eruby.new <<-EOF
194
- <%#encoding:UTF-8%><orderedlist#{id}#{role}#{xreflabel}#{attribute('numeration', :style)}>
195
- #{title}
213
+ <%#encoding:UTF-8%><orderedlist#{common_attrs_erb}#{attribute('numeration', :style)}>
214
+ #{title_tag}
196
215
  <% content.each do |li| %>
197
216
  <listitem>
198
217
  <simpara><%= li.text %></simpara>
@@ -206,25 +225,25 @@ class BlockOlistTemplate < ::Asciidoctor::BaseTemplate
206
225
  end
207
226
  end
208
227
 
209
- class BlockColistTemplate < ::Asciidoctor::BaseTemplate
228
+ class BlockColistTemplate < BaseTemplate
210
229
  def template
211
230
  @template ||= @eruby.new <<-EOF
212
- <%#encoding:UTF-8%><calloutlist#{id}#{role}#{xreflabel}>
213
- #{title}
231
+ <%#encoding:UTF-8%><calloutlist#{common_attrs_erb}>
232
+ #{title_tag}
214
233
  <% content.each do |li| %>
215
- <callout arearefs="<%= li.attr :coids %>">
216
- <para><%= li.text %></para>
217
- <% if li.blocks? %>
234
+ <callout arearefs="<%= li.attr :coids %>">
235
+ <para><%= li.text %></para>
236
+ <% if li.blocks? %>
218
237
  <%= li.content %>
219
- <% end %>
220
- </callout>
238
+ <% end %>
239
+ </callout>
221
240
  <% end %>
222
241
  </calloutlist>
223
242
  EOF
224
243
  end
225
244
  end
226
245
 
227
- class BlockDlistTemplate < ::Asciidoctor::BaseTemplate
246
+ class BlockDlistTemplate < BaseTemplate
228
247
  LIST_TAGS = {
229
248
  'labeled' => {
230
249
  :list => 'variablelist',
@@ -249,8 +268,8 @@ class BlockDlistTemplate < ::Asciidoctor::BaseTemplate
249
268
  def template
250
269
  @template ||= @eruby.new <<-EOF
251
270
  <%#encoding:UTF-8%><% tags = (template.class::LIST_TAGS[attr :style] || template.class::LIST_TAGS['labeled']) %>
252
- <% if tags[:list] %><<%= tags[:list] %>#{id}#{role}#{xreflabel}><% end %>
253
- #{title}
271
+ <% if tags[:list] %><<%= tags[:list] %>#{common_attrs_erb}><% end %>
272
+ #{title_tag}
254
273
  <% content.each do |dt, dd| %>
255
274
  <<%= tags[:entry] %>>
256
275
  <<%= tags[:term] %>>
@@ -273,28 +292,26 @@ class BlockDlistTemplate < ::Asciidoctor::BaseTemplate
273
292
  end
274
293
  end
275
294
 
276
- class BlockOpenTemplate < ::Asciidoctor::BaseTemplate
295
+ class BlockOpenTemplate < BaseTemplate
277
296
  def template
278
- @template ||= @eruby.new <<-EOS
279
- <%#encoding:UTF-8%><%= content %>
280
- EOS
297
+ :content
281
298
  end
282
299
  end
283
300
 
284
- class BlockListingTemplate < ::Asciidoctor::BaseTemplate
301
+ class BlockListingTemplate < BaseTemplate
285
302
  def template
286
303
  @template ||= @eruby.new <<-EOF
287
304
  <%#encoding:UTF-8%><% if !title? %>
288
- <% if (attr :style) == 'source' %>
289
- <programlisting#{id}#{role}#{xreflabel}#{attribute('language', :language)} linenumbering="<%= (attr? :linenums) ? 'numbered' : 'unnumbered' %>"><%= template.preserve_endlines(content, self) %></programlisting>
305
+ <% if attr? :style, 'source' %>
306
+ <programlisting#{common_attrs_erb}#{attribute('language', :language)} linenumbering="<%= (attr? :linenums) ? 'numbered' : 'unnumbered' %>"><%= template.preserve_endlines(content, self) %></programlisting>
290
307
  <% else %>
291
- <screen#{id}#{role}#{xreflabel}><%= template.preserve_endlines(content, self) %></screen>
308
+ <screen#{common_attrs_erb}><%= template.preserve_endlines(content, self) %></screen>
292
309
  <% end %>
293
310
  <% else %>
294
- <formalpara#{id}#{role}#{xreflabel}>
295
- <title><%= title %></title>
311
+ <formalpara#{common_attrs_erb}>
312
+ #{title_tag false}
296
313
  <para>
297
- <% if (attr :style) == 'source' %>
314
+ <% if attr :style, 'source' %>
298
315
  <programlisting language="<%= attr :language %>" linenumbering="<%= (attr? :linenums) ? 'numbered' : 'unnumbered' %>"><%= template.preserve_endlines(content, self) %></programlisting>
299
316
  <% else %>
300
317
  <screen><%= template.preserve_endlines(content, self) %></screen>
@@ -306,14 +323,14 @@ class BlockListingTemplate < ::Asciidoctor::BaseTemplate
306
323
  end
307
324
  end
308
325
 
309
- class BlockLiteralTemplate < ::Asciidoctor::BaseTemplate
326
+ class BlockLiteralTemplate < BaseTemplate
310
327
  def template
311
328
  @template ||= @eruby.new <<-EOF
312
329
  <%#encoding:UTF-8%><% if !title? %>
313
- <literallayout#{id}#{role}#{xreflabel} class="monospaced"><%= template.preserve_endlines(content, self) %></literallayout>
330
+ <literallayout#{common_attrs_erb} class="monospaced"><%= template.preserve_endlines(content, self) %></literallayout>
314
331
  <% else %>
315
- <formalpara#{id}#{role}#{xreflabel}>
316
- <title><%= title %></title>
332
+ <formalpara#{common_attrs_erb}>
333
+ #{title_tag false}
317
334
  <para>
318
335
  <literallayout class="monospaced"><%= template.preserve_endlines(content, self) %></literallayout>
319
336
  </para>
@@ -323,33 +340,33 @@ class BlockLiteralTemplate < ::Asciidoctor::BaseTemplate
323
340
  end
324
341
  end
325
342
 
326
- class BlockExampleTemplate < ::Asciidoctor::BaseTemplate
343
+ class BlockExampleTemplate < BaseTemplate
327
344
  def template
328
345
  @template ||= @eruby.new <<-EOF
329
- <%#encoding:UTF-8%><example#{id}#{role}#{xreflabel}>
330
- #{title}
346
+ <%#encoding:UTF-8%><example#{common_attrs_erb}>
347
+ #{title_tag}
331
348
  <%= content %>
332
349
  </example>
333
350
  EOF
334
351
  end
335
352
  end
336
353
 
337
- class BlockSidebarTemplate < ::Asciidoctor::BaseTemplate
354
+ class BlockSidebarTemplate < BaseTemplate
338
355
  def template
339
356
  @template ||= @eruby.new <<-EOF
340
- <%#encoding:UTF-8%><sidebar#{id}#{role}#{xreflabel}>
341
- #{title}
357
+ <%#encoding:UTF-8%><sidebar#{common_attrs_erb}>
358
+ #{title_tag}
342
359
  <%= content %>
343
360
  </sidebar>
344
361
  EOF
345
362
  end
346
363
  end
347
364
 
348
- class BlockQuoteTemplate < ::Asciidoctor::BaseTemplate
365
+ class BlockQuoteTemplate < BaseTemplate
349
366
  def template
350
367
  @template ||= @eruby.new <<-EOF
351
- <%#encoding:UTF-8%><blockquote#{id}#{role}#{xreflabel}>
352
- #{title}
368
+ <%#encoding:UTF-8%><blockquote#{common_attrs_erb}>
369
+ #{title_tag}
353
370
  <% if (attr? :attribution) || (attr? :citetitle) %>
354
371
  <attribution>
355
372
  <% if attr? :attribution %>
@@ -358,7 +375,7 @@ class BlockQuoteTemplate < ::Asciidoctor::BaseTemplate
358
375
  #{tag 'citetitle', :citetitle}
359
376
  </attribution>
360
377
  <% end %>
361
- <% if !buffer.nil? %>
378
+ <% if !@buffer.nil? %>
362
379
  <simpara><%= content %></simpara>
363
380
  <% else %>
364
381
  <%= content %>
@@ -368,11 +385,11 @@ class BlockQuoteTemplate < ::Asciidoctor::BaseTemplate
368
385
  end
369
386
  end
370
387
 
371
- class BlockVerseTemplate < ::Asciidoctor::BaseTemplate
388
+ class BlockVerseTemplate < BaseTemplate
372
389
  def template
373
390
  @template ||= @eruby.new <<-EOF
374
- <%#encoding:UTF-8%><blockquote#{id}#{role}#{xreflabel}>
375
- #{title}
391
+ <%#encoding:UTF-8%><blockquote#{common_attrs_erb}>
392
+ #{title_tag}
376
393
  <% if (attr? :attribution) || (attr? :citetitle) %>
377
394
  <attribution>
378
395
  <% if attr? :attribution %>
@@ -387,20 +404,18 @@ class BlockVerseTemplate < ::Asciidoctor::BaseTemplate
387
404
  end
388
405
  end
389
406
 
390
- class BlockPassTemplate < ::Asciidoctor::BaseTemplate
407
+ class BlockPassTemplate < BaseTemplate
391
408
  def template
392
- @template ||= @eruby.new <<-EOS
393
- <%#encoding:UTF-8%><%= content %>
394
- EOS
409
+ :content
395
410
  end
396
411
  end
397
412
 
398
- class BlockTableTemplate < ::Asciidoctor::BaseTemplate
413
+ class BlockTableTemplate < BaseTemplate
399
414
  def template
400
415
  @template ||= @eruby.new <<-EOS
401
- <%#encoding:UTF-8%><<%= title? ? 'table' : 'informaltable'%>#{id}#{role}#{xreflabel} frame="<%= attr :frame, 'all'%>"
416
+ <%#encoding:UTF-8%><<%= title? ? 'table' : 'informaltable'%>#{common_attrs_erb} frame="<%= attr :frame, 'all'%>"
402
417
  rowsep="<%= ['none', 'cols'].include?(attr :grid) ? 0 : 1 %>" colsep="<%= ['none', 'rows'].include?(attr :grid) ? 0 : 1 %>">
403
- #{title}
418
+ #{title_tag}
404
419
  <% if attr? :width %>
405
420
  <?dbhtml table-width="<%= attr :width %>"?>
406
421
  <?dbfo table-width="<%= attr :width %>"?>
@@ -410,15 +425,15 @@ class BlockTableTemplate < ::Asciidoctor::BaseTemplate
410
425
  <% @columns.each do |col| %>
411
426
  <colspec colname="col_<%= col.attr :colnumber %>" colwidth="<%= col.attr((attr? :width) ? :colabswidth : :colpcwidth) %>*"/>
412
427
  <% end %>
413
- <% [:head, :foot, :body].select {|tsec| !rows[tsec].empty? }.each do |tsec| %>
414
- <t<%= tsec %>>
415
- <% @rows[tsec].each do |row| %>
428
+ <% [:head, :foot, :body].select {|tblsec| !rows[tblsec].empty? }.each do |tblsec| %>
429
+ <t<%= tblsec %>>
430
+ <% @rows[tblsec].each do |row| %>
416
431
  <row>
417
432
  <% row.each do |cell| %>
418
433
  <entry#{attribute('align', 'cell.attr :halign')}#{attribute('valign', 'cell.attr :valign')}<%
419
434
  if cell.colspan %> namest="col_<%= cell.column.attr :colnumber %>" nameend="col_<%= (cell.column.attr :colnumber) + cell.colspan - 1 %>"<%
420
435
  end %><% if cell.rowspan %> morerows="<%= cell.rowspan - 1 %>"<% end %>><%
421
- if tsec == :head %><%= cell.text %><%
436
+ if tblsec == :head %><%= cell.text %><%
422
437
  else %><%
423
438
  case cell.attr(:style)
424
439
  when :asciidoc %><%= cell.content %><%
@@ -430,7 +445,7 @@ class BlockTableTemplate < ::Asciidoctor::BaseTemplate
430
445
  <% end %>
431
446
  </row>
432
447
  <% end %>
433
- </t<%= tsec %>>
448
+ </t<%= tblsec %>>
434
449
  <% end %>
435
450
  </tgroup>
436
451
  </<%= title? ? 'table' : 'informaltable'%>>
@@ -438,11 +453,11 @@ class BlockTableTemplate < ::Asciidoctor::BaseTemplate
438
453
  end
439
454
  end
440
455
 
441
- class BlockImageTemplate < ::Asciidoctor::BaseTemplate
456
+ class BlockImageTemplate < BaseTemplate
442
457
  def template
443
458
  @template ||= @eruby.new <<-EOF
444
- <%#encoding:UTF-8%><%#encoding:UTF-8%><figure#{id}#{role}#{xreflabel}>
445
- #{title}
459
+ <%#encoding:UTF-8%><%#encoding:UTF-8%><figure#{common_attrs_erb}>
460
+ #{title_tag}
446
461
  <mediaobject>
447
462
  <imageobject>
448
463
  <imagedata fileref="<%= image_uri(attr :target) %>"#{attribute('contentwidth', :width)}#{attribute('contentdepth', :height)}/>
@@ -454,7 +469,7 @@ class BlockImageTemplate < ::Asciidoctor::BaseTemplate
454
469
  end
455
470
  end
456
471
 
457
- class BlockRulerTemplate < ::Asciidoctor::BaseTemplate
472
+ class BlockRulerTemplate < BaseTemplate
458
473
  def template
459
474
  @template ||= @eruby.new <<-EOF
460
475
  <%#encoding:UTF-8%><simpara><?asciidoc-hr?></simpara>
@@ -462,59 +477,74 @@ class BlockRulerTemplate < ::Asciidoctor::BaseTemplate
462
477
  end
463
478
  end
464
479
 
465
- class InlineBreakTemplate < ::Asciidoctor::BaseTemplate
480
+ class BlockPageBreakTemplate < BaseTemplate
481
+ def template
482
+ @template ||= @eruby.new <<-EOF
483
+ <%#encoding:UTF-8%><simpara><?asciidoc-pagebreak?></simpara>
484
+ EOF
485
+ end
486
+ end
487
+
488
+ class InlineBreakTemplate < BaseTemplate
466
489
  def template
467
490
  @template ||= @eruby.new <<-EOF
468
- <%#encoding:UTF-8%><%= text %><?asciidoc-br?>
491
+ <%#encoding:UTF-8%><%= @text %><?asciidoc-br?>
469
492
  EOF
470
493
  end
471
494
  end
472
495
 
473
- class InlineQuotedTemplate < ::Asciidoctor::BaseTemplate
496
+ class InlineQuotedTemplate < BaseTemplate
474
497
  QUOTED_TAGS = {
475
498
  :emphasis => ['<emphasis>', '</emphasis>'],
476
499
  :strong => ['<emphasis role="strong">', '</emphasis>'],
477
500
  :monospaced => ['<literal>', '</literal>'],
478
501
  :superscript => ['<superscript>', '</superscript>'],
479
502
  :subscript => ['<subscript>', '</subscript>'],
480
- :double => [Asciidoctor::INTRINSICS['ldquo'], Asciidoctor::INTRINSICS['rdquo']],
481
- :single => [Asciidoctor::INTRINSICS['lsquo'], Asciidoctor::INTRINSICS['rsquo']],
482
- :none => ['', '']
503
+ :double => ['&#8220;', '&#8221;'],
504
+ :single => ['&#8216;', '&#8217;']
505
+ #:none => ['', '']
483
506
  }
484
507
 
508
+ def quote(text, type, role)
509
+ start_tag, end_tag = QUOTED_TAGS[type] || ['', '']
510
+ if role
511
+ "#{start_tag}<phrase role=\"#{role}\">#{text}</phrase>#{end_tag}"
512
+ else
513
+ "#{start_tag}#{text}#{end_tag}"
514
+ end
515
+ end
516
+
485
517
  def template
518
+ # very hot piece of code, optimized for speed
486
519
  @template ||= @eruby.new <<-EOF
487
- <%#encoding:UTF-8%><% tags = template.class::QUOTED_TAGS[@type] %><%= tags.first %><%
488
- if attr? :role %><phrase#{role}><%
489
- end %><%= @text %><%
490
- if attr? :role %></phrase><%
491
- end %><%= tags.last %>
520
+ <%#encoding:UTF-8%><%= template.quote(@text, @type, attr('role')) %>
492
521
  EOF
493
522
  end
494
523
  end
495
524
 
496
- class InlineAnchorTemplate < ::Asciidoctor::BaseTemplate
525
+ class InlineAnchorTemplate < BaseTemplate
526
+ def anchor(target, text, type)
527
+ case type
528
+ when :ref
529
+ %(<anchor id="#{target}" xreflabel="#{text}"/>)
530
+ when :xref
531
+ text.nil? ? %(<xref linkend="#{target}"/>) : %(<link linkend="#{target}">#{text}</link>)
532
+ when :link
533
+ %(<ulink url="#{target}">#{text}</ulink>)
534
+ when :bibref
535
+ %(<anchor id="#{target}" xreflabel="[#{target}]"/>[#{target}])
536
+ end
537
+ end
538
+
497
539
  def template
498
- @template ||= @eruby.new <<-EOF
499
- <%#encoding:UTF-8%><% if @type == :xref
500
- %><%
501
- if @text.nil?
502
- %><xref linkend="<%= @target %>"/><%
503
- else
504
- %><link linkend="<%= @target %>"><%= @text %></link><%
505
- end %><%
506
- elsif @type == :ref
507
- %><anchor id="<%= @target %>" xreflabel="<%= @text %>"/><%
508
- elsif @type == :bibref
509
- %><anchor id="<%= @target %>" xreflabel="[<%= @target %>]"/>[<%= @target %>]<%
510
- else
511
- %><ulink url="<%= @target %>"><%= @text %></ulink><%
512
- end %>
513
- EOF
540
+ # hot piece of code, optimized for speed
541
+ @template ||= @eruby.new <<-EOS
542
+ <%#encoding:UTF-8%><%= template.anchor(@target, @text, @type) %>
543
+ EOS
514
544
  end
515
545
  end
516
546
 
517
- class InlineImageTemplate < ::Asciidoctor::BaseTemplate
547
+ class InlineImageTemplate < BaseTemplate
518
548
  def template
519
549
  @template ||= @eruby.new <<-EOF
520
550
  <%#encoding:UTF-8%><inlinemediaobject>
@@ -527,11 +557,11 @@ class InlineImageTemplate < ::Asciidoctor::BaseTemplate
527
557
  end
528
558
  end
529
559
 
530
- class InlineFootnoteTemplate < ::Asciidoctor::BaseTemplate
560
+ class InlineFootnoteTemplate < BaseTemplate
531
561
  def template
532
562
  @template ||= @eruby.new <<-EOS
533
563
  <%#encoding:UTF-8%><%
534
- if type == :xref
564
+ if @type == :xref
535
565
  %><footnoteref linkend="<%= @target %>"/><%
536
566
  else
537
567
  %><footnote#{id}><simpara><%= @text %></simpara></footnote><%
@@ -540,7 +570,7 @@ end %>
540
570
  end
541
571
  end
542
572
 
543
- class InlineCalloutTemplate < ::Asciidoctor::BaseTemplate
573
+ class InlineCalloutTemplate < BaseTemplate
544
574
  def template
545
575
  @template ||= @eruby.new <<-EOF
546
576
  <%#encoding:UTF-8%><co#{id}/>
@@ -548,10 +578,10 @@ class InlineCalloutTemplate < ::Asciidoctor::BaseTemplate
548
578
  end
549
579
  end
550
580
 
551
- class InlineIndextermTemplate < ::Asciidoctor::BaseTemplate
581
+ class InlineIndextermTemplate < BaseTemplate
552
582
  def template
553
583
  @template ||= @eruby.new <<-EOS
554
- <%#encoding:UTF-8%><% if type == :visible %><indexterm><primary><%= @text %></primary></indexterm><%= @text %><%
584
+ <%#encoding:UTF-8%><% if @type == :visible %><indexterm><primary><%= @text %></primary></indexterm><%= @text %><%
555
585
  else %><% terms = (attr :terms); numterms = terms.size %><%
556
586
  if numterms > 2 %><indexterm>
557
587
  <primary><%= terms[0] %></primary><secondary><%= terms[1] %></secondary><tertiary><%= terms[2] %></tertiary>
@@ -566,4 +596,6 @@ if numterms > 1 %><indexterm>
566
596
  EOS
567
597
  end
568
598
  end
569
- end
599
+
600
+ end # module DocBook45
601
+ end # module Asciidoctor