asciidoctor 0.1.1 → 0.1.2
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 +7 -0
- data/Gemfile +1 -1
- data/LICENSE +2 -2
- data/README.adoc +461 -0
- data/asciidoctor.gemspec +27 -16
- data/compat/asciidoc.conf +139 -0
- data/lib/asciidoctor.rb +212 -69
- data/lib/asciidoctor/abstract_block.rb +41 -0
- data/lib/asciidoctor/abstract_node.rb +128 -81
- data/lib/asciidoctor/attribute_list.rb +5 -2
- data/lib/asciidoctor/backends/base_template.rb +16 -4
- data/lib/asciidoctor/backends/docbook45.rb +112 -42
- data/lib/asciidoctor/backends/html5.rb +206 -90
- data/lib/asciidoctor/block.rb +5 -5
- data/lib/asciidoctor/cli/invoker.rb +38 -34
- data/lib/asciidoctor/cli/options.rb +3 -3
- data/lib/asciidoctor/document.rb +115 -13
- data/lib/asciidoctor/helpers.rb +16 -0
- data/lib/asciidoctor/lexer.rb +486 -359
- data/lib/asciidoctor/path_resolver.rb +360 -0
- data/lib/asciidoctor/reader.rb +122 -23
- data/lib/asciidoctor/renderer.rb +1 -33
- data/lib/asciidoctor/section.rb +1 -1
- data/lib/asciidoctor/substituters.rb +103 -19
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +6 -6
- data/man/asciidoctor.ad +5 -3
- data/stylesheets/asciidoctor.css +274 -0
- data/test/attributes_test.rb +133 -10
- data/test/blocks_test.rb +302 -17
- data/test/document_test.rb +269 -6
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +4 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +2 -0
- data/test/fixtures/include-file.asciidoc +22 -1
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/invoker_test.rb +38 -6
- data/test/lexer_test.rb +64 -21
- data/test/links_test.rb +4 -0
- data/test/lists_test.rb +251 -12
- data/test/paragraphs_test.rb +225 -30
- data/test/paths_test.rb +174 -0
- data/test/reader_test.rb +89 -2
- data/test/sections_test.rb +518 -16
- data/test/substitutions_test.rb +121 -10
- data/test/tables_test.rb +53 -13
- data/test/test_helper.rb +2 -2
- data/test/text_test.rb +5 -5
- metadata +46 -50
- data/README.asciidoc +0 -296
- data/lib/asciidoctor/errors.rb +0 -5
@@ -189,6 +189,47 @@ class AbstractBlock < AbstractNode
|
|
189
189
|
}
|
190
190
|
end
|
191
191
|
|
192
|
+
# Public: Generate a caption and assign it to this block if one
|
193
|
+
# is not already assigned.
|
194
|
+
#
|
195
|
+
# If the block has a title and a caption prefix is available
|
196
|
+
# for this block, then build a caption from this information,
|
197
|
+
# assign it a number and store it to the caption attribute on
|
198
|
+
# the block.
|
199
|
+
#
|
200
|
+
# If an explicit caption has been specified on this block, then
|
201
|
+
# do nothing.
|
202
|
+
#
|
203
|
+
# key - The prefix of the caption and counter attribute names.
|
204
|
+
# If not provided, the name of the context for this block
|
205
|
+
# is used. (default: nil).
|
206
|
+
#
|
207
|
+
# returns nothing
|
208
|
+
def assign_caption(caption = nil, key = nil)
|
209
|
+
unless title? || @caption.nil?
|
210
|
+
return nil
|
211
|
+
end
|
212
|
+
|
213
|
+
if caption.nil?
|
214
|
+
if @document.attr?('caption')
|
215
|
+
@caption = @document.attr('caption')
|
216
|
+
elsif title?
|
217
|
+
key ||= @context.to_s
|
218
|
+
caption_key = "#{key}-caption"
|
219
|
+
if @document.attributes.has_key?(caption_key)
|
220
|
+
caption_title = @document.attributes["#{key}-caption"]
|
221
|
+
caption_num = @document.counter_increment("#{key}-number", self)
|
222
|
+
@caption = @attributes['caption'] = "#{caption_title} #{caption_num}. "
|
223
|
+
end
|
224
|
+
else
|
225
|
+
@caption = caption
|
226
|
+
end
|
227
|
+
else
|
228
|
+
@caption = caption
|
229
|
+
end
|
230
|
+
nil
|
231
|
+
end
|
232
|
+
|
192
233
|
# Internal: Assign the next index (0-based) to this section
|
193
234
|
#
|
194
235
|
# Assign the next index of this section within the parent
|
@@ -94,6 +94,27 @@ class AbstractNode
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
+
# Public: Assign the value to the specified key in this
|
98
|
+
# block's attributes hash.
|
99
|
+
#
|
100
|
+
# key - The attribute key (or name)
|
101
|
+
# val - The value to assign to the key
|
102
|
+
#
|
103
|
+
# returns a flag indicating whether the assignment was performed
|
104
|
+
def set_attr(key, val, overwrite = nil)
|
105
|
+
if overwrite.nil?
|
106
|
+
@attributes[key] = val
|
107
|
+
true
|
108
|
+
else
|
109
|
+
if overwrite || @attributes.has_key?(key)
|
110
|
+
@attributes[key] = val
|
111
|
+
true
|
112
|
+
else
|
113
|
+
false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
97
118
|
# Public: Get the execution context of this object (via Kernel#binding).
|
98
119
|
#
|
99
120
|
# This method is used to set the 'self' reference as well as local variables
|
@@ -156,11 +177,35 @@ class AbstractNode
|
|
156
177
|
if attr? 'icon'
|
157
178
|
image_uri(attr('icon'), nil)
|
158
179
|
else
|
159
|
-
image_uri(name
|
180
|
+
image_uri("#{name}.#{@document.attr('icontype', 'png')}", 'iconsdir')
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Public: Construct a URI reference to the target media.
|
185
|
+
#
|
186
|
+
# If the target media is a URI reference, then leave it untouched.
|
187
|
+
#
|
188
|
+
# The target media is resolved relative to the directory retrieved from the
|
189
|
+
# specified attribute key, if provided.
|
190
|
+
#
|
191
|
+
# The return value can be safely used in a media tag (img, audio, video).
|
192
|
+
#
|
193
|
+
# target - A String reference to the target media
|
194
|
+
# asset_dir_key - The String attribute key used to lookup the directory where
|
195
|
+
# the media is located (default: 'imagesdir')
|
196
|
+
#
|
197
|
+
# Returns A String reference for the target media
|
198
|
+
def media_uri(target, asset_dir_key = 'imagesdir')
|
199
|
+
if target.include?(':') && target.match(Asciidoctor::REGEXP[:uri_sniff])
|
200
|
+
target
|
201
|
+
elsif asset_dir_key && attr?(asset_dir_key)
|
202
|
+
normalize_web_path(target, @document.attr(asset_dir_key))
|
203
|
+
else
|
204
|
+
normalize_web_path(target)
|
160
205
|
end
|
161
206
|
end
|
162
207
|
|
163
|
-
# Public: Construct a reference or data URI to the target image.
|
208
|
+
# Public: Construct a URI reference or data URI to the target image.
|
164
209
|
#
|
165
210
|
# If the target image is a URI reference, then leave it untouched.
|
166
211
|
#
|
@@ -185,9 +230,9 @@ class AbstractNode
|
|
185
230
|
elsif @document.safe < Asciidoctor::SafeMode::SECURE && @document.attr?('data-uri')
|
186
231
|
generate_data_uri(target_image, asset_dir_key)
|
187
232
|
elsif asset_dir_key && attr?(asset_dir_key)
|
188
|
-
|
233
|
+
normalize_web_path(target_image, @document.attr(asset_dir_key))
|
189
234
|
else
|
190
|
-
target_image
|
235
|
+
normalize_web_path(target_image)
|
191
236
|
end
|
192
237
|
end
|
193
238
|
|
@@ -208,9 +253,17 @@ class AbstractNode
|
|
208
253
|
|
209
254
|
mimetype = 'image/' + File.extname(target_image)[1..-1]
|
210
255
|
if asset_dir_key
|
211
|
-
|
256
|
+
#asset_dir_path = normalize_system_path(@document.attr(asset_dir_key), nil, nil, :target_name => asset_dir_key)
|
257
|
+
#image_path = normalize_system_path(target_image, asset_dir_path, nil, :target_name => 'image')
|
258
|
+
image_path = normalize_system_path(target_image, @document.attr(asset_dir_key), nil, :target_name => 'image')
|
212
259
|
else
|
213
|
-
image_path =
|
260
|
+
image_path = normalize_system_path(target_image)
|
261
|
+
end
|
262
|
+
|
263
|
+
if !File.readable? image_path
|
264
|
+
puts "asciidoctor: WARNING: image to embed not found or not readable: #{image_path}"
|
265
|
+
return "data:#{mimetype}:base64,"
|
266
|
+
#return 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='
|
214
267
|
end
|
215
268
|
|
216
269
|
bindata = nil
|
@@ -219,88 +272,82 @@ class AbstractNode
|
|
219
272
|
else
|
220
273
|
bindata = File.open(image_path, 'rb') {|file| file.read }
|
221
274
|
end
|
222
|
-
|
275
|
+
"data:#{mimetype};base64,#{Base64.encode64(bindata).delete("\n")}"
|
223
276
|
end
|
224
277
|
|
225
|
-
# Public:
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
# Examples
|
239
|
-
#
|
240
|
-
# # given these fixtures
|
241
|
-
# document.base_dir
|
242
|
-
# # => "/path/to/chroot"
|
243
|
-
# document.safe >= Asciidoctor::SafeMode::SAFE
|
244
|
-
# # => true
|
245
|
-
#
|
246
|
-
# # then
|
247
|
-
# normalize_asset_path('images')
|
248
|
-
# # => "/path/to/chroot/images"
|
249
|
-
# normalize_asset_path('/etc/images')
|
250
|
-
# # => "/path/to/chroot/images"
|
251
|
-
# normalize_asset_path('../images')
|
252
|
-
# # => "/path/to/chroot/images"
|
253
|
-
#
|
254
|
-
# # given these fixtures
|
255
|
-
# document.base_dir
|
256
|
-
# # => "/path/to/chroot"
|
257
|
-
# document.safe >= Asciidoctor::SafeMode::SAFE
|
258
|
-
# # => false
|
259
|
-
#
|
260
|
-
# # then
|
261
|
-
# normalize_asset_path('images')
|
262
|
-
# # => "/path/to/chroot/images"
|
263
|
-
# normalize_asset_path('/etc/images')
|
264
|
-
# # => "/etc/images"
|
265
|
-
# normalize_asset_path('../images')
|
266
|
-
# # => "/path/to/images"
|
267
|
-
#
|
268
|
-
# Returns The normalized asset file or directory as a String path
|
269
|
-
#--
|
270
|
-
# TODO this method is missing a coordinate; it should be able to resolve
|
271
|
-
# both the directory reference and the path to an asset in it; callers
|
272
|
-
# of this method are still doing a File.join to finish the task
|
273
|
-
def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true)
|
274
|
-
# TODO we may use pathname enough to make it a top-level require
|
275
|
-
Helpers.require_library 'pathname'
|
276
|
-
|
277
|
-
input_path = @document.base_dir
|
278
|
-
asset_path = Pathname.new(asset_ref)
|
279
|
-
|
280
|
-
if asset_path.relative?
|
281
|
-
asset_path = File.expand_path(File.join(input_path, asset_ref))
|
278
|
+
# Public: Read the contents of the file at the specified path.
|
279
|
+
# This method assumes that the path is safe to read. It checks
|
280
|
+
# that the file is readable before attempting to read it.
|
281
|
+
#
|
282
|
+
# path - the String path from which to read the contents
|
283
|
+
# warn_on_failure - a Boolean that controls whether a warning is issued if
|
284
|
+
# the file cannot be read
|
285
|
+
#
|
286
|
+
# returns the contents of the file at the specified path, or nil
|
287
|
+
# if the file does not exist.
|
288
|
+
def read_asset(path, warn_on_failure = false)
|
289
|
+
if File.readable? path
|
290
|
+
File.read path
|
282
291
|
else
|
283
|
-
|
292
|
+
puts "asciidoctor: WARNING: file does not exist or cannot be read: #{path}" if warn_on_failure
|
293
|
+
nil
|
284
294
|
end
|
295
|
+
end
|
285
296
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
297
|
+
# Public: Normalize the web page using the PathResolver.
|
298
|
+
#
|
299
|
+
# See PathResolver::web_path(target, start) for details.
|
300
|
+
#
|
301
|
+
# target - the String target path
|
302
|
+
# start - the String start (i.e, parent) path (optional, default: nil)
|
303
|
+
#
|
304
|
+
# returns the resolved String path
|
305
|
+
def normalize_web_path(target, start = nil)
|
306
|
+
PathResolver.new.web_path(target, start)
|
307
|
+
end
|
308
|
+
|
309
|
+
# Public: Resolve and normalize a secure path from the target and start paths
|
310
|
+
# using the PathResolver.
|
311
|
+
#
|
312
|
+
# See PathResolver::system_path(target, start, jail, opts) for details.
|
313
|
+
#
|
314
|
+
# The most important functionality in this method is to prevent resolving a
|
315
|
+
# path outside of the jail (which defaults to the directory of the source
|
316
|
+
# file, stored in the base_dir instance variable on Document) if the document
|
317
|
+
# safe level is set to SafeMode::SAFE or greater (a condition which is true
|
318
|
+
# by default).
|
319
|
+
#
|
320
|
+
# target - the String target path
|
321
|
+
# start - the String start (i.e., parent) path
|
322
|
+
# jail - the String jail path to confine the resolved path
|
323
|
+
# opts - an optional Hash of options to control processing (default: {}):
|
324
|
+
# * :recover is used to control whether the processor should auto-recover
|
325
|
+
# when an illegal path is encountered
|
326
|
+
# * :target_name is used in messages to refer to the path being resolved
|
327
|
+
#
|
328
|
+
# raises a SecurityError if a jail is specified and the resolved path is
|
329
|
+
# outside the jail.
|
330
|
+
#
|
331
|
+
# returns a String path resolved from the start and target paths, with any
|
332
|
+
# parent references resolved and self references removed. If a jail is provided,
|
333
|
+
# this path will be guaranteed to be contained within the jail.
|
334
|
+
def normalize_system_path(target, start = nil, jail = nil, opts = {})
|
335
|
+
if start.nil?
|
336
|
+
start = @document.base_dir
|
301
337
|
end
|
338
|
+
if jail.nil? && @document.safe >= SafeMode::SAFE
|
339
|
+
jail = @document.base_dir
|
340
|
+
end
|
341
|
+
PathResolver.new.system_path(target, start, jail, opts)
|
342
|
+
end
|
302
343
|
|
303
|
-
|
344
|
+
# Public: Normalize the asset file or directory to a concrete and rinsed path
|
345
|
+
#
|
346
|
+
# Delegates to normalize_system_path, with the start path set to the value of
|
347
|
+
# the base_dir instance variable on the Document object.
|
348
|
+
def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true)
|
349
|
+
normalize_system_path(asset_ref, @document.base_dir, nil,
|
350
|
+
:target_name => asset_name, :recover => autocorrect)
|
304
351
|
end
|
305
352
|
|
306
353
|
end
|
@@ -84,6 +84,7 @@ class AttributeList
|
|
84
84
|
|
85
85
|
def self.rekey(attributes, pos_attrs)
|
86
86
|
pos_attrs.each_with_index do |key, index|
|
87
|
+
next if key.nil?
|
87
88
|
pos = index + 1
|
88
89
|
unless (val = attributes[pos]).nil?
|
89
90
|
attributes[key] = val
|
@@ -166,9 +167,11 @@ class AttributeList
|
|
166
167
|
else
|
167
168
|
resolved_value = value
|
168
169
|
# example: options="opt1,opt2,opt3"
|
169
|
-
|
170
|
+
# opts is an alias for options
|
171
|
+
if name == 'options' || name == 'opts'
|
172
|
+
name = 'options'
|
170
173
|
resolved_value.split(CSV_SPLIT_PATTERN).each do |o|
|
171
|
-
@attributes[o + '-option'] =
|
174
|
+
@attributes[o + '-option'] = ''
|
172
175
|
end
|
173
176
|
elsif single_quoted_value && !@block.nil?
|
174
177
|
resolved_value = @block.apply_normal_subs(value)
|
@@ -40,15 +40,17 @@ class BaseTemplate
|
|
40
40
|
# locals - A Hash of additional variables. Not currently in use.
|
41
41
|
def render(node = Object.new, locals = {})
|
42
42
|
tmpl = template
|
43
|
-
|
43
|
+
case tmpl
|
44
|
+
when :invoke_result
|
45
|
+
return result(node)
|
46
|
+
when :content
|
44
47
|
result = node.content
|
45
|
-
#elsif tmpl.is_a?(String)
|
46
|
-
# result = tmpl
|
47
48
|
else
|
48
49
|
result = tmpl.result(node.get_binding(self))
|
49
50
|
end
|
50
51
|
|
51
|
-
if (@view == 'document' || @view == 'embedded') &&
|
52
|
+
if (@view == 'document' || @view == 'embedded') &&
|
53
|
+
node.renderer.compact && !node.document.nested?
|
52
54
|
compact result
|
53
55
|
else
|
54
56
|
result
|
@@ -105,4 +107,14 @@ class BaseTemplate
|
|
105
107
|
attribute('id', '@id')
|
106
108
|
end
|
107
109
|
end
|
110
|
+
|
111
|
+
module EmptyTemplate
|
112
|
+
def result(node)
|
113
|
+
''
|
114
|
+
end
|
115
|
+
|
116
|
+
def template
|
117
|
+
:invoke_result
|
118
|
+
end
|
119
|
+
end
|
108
120
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module Asciidoctor
|
2
2
|
class BaseTemplate
|
3
|
-
def tag(name, key)
|
3
|
+
def tag(name, key, dynamic = false)
|
4
4
|
type = key.is_a?(Symbol) ? :attr : :var
|
5
5
|
key = key.to_s
|
6
6
|
if type == :attr
|
7
|
+
key_str = dynamic ? %("#{key}") : "'#{key}'"
|
7
8
|
# example: <% if attr? 'foo' %><bar><%= attr 'foo' %></bar><% end %>
|
8
|
-
%(<% if attr?
|
9
|
+
%(<% if attr? #{key_str} %><#{name}><%= attr #{key_str} %></#{name}><% end %>)
|
9
10
|
else
|
10
11
|
# example: <% unless foo.to_s.empty? %><bar><%= foo %></bar><% end %>
|
11
12
|
%(<% unless #{key}.to_s.empty? %><#{name}><%= #{key} %></#{name}><% end %>)
|
@@ -31,10 +32,20 @@ module Asciidoctor
|
|
31
32
|
|
32
33
|
module DocBook45
|
33
34
|
class DocumentTemplate < BaseTemplate
|
35
|
+
def title_tags(str)
|
36
|
+
if str.include?(': ')
|
37
|
+
title, _, subtitle = str.rpartition(': ')
|
38
|
+
%(<title>#{title}</title>
|
39
|
+
<subtitle>#{subtitle}</subtitle>)
|
40
|
+
else
|
41
|
+
%(<title>#{str}</title>)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
34
45
|
def docinfo
|
35
46
|
<<-EOF
|
36
47
|
<% if has_header? && !notitle %>
|
37
|
-
|
48
|
+
<%= template.title_tags(@header.title) %>
|
38
49
|
<% end %>
|
39
50
|
<% if attr? :revdate %>
|
40
51
|
<date><%= attr :revdate %></date>
|
@@ -43,6 +54,7 @@ class DocumentTemplate < BaseTemplate
|
|
43
54
|
<% end %>
|
44
55
|
<% if has_header? %>
|
45
56
|
<% if attr? :author %>
|
57
|
+
<% if attr? :authorcount, 1 %>
|
46
58
|
<author>
|
47
59
|
#{tag 'firstname', :firstname}
|
48
60
|
#{tag 'othername', :middlename}
|
@@ -50,15 +62,31 @@ class DocumentTemplate < BaseTemplate
|
|
50
62
|
#{tag 'email', :email}
|
51
63
|
</author>
|
52
64
|
#{tag 'authorinitials', :authorinitials}
|
65
|
+
<% else %>
|
66
|
+
<authorgroup>
|
67
|
+
<% (1..(attr(:authorcount))).each do |idx| %>
|
68
|
+
<author>
|
69
|
+
#{tag 'firstname', :"firstname_\#{idx}", true}
|
70
|
+
#{tag 'othername', :"middlename_\#{idx}", true}
|
71
|
+
#{tag 'surname', :"lastname_\#{idx}", true}
|
72
|
+
#{tag 'email', :"email_\#{idx}", true}
|
73
|
+
</author>
|
74
|
+
<% end %>
|
75
|
+
</authorgroup>
|
76
|
+
<% end %>
|
53
77
|
<% end %>
|
54
78
|
<% if (attr? :revnumber) || (attr? :revremark) %>
|
55
79
|
<revhistory>
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
80
|
+
<revision>
|
81
|
+
#{tag 'revnumber', :revnumber}
|
82
|
+
#{tag 'date', :revdate}
|
83
|
+
#{tag 'authorinitials', :authorinitials}
|
84
|
+
#{tag 'revremark', :revremark}
|
85
|
+
</revision>
|
60
86
|
</revhistory>
|
61
87
|
<% end %>
|
88
|
+
<%= docinfo %>
|
89
|
+
#{tag 'orgname', :orgname}
|
62
90
|
<% end %>
|
63
91
|
EOF
|
64
92
|
end
|
@@ -94,12 +122,22 @@ class EmbeddedTemplate < BaseTemplate
|
|
94
122
|
end
|
95
123
|
end
|
96
124
|
|
125
|
+
class BlockTocTemplate < BaseTemplate
|
126
|
+
def result(node)
|
127
|
+
''
|
128
|
+
end
|
129
|
+
|
130
|
+
def template
|
131
|
+
:invoke_result
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
97
135
|
class BlockPreambleTemplate < BaseTemplate
|
98
136
|
def template
|
99
137
|
@template ||= @eruby.new <<-EOF
|
100
138
|
<%#encoding:UTF-8%><% if @document.doctype == 'book' %>
|
101
139
|
<preface#{common_attrs_erb}>
|
102
|
-
|
140
|
+
#{title_tag false}
|
103
141
|
<%= content %>
|
104
142
|
</preface>
|
105
143
|
<% else %>
|
@@ -110,11 +148,11 @@ class BlockPreambleTemplate < BaseTemplate
|
|
110
148
|
end
|
111
149
|
|
112
150
|
class SectionTemplate < BaseTemplate
|
113
|
-
def
|
151
|
+
def result(sec)
|
114
152
|
if sec.special
|
115
153
|
tag = sec.level <= 1 ? sec.sectname : 'section'
|
116
154
|
else
|
117
|
-
tag = sec.document.doctype == 'book' && sec.level <= 1 ? 'chapter' : 'section'
|
155
|
+
tag = sec.document.doctype == 'book' && sec.level <= 1 ? (sec.level == 0 ? 'part' : 'chapter') : 'section'
|
118
156
|
end
|
119
157
|
%(<#{tag}#{common_attrs(sec.id, (sec.attr 'role'), (sec.attr 'reftext'))}>
|
120
158
|
#{sec.title? ? "<title>#{sec.title}</title>" : nil}
|
@@ -123,10 +161,7 @@ class SectionTemplate < BaseTemplate
|
|
123
161
|
end
|
124
162
|
|
125
163
|
def template
|
126
|
-
|
127
|
-
@template ||= @eruby.new <<-EOF
|
128
|
-
<%#encoding:UTF-8%><%= template.section(self) %>
|
129
|
-
EOF
|
164
|
+
:invoke_result
|
130
165
|
end
|
131
166
|
end
|
132
167
|
|
@@ -138,25 +173,38 @@ class BlockFloatingTitleTemplate < BaseTemplate
|
|
138
173
|
end
|
139
174
|
end
|
140
175
|
|
141
|
-
|
142
176
|
class BlockParagraphTemplate < BaseTemplate
|
143
|
-
|
144
|
-
|
145
|
-
if
|
146
|
-
|
177
|
+
def paragraph(id, style, role, reftext, title, content)
|
178
|
+
# FIXME temporary hack until I can generalize this feature
|
179
|
+
if style == 'partintro'
|
180
|
+
if title
|
181
|
+
%(<partintro#{common_attrs(id, role, reftext)}>
|
182
|
+
<title>#{title}</title>
|
183
|
+
<simpara>#{content}</simpara>
|
184
|
+
</partintro>)
|
185
|
+
else
|
186
|
+
%(<partintro#{common_attrs(id, role, reftext)}>
|
187
|
+
<simpara>#{content}</simpara>
|
188
|
+
</partintro>)
|
189
|
+
end
|
190
|
+
else
|
191
|
+
if title
|
192
|
+
%(<formalpara#{common_attrs(id, role, reftext)}>
|
147
193
|
<title>#{title}</title>
|
148
194
|
<para>#{content}</para>
|
149
195
|
</formalpara>)
|
150
|
-
|
151
|
-
|
196
|
+
else
|
197
|
+
%(<simpara#{common_attrs(id, role, reftext)}>#{content}</simpara>)
|
198
|
+
end
|
152
199
|
end
|
153
200
|
end
|
154
201
|
|
202
|
+
def result(node)
|
203
|
+
paragraph(node.id, node.attr('style'), node.attr('role'), node.attr('reftext'), (node.title? ? node.title : nil), node.content)
|
204
|
+
end
|
205
|
+
|
155
206
|
def template
|
156
|
-
|
157
|
-
@template ||= @eruby.new <<-EOF
|
158
|
-
<%#encoding:UTF-8%><%= template.paragraph(@id, (attr 'role'), (attr 'reftext'), title? ? title : nil, content) %>
|
159
|
-
EOF
|
207
|
+
:invoke_result
|
160
208
|
end
|
161
209
|
end
|
162
210
|
|
@@ -254,7 +302,8 @@ class BlockDlistTemplate < BaseTemplate
|
|
254
302
|
'qanda' => {
|
255
303
|
:list => 'qandaset',
|
256
304
|
:entry => 'qandaentry',
|
257
|
-
:
|
305
|
+
:label => 'question',
|
306
|
+
:term => 'simpara',
|
258
307
|
:item => 'answer'
|
259
308
|
},
|
260
309
|
'glossary' => {
|
@@ -272,9 +321,17 @@ class BlockDlistTemplate < BaseTemplate
|
|
272
321
|
#{title_tag}
|
273
322
|
<% content.each do |dt, dd| %>
|
274
323
|
<<%= tags[:entry] %>>
|
324
|
+
<% if tags.has_key?(:label) %>
|
325
|
+
<<%= tags[:label] %>>
|
326
|
+
<<%= tags[:term] %>>
|
327
|
+
<%= dt.text %>
|
328
|
+
</<%= tags[:term] %>>
|
329
|
+
</<%= tags[:label] %>>
|
330
|
+
<% else %>
|
275
331
|
<<%= tags[:term] %>>
|
276
332
|
<%= dt.text %>
|
277
333
|
</<%= tags[:term] %>>
|
334
|
+
<% end %>
|
278
335
|
<% unless dd.nil? %>
|
279
336
|
<<%= tags[:item] %>>
|
280
337
|
<% if dd.text? %>
|
@@ -469,6 +526,14 @@ class BlockImageTemplate < BaseTemplate
|
|
469
526
|
end
|
470
527
|
end
|
471
528
|
|
529
|
+
class BlockAudioTemplate < BaseTemplate
|
530
|
+
include EmptyTemplate
|
531
|
+
end
|
532
|
+
|
533
|
+
class BlockVideoTemplate < BaseTemplate
|
534
|
+
include EmptyTemplate
|
535
|
+
end
|
536
|
+
|
472
537
|
class BlockRulerTemplate < BaseTemplate
|
473
538
|
def template
|
474
539
|
@template ||= @eruby.new <<-EOF
|
@@ -494,6 +559,8 @@ class InlineBreakTemplate < BaseTemplate
|
|
494
559
|
end
|
495
560
|
|
496
561
|
class InlineQuotedTemplate < BaseTemplate
|
562
|
+
NO_TAGS = ['', '']
|
563
|
+
|
497
564
|
QUOTED_TAGS = {
|
498
565
|
:emphasis => ['<emphasis>', '</emphasis>'],
|
499
566
|
:strong => ['<emphasis role="strong">', '</emphasis>'],
|
@@ -502,11 +569,10 @@ class InlineQuotedTemplate < BaseTemplate
|
|
502
569
|
:subscript => ['<subscript>', '</subscript>'],
|
503
570
|
:double => ['“', '”'],
|
504
571
|
:single => ['‘', '’']
|
505
|
-
#:none => ['', '']
|
506
572
|
}
|
507
573
|
|
508
|
-
def
|
509
|
-
start_tag, end_tag = QUOTED_TAGS[type] ||
|
574
|
+
def quote_text(text, type, role)
|
575
|
+
start_tag, end_tag = QUOTED_TAGS[type] || NO_TAGS
|
510
576
|
if role
|
511
577
|
"#{start_tag}<phrase role=\"#{role}\">#{text}</phrase>#{end_tag}"
|
512
578
|
else
|
@@ -514,11 +580,12 @@ class InlineQuotedTemplate < BaseTemplate
|
|
514
580
|
end
|
515
581
|
end
|
516
582
|
|
583
|
+
def result(node)
|
584
|
+
quote_text(node.text, node.type, node.attr('role'))
|
585
|
+
end
|
586
|
+
|
517
587
|
def template
|
518
|
-
|
519
|
-
@template ||= @eruby.new <<-EOF
|
520
|
-
<%#encoding:UTF-8%><%= template.quote(@text, @type, attr('role')) %>
|
521
|
-
EOF
|
588
|
+
:invoke_result
|
522
589
|
end
|
523
590
|
end
|
524
591
|
|
@@ -536,11 +603,12 @@ class InlineAnchorTemplate < BaseTemplate
|
|
536
603
|
end
|
537
604
|
end
|
538
605
|
|
606
|
+
def result(node)
|
607
|
+
anchor(node.target, node.text, node.type)
|
608
|
+
end
|
609
|
+
|
539
610
|
def template
|
540
|
-
|
541
|
-
@template ||= @eruby.new <<-EOS
|
542
|
-
<%#encoding:UTF-8%><%= template.anchor(@target, @text, @type) %>
|
543
|
-
EOS
|
611
|
+
:invoke_result
|
544
612
|
end
|
545
613
|
end
|
546
614
|
|
@@ -571,10 +639,12 @@ end %>
|
|
571
639
|
end
|
572
640
|
|
573
641
|
class InlineCalloutTemplate < BaseTemplate
|
642
|
+
def result(node)
|
643
|
+
%(<co id="#{node.id}"/>)
|
644
|
+
end
|
645
|
+
|
574
646
|
def template
|
575
|
-
|
576
|
-
<%#encoding:UTF-8%><co#{id}/>
|
577
|
-
EOF
|
647
|
+
:invoke_result
|
578
648
|
end
|
579
649
|
end
|
580
650
|
|
@@ -588,10 +658,10 @@ if numterms > 2 %><indexterm>
|
|
588
658
|
</indexterm>
|
589
659
|
<% end %><%
|
590
660
|
if numterms > 1 %><indexterm>
|
591
|
-
<primary><%= terms[
|
661
|
+
<primary><%= terms[-2] %></primary><secondary><%= terms[-1] %></secondary>
|
592
662
|
</indexterm>
|
593
663
|
<% end %><indexterm>
|
594
|
-
<primary><%= terms[
|
664
|
+
<primary><%= terms[-1] %></primary>
|
595
665
|
</indexterm><% end %>
|
596
666
|
EOS
|
597
667
|
end
|