asciidoctor 1.5.8 → 2.0.0.rc.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +162 -17
- data/LICENSE +1 -1
- data/README-de.adoc +12 -13
- data/README-fr.adoc +11 -12
- data/README-jp.adoc +11 -12
- data/README-zh_CN.adoc +12 -13
- data/README.adoc +6 -7
- data/asciidoctor.gemspec +19 -24
- data/bin/asciidoctor +5 -4
- data/data/reference/syntax.adoc +283 -0
- data/data/stylesheets/asciidoctor-default.css +56 -52
- data/data/stylesheets/coderay-asciidoctor.css +7 -9
- data/lib/asciidoctor.rb +171 -232
- data/lib/asciidoctor/abstract_block.rb +96 -105
- data/lib/asciidoctor/abstract_node.rb +118 -139
- data/lib/asciidoctor/attribute_list.rb +10 -14
- data/lib/asciidoctor/block.rb +20 -19
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/cli/invoker.rb +14 -21
- data/lib/asciidoctor/cli/options.rb +64 -54
- data/lib/asciidoctor/converter.rb +357 -185
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +604 -640
- data/lib/asciidoctor/converter/html5.rb +949 -963
- data/lib/asciidoctor/converter/manpage.rb +569 -548
- data/lib/asciidoctor/converter/template.rb +231 -272
- data/lib/asciidoctor/core_ext.rb +5 -18
- data/lib/asciidoctor/core_ext/float/truncate.rb +19 -0
- data/lib/asciidoctor/core_ext/match_data/names.rb +7 -0
- data/lib/asciidoctor/core_ext/nil_or_empty.rb +1 -0
- data/lib/asciidoctor/core_ext/regexp/is_match.rb +4 -2
- data/lib/asciidoctor/document.rb +399 -377
- data/lib/asciidoctor/extensions.rb +72 -140
- data/lib/asciidoctor/helpers.rb +122 -83
- data/lib/asciidoctor/inline.rb +5 -1
- data/lib/asciidoctor/list.rb +13 -11
- data/lib/asciidoctor/logging.rb +17 -16
- data/lib/asciidoctor/parser.rb +390 -423
- data/lib/asciidoctor/path_resolver.rb +10 -5
- data/lib/asciidoctor/reader.rb +286 -263
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/section.rb +9 -8
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +364 -509
- data/lib/asciidoctor/syntax_highlighter.rb +238 -0
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +87 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +26 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +27 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +149 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +129 -0
- data/lib/asciidoctor/table.rb +73 -66
- data/lib/asciidoctor/timings.rb +4 -2
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/man/asciidoctor.1 +19 -15
- data/man/asciidoctor.adoc +14 -12
- metadata +69 -216
- data/CONTRIBUTING.adoc +0 -185
- data/Gemfile +0 -60
- data/Rakefile +0 -129
- data/bin/asciidoctor-safe +0 -15
- data/features/open_block.feature +0 -92
- data/features/pass_block.feature +0 -66
- data/features/step_definitions.rb +0 -49
- data/features/text_formatting.feature +0 -57
- data/features/xref.feature +0 -1039
- data/lib/asciidoctor/converter/base.rb +0 -59
- data/lib/asciidoctor/converter/docbook45.rb +0 -93
- data/lib/asciidoctor/converter/factory.rb +0 -226
- data/lib/asciidoctor/core_ext/1.8.7/base64/strict_encode64.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/concurrent/hash.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/hash/key.rb +0 -4
- data/lib/asciidoctor/core_ext/1.8.7/io/binread.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/io/write.rb +0 -5
- data/lib/asciidoctor/core_ext/1.8.7/string/chr.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/string/limit_bytesize.rb +0 -29
- data/lib/asciidoctor/core_ext/1.8.7/symbol/empty.rb +0 -6
- data/lib/asciidoctor/core_ext/1.8.7/symbol/length.rb +0 -6
- data/lib/asciidoctor/core_ext/string/limit_bytesize.rb +0 -10
- data/test/api_test.rb +0 -1240
- data/test/attribute_list_test.rb +0 -242
- data/test/attributes_test.rb +0 -1623
- data/test/blocks_test.rb +0 -3870
- data/test/converter_test.rb +0 -470
- data/test/document_test.rb +0 -1853
- data/test/extensions_test.rb +0 -1560
- data/test/fixtures/asciidoc_index.txt +0 -521
- data/test/fixtures/basic-docinfo-footer.html +0 -6
- data/test/fixtures/basic-docinfo-footer.xml +0 -8
- data/test/fixtures/basic-docinfo.html +0 -1
- data/test/fixtures/basic-docinfo.xml +0 -4
- data/test/fixtures/basic.asciidoc +0 -5
- data/test/fixtures/chapter-a.adoc +0 -3
- data/test/fixtures/child-include.adoc +0 -5
- data/test/fixtures/circle.svg +0 -9
- data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +0 -6
- data/test/fixtures/custom-backends/haml/docbook45/block_paragraph.xml.haml +0 -6
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- data/test/fixtures/custom-backends/haml/html5/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/slim/docbook45/block_paragraph.xml.slim +0 -6
- data/test/fixtures/custom-backends/slim/html5/block_paragraph.html.slim +0 -3
- data/test/fixtures/custom-backends/slim/html5/block_sidebar.html.slim +0 -5
- data/test/fixtures/custom-docinfodir/basic-docinfo.html +0 -1
- data/test/fixtures/custom-docinfodir/docinfo.html +0 -1
- data/test/fixtures/docinfo-footer.html +0 -1
- data/test/fixtures/docinfo-footer.xml +0 -9
- data/test/fixtures/docinfo.html +0 -1
- data/test/fixtures/docinfo.xml +0 -3
- data/test/fixtures/doctime-localtime.adoc +0 -2
- data/test/fixtures/dot.gif +0 -0
- data/test/fixtures/encoding.asciidoc +0 -13
- data/test/fixtures/file-with-missing-include.adoc +0 -1
- data/test/fixtures/grandchild-include.adoc +0 -3
- data/test/fixtures/hello-asciidoctor.pdf +0 -69
- data/test/fixtures/include-file.asciidoc +0 -24
- data/test/fixtures/include-file.jsx +0 -8
- data/test/fixtures/include-file.ml +0 -3
- data/test/fixtures/include-file.xml +0 -5
- data/test/fixtures/lists.adoc +0 -96
- data/test/fixtures/master.adoc +0 -5
- data/test/fixtures/mismatched-end-tag.adoc +0 -7
- data/test/fixtures/other-chapters.adoc +0 -11
- data/test/fixtures/outer-include.adoc +0 -5
- data/test/fixtures/parent-include-restricted.adoc +0 -5
- data/test/fixtures/parent-include.adoc +0 -5
- data/test/fixtures/sample.asciidoc +0 -30
- data/test/fixtures/section-a.adoc +0 -4
- data/test/fixtures/stylesheets/custom.css +0 -3
- data/test/fixtures/subdir/index.adoc +0 -3
- data/test/fixtures/subdir/inner-include.adoc +0 -3
- data/test/fixtures/subdir/middle-include.adoc +0 -5
- data/test/fixtures/subs-docinfo.html +0 -2
- data/test/fixtures/subs.adoc +0 -6
- data/test/fixtures/tagged-class-enclosed.rb +0 -25
- data/test/fixtures/tagged-class.rb +0 -23
- data/test/fixtures/tip.gif +0 -0
- data/test/fixtures/unclosed-tag.adoc +0 -3
- data/test/fixtures/unexpected-end-tag.adoc +0 -4
- data/test/invoker_test.rb +0 -745
- data/test/links_test.rb +0 -855
- data/test/lists_test.rb +0 -5151
- data/test/logger_test.rb +0 -211
- data/test/manpage_test.rb +0 -660
- data/test/options_test.rb +0 -262
- data/test/paragraphs_test.rb +0 -562
- data/test/parser_test.rb +0 -742
- data/test/paths_test.rb +0 -395
- data/test/preamble_test.rb +0 -173
- data/test/reader_test.rb +0 -2161
- data/test/sections_test.rb +0 -3575
- data/test/substitutions_test.rb +0 -2066
- data/test/tables_test.rb +0 -2036
- data/test/test_helper.rb +0 -447
- data/test/text_test.rb +0 -309
@@ -1,55 +1,47 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
# A {Converter} implementation that delegates to the chain of {Converter}
|
4
|
+
# objects passed to the constructor. Selects the first {Converter} that
|
5
|
+
# identifies itself as the handler for a given transform.
|
6
|
+
class Converter::CompositeConverter < Converter::Base
|
7
|
+
# Get the Array of Converter objects in the chain
|
8
|
+
attr_reader :converters
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
converter.composed self if converter.respond_to? :composed
|
15
|
-
end
|
16
|
-
@converter_map = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
# Public: Delegates to the first converter that identifies itself as the
|
20
|
-
# handler for the given transform. The optional Hash is passed as the last
|
21
|
-
# option to the delegate's convert method.
|
22
|
-
#
|
23
|
-
# node - the AbstractNode to convert
|
24
|
-
# transform - the optional String transform, or the name of the node if no
|
25
|
-
# transform is specified. (default: nil)
|
26
|
-
# opts - an optional Hash that is passed to the delegate's convert method. (default: {})
|
27
|
-
#
|
28
|
-
# Returns the String result returned from the delegate's convert method
|
29
|
-
def convert node, transform = nil, opts = {}
|
30
|
-
transform ||= node.node_name
|
31
|
-
(converter_for transform).convert node, transform, opts
|
32
|
-
end
|
10
|
+
def initialize backend, *converters, backend_traits_source: nil
|
11
|
+
@backend = backend
|
12
|
+
(@converters = converters).each {|converter| converter.composed self if converter.respond_to? :composed }
|
13
|
+
init_backend_traits backend_traits_source.backend_traits if backend_traits_source
|
14
|
+
@converter_cache = ::Hash.new {|hash, key| hash[key] = find_converter key }
|
15
|
+
end
|
33
16
|
|
34
|
-
|
35
|
-
|
17
|
+
# Public: Delegates to the first converter that identifies itself as the
|
18
|
+
# handler for the given transform. The optional Hash is passed as the last
|
19
|
+
# option to the delegate's convert method.
|
20
|
+
#
|
21
|
+
# node - the AbstractNode to convert
|
22
|
+
# transform - the optional String transform, or the name of the node if no
|
23
|
+
# transform is specified. (default: nil)
|
24
|
+
# opts - an optional Hash that is passed to the delegate's convert method. (default: nil)
|
25
|
+
#
|
26
|
+
# Returns the String result returned from the delegate's convert method
|
27
|
+
def convert node, transform = nil, opts = nil
|
28
|
+
(converter_for transform ||= node.node_name).convert node, transform, opts
|
29
|
+
end
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
31
|
+
# Public: Retrieve the converter for the specified transform.
|
32
|
+
#
|
33
|
+
# Returns the matching [Converter] object
|
34
|
+
def converter_for transform
|
35
|
+
@converter_cache[transform]
|
36
|
+
end
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
raise %(Could not find a converter to handle transform: #{transform})
|
53
|
-
end
|
38
|
+
# Public: Find the converter for the specified transform.
|
39
|
+
# Raise an exception if no converter is found.
|
40
|
+
#
|
41
|
+
# Returns the matching [Converter] object
|
42
|
+
def find_converter transform
|
43
|
+
@converters.each {|candidate| return candidate if candidate.handles? transform }
|
44
|
+
raise %(Could not find a converter to handle transform: #{transform})
|
54
45
|
end
|
55
46
|
end
|
47
|
+
end
|
@@ -1,815 +1,779 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
3
|
+
# A built-in {Converter} implementation that generates DocBook 5 output. The output is inspired by the output produced
|
4
|
+
# by the docbook45 backend from AsciiDoc Python, except it has been migrated to the DocBook 5 specification.
|
5
|
+
class Converter::DocBook5Converter < Converter::Base
|
6
|
+
register_for 'docbook5'
|
7
|
+
|
8
|
+
# default represents variablelist
|
9
|
+
(DLIST_TAGS = {
|
10
|
+
'qanda' => { list: 'qandaset', entry: 'qandaentry', label: 'question', term: 'simpara', item: 'answer' },
|
11
|
+
'glossary' => { list: nil, entry: 'glossentry', term: 'glossterm', item: 'glossdef' },
|
12
|
+
}).default = { list: 'variablelist', entry: 'varlistentry', term: 'term', item: 'listitem' }
|
13
|
+
|
14
|
+
(QUOTE_TAGS = {
|
15
|
+
monospaced: ['<literal>', '</literal>'],
|
16
|
+
emphasis: ['<emphasis>', '</emphasis>', true],
|
17
|
+
strong: ['<emphasis role="strong">', '</emphasis>', true],
|
18
|
+
double: ['<quote>', '</quote>', true],
|
19
|
+
single: ['<quote>', '</quote>', true],
|
20
|
+
mark: ['<emphasis role="marked">', '</emphasis>'],
|
21
|
+
superscript: ['<superscript>', '</superscript>'],
|
22
|
+
subscript: ['<subscript>', '</subscript>'],
|
23
|
+
}).default = ['', '', true]
|
24
|
+
|
25
|
+
MANPAGE_SECTION_TAGS = { 'section' => 'refsection', 'synopsis' => 'refsynopsisdiv' }
|
26
|
+
TABLE_PI_NAMES = ['dbhtml', 'dbfo', 'dblatex']
|
27
|
+
|
28
|
+
CopyrightRx = /^(.+?)(?: ((?:\d{4}\-)?\d{4}))?$/
|
29
|
+
ImageMacroRx = /^image::?(.+?)\[(.*?)\]$/
|
30
|
+
|
31
|
+
def initialize backend, opts = {}
|
32
|
+
@backend = backend
|
33
|
+
init_backend_traits basebackend: 'docbook', filetype: 'xml', outfilesuffix: '.xml', supports_templates: true
|
34
|
+
end
|
35
|
+
|
36
|
+
def document node
|
37
|
+
result = ['<?xml version="1.0" encoding="UTF-8"?>']
|
38
|
+
if node.attr? 'toc'
|
39
|
+
if node.attr? 'toclevels'
|
40
|
+
result << %(<?asciidoc-toc maxdepth="#{node.attr 'toclevels'}"?>)
|
41
|
+
else
|
42
|
+
result << '<?asciidoc-toc?>'
|
32
43
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
result <<
|
44
|
+
end
|
45
|
+
if node.attr? 'sectnums'
|
46
|
+
if node.attr? 'sectnumlevels'
|
47
|
+
result << %(<?asciidoc-numbered maxdepth="#{node.attr 'sectnumlevels'}"?>)
|
48
|
+
else
|
49
|
+
result << '<?asciidoc-numbered?>'
|
39
50
|
end
|
40
|
-
result << %(</#{root_tag_name}>)
|
41
|
-
result.join LF
|
42
51
|
end
|
52
|
+
lang_attribute = (node.attr? 'nolang') ? '' : %( xml:lang="#{node.attr 'lang', 'en'}")
|
53
|
+
if (root_tag_name = node.doctype) == 'manpage'
|
54
|
+
root_tag_name = 'refentry'
|
55
|
+
end
|
56
|
+
result << %(<#{root_tag_name} xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0"#{lang_attribute}#{_common_attributes node.id}>)
|
57
|
+
result << (_document_info_tag node) unless node.noheader
|
58
|
+
unless (docinfo_content = node.docinfo :header).empty?
|
59
|
+
result << docinfo_content
|
60
|
+
end
|
61
|
+
result << node.content if node.blocks?
|
62
|
+
unless (docinfo_content = node.docinfo :footer).empty?
|
63
|
+
result << docinfo_content
|
64
|
+
end
|
65
|
+
result << %(</#{root_tag_name}>)
|
66
|
+
result.join LF
|
67
|
+
end
|
43
68
|
|
44
|
-
|
45
|
-
|
46
|
-
MANPAGE_SECTION_TAGS = { 'section' => 'refsection', 'synopsis' => 'refsynopsisdiv' }
|
69
|
+
alias embedded _content_only
|
47
70
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
71
|
+
def section node
|
72
|
+
if node.document.doctype == 'manpage'
|
73
|
+
tag_name = MANPAGE_SECTION_TAGS[tag_name = node.sectname] || tag_name
|
74
|
+
else
|
75
|
+
tag_name = node.sectname
|
76
|
+
end
|
77
|
+
title_el = node.special && (node.option? 'untitled') ? '' : %(<title>#{node.title}</title>\n)
|
78
|
+
%(<#{tag_name}#{_common_attributes node.id, node.role, node.reftext}>
|
56
79
|
#{title_el}#{node.content}
|
57
80
|
</#{tag_name}>)
|
58
|
-
|
81
|
+
end
|
59
82
|
|
60
|
-
|
61
|
-
|
62
|
-
#{
|
83
|
+
def admonition node
|
84
|
+
%(<#{tag_name = node.attr 'name'}#{_common_attributes node.id, node.role, node.reftext}>
|
85
|
+
#{_title_tag node}#{_enclose_content node}
|
63
86
|
</#{tag_name}>)
|
64
|
-
|
87
|
+
end
|
65
88
|
|
66
|
-
|
89
|
+
alias audio _skip
|
67
90
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
result << %(</calloutlist>)
|
79
|
-
result.join LF
|
91
|
+
def colist node
|
92
|
+
result = []
|
93
|
+
result << %(<calloutlist#{_common_attributes node.id, node.role, node.reftext}>)
|
94
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
95
|
+
node.items.each do |item|
|
96
|
+
result << %(<callout arearefs="#{item.attr 'coids'}">)
|
97
|
+
result << %(<para>#{item.text}</para>)
|
98
|
+
result << item.content if item.blocks?
|
99
|
+
result << '</callout>'
|
80
100
|
end
|
101
|
+
result << %(</calloutlist>)
|
102
|
+
result.join LF
|
103
|
+
end
|
81
104
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
:term => 'simpara',
|
88
|
-
:item => 'answer'
|
89
|
-
},
|
90
|
-
'glossary' => {
|
91
|
-
:list => nil,
|
92
|
-
:entry => 'glossentry',
|
93
|
-
:term => 'glossterm',
|
94
|
-
:item => 'glossdef'
|
95
|
-
}
|
96
|
-
}).default = { # default is variable
|
97
|
-
:list => 'variablelist',
|
98
|
-
:entry => 'varlistentry',
|
99
|
-
:term => 'term',
|
100
|
-
:item => 'listitem'
|
101
|
-
}
|
102
|
-
|
103
|
-
def dlist node
|
104
|
-
result = []
|
105
|
-
if node.style == 'horizontal'
|
106
|
-
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{common_attributes node.id, node.role, node.reftext} tabstyle="horizontal" frame="none" colsep="0" rowsep="0">
|
107
|
-
#{title_tag node}<tgroup cols="2">
|
105
|
+
def dlist node
|
106
|
+
result = []
|
107
|
+
if node.style == 'horizontal'
|
108
|
+
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{_common_attributes node.id, node.role, node.reftext} tabstyle="horizontal" frame="none" colsep="0" rowsep="0">
|
109
|
+
#{_title_tag node}<tgroup cols="2">
|
108
110
|
<colspec colwidth="#{node.attr 'labelwidth', 15}*"/>
|
109
111
|
<colspec colwidth="#{node.attr 'itemwidth', 85}*"/>
|
110
112
|
<tbody valign="top">)
|
111
|
-
|
112
|
-
|
113
|
+
node.items.each do |terms, dd|
|
114
|
+
result << %(<row>
|
113
115
|
<entry>)
|
114
|
-
|
115
|
-
|
116
|
-
end
|
117
|
-
result << %(</entry>
|
116
|
+
terms.each {|dt| result << %(<simpara>#{dt.text}</simpara>) }
|
117
|
+
result << %(</entry>
|
118
118
|
<entry>)
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
123
|
-
result << %(</entry>
|
124
|
-
</row>)
|
119
|
+
if dd
|
120
|
+
result << %(<simpara>#{dd.text}</simpara>) if dd.text?
|
121
|
+
result << dd.content if dd.blocks?
|
125
122
|
end
|
126
|
-
result << %(</
|
123
|
+
result << %(</entry>
|
124
|
+
</row>)
|
125
|
+
end
|
126
|
+
result << %(</tbody>
|
127
127
|
</tgroup>
|
128
128
|
</#{tag_name}>)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
node.items.each do |terms, dd|
|
142
|
-
result << %(<#{entry_tag}>)
|
143
|
-
result << %(<#{label_tag}>) if label_tag
|
144
|
-
|
145
|
-
[*terms].each do |dt|
|
146
|
-
result << %(<#{term_tag}>#{dt.text}</#{term_tag}>)
|
147
|
-
end
|
129
|
+
else
|
130
|
+
tags = DLIST_TAGS[node.style]
|
131
|
+
list_tag = tags[:list]
|
132
|
+
entry_tag = tags[:entry]
|
133
|
+
label_tag = tags[:label]
|
134
|
+
term_tag = tags[:term]
|
135
|
+
item_tag = tags[:item]
|
136
|
+
if list_tag
|
137
|
+
result << %(<#{list_tag}#{_common_attributes node.id, node.role, node.reftext}>)
|
138
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
139
|
+
end
|
148
140
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
result << %(
|
141
|
+
node.items.each do |terms, dd|
|
142
|
+
result << %(<#{entry_tag}>)
|
143
|
+
result << %(<#{label_tag}>) if label_tag
|
144
|
+
terms.each {|dt| result << %(<#{term_tag}>#{dt.text}</#{term_tag}>) }
|
145
|
+
result << %(</#{label_tag}>) if label_tag
|
146
|
+
result << %(<#{item_tag}>)
|
147
|
+
if dd
|
148
|
+
result << %(<simpara>#{dd.text}</simpara>) if dd.text?
|
149
|
+
result << dd.content if dd.blocks?
|
157
150
|
end
|
158
|
-
|
159
|
-
result << %(</#{
|
151
|
+
result << %(</#{item_tag}>)
|
152
|
+
result << %(</#{entry_tag}>)
|
160
153
|
end
|
161
154
|
|
162
|
-
result
|
155
|
+
result << %(</#{list_tag}>) if list_tag
|
163
156
|
end
|
164
157
|
|
165
|
-
|
166
|
-
|
167
|
-
|
158
|
+
result.join LF
|
159
|
+
end
|
160
|
+
|
161
|
+
def example node
|
162
|
+
if node.title?
|
163
|
+
%(<example#{_common_attributes node.id, node.role, node.reftext}>
|
168
164
|
<title>#{node.title}</title>
|
169
|
-
#{
|
165
|
+
#{_enclose_content node}
|
170
166
|
</example>)
|
171
|
-
|
172
|
-
|
173
|
-
#{
|
167
|
+
else
|
168
|
+
%(<informalexample#{_common_attributes node.id, node.role, node.reftext}>
|
169
|
+
#{_enclose_content node}
|
174
170
|
</informalexample>)
|
175
|
-
end
|
176
171
|
end
|
172
|
+
end
|
177
173
|
|
178
|
-
|
179
|
-
|
180
|
-
|
174
|
+
def floating_title node
|
175
|
+
%(<bridgehead#{_common_attributes node.id, node.role, node.reftext} renderas="sect#{node.level}">#{node.title}</bridgehead>)
|
176
|
+
end
|
181
177
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
178
|
+
def image node
|
179
|
+
# NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
|
180
|
+
# See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
|
181
|
+
if node.attr? 'scaledwidth'
|
182
|
+
width_attribute = %( width="#{node.attr 'scaledwidth'}")
|
183
|
+
depth_attribute = ''
|
184
|
+
scale_attribute = ''
|
185
|
+
elsif node.attr? 'scale'
|
186
|
+
# QUESTION should we set the viewport using width and depth? (the scaled image would be contained within this box)
|
187
|
+
#width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
|
188
|
+
#depth_attribute = (node.attr? 'height') ? %( depth="#{node.attr 'height'}") : ''
|
189
|
+
scale_attribute = %( scale="#{node.attr 'scale'}")
|
190
|
+
else
|
191
|
+
width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
|
192
|
+
depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
|
193
|
+
scale_attribute = ''
|
194
|
+
end
|
195
|
+
align_attribute = (node.attr? 'align') ? %( align="#{node.attr 'align'}") : ''
|
200
196
|
|
201
|
-
|
197
|
+
mediaobject = %(<mediaobject>
|
202
198
|
<imageobject>
|
203
199
|
<imagedata fileref="#{node.image_uri(node.attr 'target')}"#{width_attribute}#{depth_attribute}#{scale_attribute}#{align_attribute}/>
|
204
200
|
</imageobject>
|
205
201
|
<textobject><phrase>#{node.alt}</phrase></textobject>
|
206
202
|
</mediaobject>)
|
207
203
|
|
208
|
-
|
209
|
-
|
204
|
+
if node.title?
|
205
|
+
%(<figure#{_common_attributes node.id, node.role, node.reftext}>
|
210
206
|
<title>#{node.title}</title>
|
211
207
|
#{mediaobject}
|
212
208
|
</figure>)
|
213
|
-
|
214
|
-
|
209
|
+
else
|
210
|
+
%(<informalfigure#{_common_attributes node.id, node.role, node.reftext}>
|
215
211
|
#{mediaobject}
|
216
212
|
</informalfigure>)
|
217
|
-
end
|
218
213
|
end
|
214
|
+
end
|
219
215
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
numbering_attributes = %( linenumbering="numbered" startinglinenumber="#{attrs['start'].to_i}")
|
227
|
-
else
|
228
|
-
numbering_attributes = ' linenumbering="numbered"'
|
229
|
-
end
|
230
|
-
else
|
231
|
-
numbering_attributes = ' linenumbering="unnumbered"'
|
232
|
-
end
|
233
|
-
listing_content = %(<programlisting#{informal ? listing_attributes : ''} language="#{attrs['language']}"#{numbering_attributes}>#{node.content}</programlisting>)
|
216
|
+
def listing node
|
217
|
+
informal = !node.title?
|
218
|
+
common_attrs = _common_attributes node.id, node.role, node.reftext
|
219
|
+
if node.style == 'source'
|
220
|
+
if (attrs = node.attributes).key? 'linenums'
|
221
|
+
numbering_attrs = (attrs.key? 'start') ? %( linenumbering="numbered" startinglinenumber="#{attrs['start'].to_i}") : ' linenumbering="numbered"'
|
234
222
|
else
|
235
|
-
|
223
|
+
numbering_attrs = ' linenumbering="unnumbered"'
|
236
224
|
end
|
237
|
-
if
|
238
|
-
|
225
|
+
if attrs.key? 'language'
|
226
|
+
wrapped_content = %(<programlisting#{informal ? common_attrs : ''} language="#{attrs['language']}"#{numbering_attrs}>#{node.content}</programlisting>)
|
239
227
|
else
|
240
|
-
%(<
|
228
|
+
wrapped_content = %(<screen#{informal ? common_attrs : ''}#{numbering_attrs}>#{node.content}</screen>)
|
229
|
+
end
|
230
|
+
else
|
231
|
+
wrapped_content = %(<screen#{informal ? common_attrs : ''}>#{node.content}</screen>)
|
232
|
+
end
|
233
|
+
informal ? wrapped_content : %(<formalpara#{common_attrs}>
|
241
234
|
<title>#{node.title}</title>
|
242
235
|
<para>
|
243
|
-
#{
|
236
|
+
#{wrapped_content}
|
244
237
|
</para>
|
245
238
|
</formalpara>)
|
246
|
-
|
247
|
-
end
|
239
|
+
end
|
248
240
|
|
249
|
-
|
250
|
-
|
251
|
-
|
241
|
+
def literal node
|
242
|
+
if node.title?
|
243
|
+
%(<formalpara#{_common_attributes node.id, node.role, node.reftext}>
|
252
244
|
<title>#{node.title}</title>
|
253
245
|
<para>
|
254
246
|
<literallayout class="monospaced">#{node.content}</literallayout>
|
255
247
|
</para>
|
256
248
|
</formalpara>)
|
257
|
-
|
258
|
-
|
259
|
-
end
|
249
|
+
else
|
250
|
+
%(<literallayout#{_common_attributes node.id, node.role, node.reftext} class="monospaced">#{node.content}</literallayout>)
|
260
251
|
end
|
252
|
+
end
|
261
253
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
279
|
-
equation_data = %(<alt><![CDATA[#{equation}]]></alt>
|
254
|
+
alias pass _content_only
|
255
|
+
|
256
|
+
def stem node
|
257
|
+
if (idx = node.subs.index :specialcharacters)
|
258
|
+
node.subs.delete_at idx
|
259
|
+
equation = node.content || ''
|
260
|
+
idx > 0 ? (node.subs.insert idx, :specialcharacters) : (node.subs.unshift :specialcharacters)
|
261
|
+
else
|
262
|
+
equation = node.content || ''
|
263
|
+
end
|
264
|
+
if node.style == 'asciimath'
|
265
|
+
# NOTE fop requires jeuclid to process mathml markup
|
266
|
+
equation_data = _asciimath_available? ? ((::AsciiMath.parse equation).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML') : %(<mathphrase><![CDATA[#{equation}]]></mathphrase>)
|
267
|
+
else
|
268
|
+
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
269
|
+
equation_data = %(<alt><![CDATA[#{equation}]]></alt>
|
280
270
|
<mathphrase><![CDATA[#{equation}]]></mathphrase>)
|
281
|
-
|
282
|
-
|
283
|
-
|
271
|
+
end
|
272
|
+
if node.title?
|
273
|
+
%(<equation#{_common_attributes node.id, node.role, node.reftext}>
|
284
274
|
<title>#{node.title}</title>
|
285
275
|
#{equation_data}
|
286
276
|
</equation>)
|
287
|
-
|
288
|
-
|
289
|
-
|
277
|
+
else
|
278
|
+
# WARNING dblatex displays the <informalequation> element inline instead of block as documented (except w/ mathml)
|
279
|
+
%(<informalequation#{_common_attributes node.id, node.role, node.reftext}>
|
290
280
|
#{equation_data}
|
291
281
|
</informalequation>)
|
292
|
-
end
|
293
282
|
end
|
283
|
+
end
|
294
284
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
285
|
+
def olist node
|
286
|
+
result = []
|
287
|
+
num_attribute = node.style ? %( numeration="#{node.style}") : ''
|
288
|
+
start_attribute = (node.attr? 'start') ? %( startingnumber="#{node.attr 'start'}") : ''
|
289
|
+
result << %(<orderedlist#{_common_attributes node.id, node.role, node.reftext}#{num_attribute}#{start_attribute}>)
|
290
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
291
|
+
node.items.each do |item|
|
292
|
+
result << %(<listitem#{_common_attributes item.id, item.role}>)
|
293
|
+
result << %(<simpara>#{item.text}</simpara>)
|
294
|
+
result << item.content if item.blocks?
|
295
|
+
result << '</listitem>'
|
296
|
+
end
|
297
|
+
result << %(</orderedlist>)
|
298
|
+
result.join LF
|
299
|
+
end
|
310
300
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
#{
|
301
|
+
def open node
|
302
|
+
case node.style
|
303
|
+
when 'abstract'
|
304
|
+
if node.parent == node.document && node.document.doctype == 'book'
|
305
|
+
logger.warn 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
|
306
|
+
''
|
307
|
+
else
|
308
|
+
%(<abstract>
|
309
|
+
#{_title_tag node}#{_enclose_content node}
|
320
310
|
</abstract>)
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
else
|
327
|
-
%(<partintro#{common_attributes node.id, node.role, node.reftext}>
|
328
|
-
#{title_tag node}#{resolve_content node}
|
329
|
-
</partintro>)
|
330
|
-
end
|
311
|
+
end
|
312
|
+
when 'partintro'
|
313
|
+
unless node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
|
314
|
+
logger.error 'partintro block can only be used when doctype is book and must be a child of a book part. Excluding block content.'
|
315
|
+
''
|
331
316
|
else
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
317
|
+
%(<partintro#{_common_attributes node.id, node.role, node.reftext}>
|
318
|
+
#{_title_tag node}#{_enclose_content node}
|
319
|
+
</partintro>)
|
320
|
+
end
|
321
|
+
else
|
322
|
+
reftext = node.reftext if (id = node.id)
|
323
|
+
role = node.role
|
324
|
+
if node.title?
|
325
|
+
%(<formalpara#{_common_attributes id, role, reftext}>
|
336
326
|
<title>#{node.title}</title>
|
337
327
|
<para>#{content_spacer = node.content_model == :compound ? LF : ''}#{node.content}#{content_spacer}</para>
|
338
328
|
</formalpara>)
|
339
|
-
|
340
|
-
|
341
|
-
|
329
|
+
elsif id || role
|
330
|
+
if node.content_model == :compound
|
331
|
+
%(<para#{_common_attributes id, role, reftext}>
|
342
332
|
#{node.content}
|
343
333
|
</para>)
|
344
|
-
else
|
345
|
-
%(<simpara#{common_attributes id, role, reftext}>#{node.content}</simpara>)
|
346
|
-
end
|
347
334
|
else
|
348
|
-
|
335
|
+
%(<simpara#{_common_attributes id, role, reftext}>#{node.content}</simpara>)
|
349
336
|
end
|
337
|
+
else
|
338
|
+
_enclose_content node
|
350
339
|
end
|
351
340
|
end
|
341
|
+
end
|
352
342
|
|
353
|
-
|
354
|
-
|
355
|
-
|
343
|
+
def page_break node
|
344
|
+
'<simpara><?asciidoc-pagebreak?></simpara>'
|
345
|
+
end
|
356
346
|
|
357
|
-
|
358
|
-
|
359
|
-
|
347
|
+
def paragraph node
|
348
|
+
if node.title?
|
349
|
+
%(<formalpara#{_common_attributes node.id, node.role, node.reftext}>
|
360
350
|
<title>#{node.title}</title>
|
361
351
|
<para>#{node.content}</para>
|
362
352
|
</formalpara>)
|
363
|
-
|
364
|
-
|
365
|
-
end
|
353
|
+
else
|
354
|
+
%(<simpara#{_common_attributes node.id, node.role, node.reftext}>#{node.content}</simpara>)
|
366
355
|
end
|
356
|
+
end
|
367
357
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
#{
|
358
|
+
def preamble node
|
359
|
+
if node.document.doctype == 'book'
|
360
|
+
%(<preface#{_common_attributes node.id, node.role, node.reftext}>
|
361
|
+
#{_title_tag node, false}#{node.content}
|
372
362
|
</preface>)
|
373
|
-
|
374
|
-
|
375
|
-
end
|
363
|
+
else
|
364
|
+
node.content
|
376
365
|
end
|
366
|
+
end
|
377
367
|
|
378
|
-
|
379
|
-
|
380
|
-
|
368
|
+
def quote node
|
369
|
+
_blockquote_tag(node, (node.has_role? 'epigraph') && 'epigraph') { _enclose_content node }
|
370
|
+
end
|
381
371
|
|
382
|
-
|
383
|
-
|
384
|
-
|
372
|
+
def thematic_break node
|
373
|
+
'<simpara><?asciidoc-hr?></simpara>'
|
374
|
+
end
|
385
375
|
|
386
|
-
|
387
|
-
|
388
|
-
#{
|
376
|
+
def sidebar node
|
377
|
+
%(<sidebar#{_common_attributes node.id, node.role, node.reftext}>
|
378
|
+
#{_title_tag node}#{_enclose_content node}
|
389
379
|
</sidebar>)
|
390
|
-
|
391
|
-
|
392
|
-
TABLE_PI_NAMES = ['dbhtml', 'dbfo', 'dblatex']
|
380
|
+
end
|
393
381
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
382
|
+
def table node
|
383
|
+
has_body = false
|
384
|
+
result = []
|
385
|
+
pgwide_attribute = (node.option? 'pgwide') ? ' pgwide="1"' : ''
|
386
|
+
if (frame = node.attr 'frame', 'all', 'table-frame') == 'ends'
|
387
|
+
frame = 'topbot'
|
388
|
+
end
|
389
|
+
grid = node.attr 'grid', nil, 'table-grid'
|
390
|
+
result << %(<#{tag_name = node.title? ? 'table' : 'informaltable'}#{_common_attributes node.id, node.role, node.reftext}#{pgwide_attribute} frame="#{frame}" rowsep="#{['none', 'cols'].include?(grid) ? 0 : 1}" colsep="#{['none', 'rows'].include?(grid) ? 0 : 1}"#{(node.attr? 'orientation', 'landscape', 'table-orientation') ? ' orient="land"' : ''}>)
|
391
|
+
if (node.option? 'unbreakable')
|
392
|
+
result << '<?dbfo keep-together="always"?>'
|
393
|
+
elsif (node.option? 'breakable')
|
394
|
+
result << '<?dbfo keep-together="auto"?>'
|
395
|
+
end
|
396
|
+
result << %(<title>#{node.title}</title>) if tag_name == 'table'
|
397
|
+
col_width_key = if (width = (node.attr? 'width') ? (node.attr 'width') : nil)
|
398
|
+
TABLE_PI_NAMES.each do |pi_name|
|
399
|
+
result << %(<?#{pi_name} table-width="#{width}"?>)
|
400
|
+
end
|
401
|
+
'colabswidth'
|
402
|
+
else
|
403
|
+
'colpcwidth'
|
404
|
+
end
|
405
|
+
result << %(<tgroup cols="#{node.attr 'colcount'}">)
|
406
|
+
node.columns.each do |col|
|
407
|
+
result << %(<colspec colname="col_#{col.attr 'colnumber'}" colwidth="#{col.attr col_width_key}*"/>)
|
408
|
+
end
|
409
|
+
node.rows.to_h.each do |tsec, rows|
|
410
|
+
next if rows.empty?
|
411
|
+
has_body = true if tsec == :body
|
412
|
+
result << %(<t#{tsec}>)
|
413
|
+
rows.each do |row|
|
414
|
+
result << '<row>'
|
415
|
+
row.each do |cell|
|
416
|
+
halign_attribute = (cell.attr? 'halign') ? %( align="#{cell.attr 'halign'}") : ''
|
417
|
+
valign_attribute = (cell.attr? 'valign') ? %( valign="#{cell.attr 'valign'}") : ''
|
418
|
+
colspan_attribute = cell.colspan ? %( namest="col_#{colnum = cell.column.attr 'colnumber'}" nameend="col_#{colnum + cell.colspan - 1}") : ''
|
419
|
+
rowspan_attribute = cell.rowspan ? %( morerows="#{cell.rowspan - 1}") : ''
|
420
|
+
# NOTE <entry> may not have whitespace (e.g., line breaks) as a direct descendant according to DocBook rules
|
421
|
+
entry_start = %(<entry#{halign_attribute}#{valign_attribute}#{colspan_attribute}#{rowspan_attribute}>)
|
422
|
+
if tsec == :head
|
423
|
+
cell_content = cell.text
|
424
|
+
else
|
425
|
+
case cell.style
|
426
|
+
when :asciidoc
|
427
|
+
cell_content = cell.content
|
428
|
+
when :literal
|
429
|
+
cell_content = %(<literallayout class="monospaced">#{cell.text}</literallayout>)
|
430
|
+
when :header
|
431
|
+
cell_content = (cell_content = cell.content).empty? ? '' : %(<simpara><emphasis role="strong">#{cell_content.join '</emphasis></simpara><simpara><emphasis role="strong">'}</emphasis></simpara>)
|
435
432
|
else
|
436
|
-
|
437
|
-
when :asciidoc
|
438
|
-
cell_content = cell.content
|
439
|
-
when :verse
|
440
|
-
cell_content = %(<literallayout>#{cell.text}</literallayout>)
|
441
|
-
when :literal
|
442
|
-
cell_content = %(<literallayout class="monospaced">#{cell.text}</literallayout>)
|
443
|
-
when :header
|
444
|
-
cell_content = (cell_content = cell.content).empty? ? '' : %(<simpara><emphasis role="strong">#{cell_content.join '</emphasis></simpara><simpara><emphasis role="strong">'}</emphasis></simpara>)
|
445
|
-
else
|
446
|
-
cell_content = (cell_content = cell.content).empty? ? '' : %(<simpara>#{cell_content.join '</simpara><simpara>'}</simpara>)
|
447
|
-
end
|
433
|
+
cell_content = (cell_content = cell.content).empty? ? '' : %(<simpara>#{cell_content.join '</simpara><simpara>'}</simpara>)
|
448
434
|
end
|
449
|
-
entry_end = (node.document.attr? 'cellbgcolor') ? %(<?dbfo bgcolor="#{node.document.attr 'cellbgcolor'}"?></entry>) : '</entry>'
|
450
|
-
result << %(#{entry_start}#{cell_content}#{entry_end})
|
451
435
|
end
|
452
|
-
|
436
|
+
entry_end = (node.document.attr? 'cellbgcolor') ? %(<?dbfo bgcolor="#{node.document.attr 'cellbgcolor'}"?></entry>) : '</entry>'
|
437
|
+
result << %(#{entry_start}#{cell_content}#{entry_end})
|
453
438
|
end
|
454
|
-
result <<
|
439
|
+
result << '</row>'
|
455
440
|
end
|
456
|
-
result <<
|
457
|
-
result << %(</#{tag_name}>)
|
458
|
-
|
459
|
-
logger.warn 'tables must have at least one body row' unless has_body
|
460
|
-
result.join LF
|
441
|
+
result << %(</t#{tsec}>)
|
461
442
|
end
|
443
|
+
result << '</tgroup>'
|
444
|
+
result << %(</#{tag_name}>)
|
462
445
|
|
463
|
-
|
446
|
+
logger.warn 'tables must have at least one body row' unless has_body
|
447
|
+
result.join LF
|
448
|
+
end
|
464
449
|
|
465
|
-
|
466
|
-
result = []
|
467
|
-
if node.style == 'bibliography'
|
468
|
-
result << %(<bibliodiv#{common_attributes node.id, node.role, node.reftext}>)
|
469
|
-
result << %(<title>#{node.title}</title>) if node.title?
|
470
|
-
node.items.each do |item|
|
471
|
-
result << '<bibliomixed>'
|
472
|
-
result << %(<bibliomisc>#{item.text}</bibliomisc>)
|
473
|
-
result << item.content if item.blocks?
|
474
|
-
result << '</bibliomixed>'
|
475
|
-
end
|
476
|
-
result << '</bibliodiv>'
|
477
|
-
else
|
478
|
-
mark_type = (checklist = node.option? 'checklist') ? 'none' : node.style
|
479
|
-
mark_attribute = mark_type ? %( mark="#{mark_type}") : ''
|
480
|
-
result << %(<itemizedlist#{common_attributes node.id, node.role, node.reftext}#{mark_attribute}>)
|
481
|
-
result << %(<title>#{node.title}</title>) if node.title?
|
482
|
-
node.items.each do |item|
|
483
|
-
text_marker = if checklist && (item.attr? 'checkbox')
|
484
|
-
(item.attr? 'checked') ? '✓ ' : '❏ '
|
485
|
-
else
|
486
|
-
''
|
487
|
-
end
|
488
|
-
result << '<listitem>'
|
489
|
-
result << %(<simpara>#{text_marker}#{item.text}</simpara>)
|
490
|
-
result << item.content if item.blocks?
|
491
|
-
result << '</listitem>'
|
492
|
-
end
|
493
|
-
result << '</itemizedlist>'
|
494
|
-
end
|
450
|
+
alias toc _skip
|
495
451
|
|
496
|
-
|
452
|
+
def ulist node
|
453
|
+
result = []
|
454
|
+
if node.style == 'bibliography'
|
455
|
+
result << %(<bibliodiv#{_common_attributes node.id, node.role, node.reftext}>)
|
456
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
457
|
+
node.items.each do |item|
|
458
|
+
result << '<bibliomixed>'
|
459
|
+
result << %(<bibliomisc>#{item.text}</bibliomisc>)
|
460
|
+
result << item.content if item.blocks?
|
461
|
+
result << '</bibliomixed>'
|
462
|
+
end
|
463
|
+
result << '</bibliodiv>'
|
464
|
+
else
|
465
|
+
mark_type = (checklist = node.option? 'checklist') ? 'none' : node.style
|
466
|
+
mark_attribute = mark_type ? %( mark="#{mark_type}") : ''
|
467
|
+
result << %(<itemizedlist#{_common_attributes node.id, node.role, node.reftext}#{mark_attribute}>)
|
468
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
469
|
+
node.items.each do |item|
|
470
|
+
text_marker = (item.attr? 'checked') ? '✓ ' : '❏ ' if checklist && (item.attr? 'checkbox')
|
471
|
+
result << %(<listitem#{_common_attributes item.id, item.role}>)
|
472
|
+
result << %(<simpara>#{text_marker || ''}#{item.text}</simpara>)
|
473
|
+
result << item.content if item.blocks?
|
474
|
+
result << '</listitem>'
|
475
|
+
end
|
476
|
+
result << '</itemizedlist>'
|
497
477
|
end
|
478
|
+
result.join LF
|
479
|
+
end
|
498
480
|
|
499
|
-
|
500
|
-
|
501
|
-
|
481
|
+
def verse node
|
482
|
+
_blockquote_tag(node, (node.has_role? 'epigraph') && 'epigraph') { %(<literallayout>#{node.content}</literallayout>) }
|
483
|
+
end
|
502
484
|
|
503
|
-
|
485
|
+
alias video _skip
|
504
486
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
else
|
514
|
-
linkend = node.attributes['fragment'] || node.target
|
515
|
-
(text = node.text) ? %(<link linkend="#{linkend}">#{text}</link>) : %(<xref linkend="#{linkend}"/>)
|
516
|
-
end
|
517
|
-
when :link
|
518
|
-
%(<link xl:href="#{node.target}">#{node.text}</link>)
|
519
|
-
when :bibref
|
520
|
-
# NOTE technically node.text should be node.reftext, but subs have already been applied to text
|
521
|
-
%(<anchor#{common_attributes node.id, nil, (text = node.text)}/>#{text})
|
487
|
+
def inline_anchor node
|
488
|
+
case node.type
|
489
|
+
when :ref
|
490
|
+
%(<anchor#{_common_attributes((id = node.id), nil, node.reftext || %([#{id}]))}/>)
|
491
|
+
when :xref
|
492
|
+
if (path = node.attributes['path'])
|
493
|
+
# QUESTION should we use refid as fallback text instead? (like the html5 backend?)
|
494
|
+
%(<link xl:href="#{node.target}">#{node.text || path}</link>)
|
522
495
|
else
|
523
|
-
|
524
|
-
|
525
|
-
end
|
496
|
+
linkend = node.attributes['fragment'] || node.target
|
497
|
+
(text = node.text) ? %(<link linkend="#{linkend}">#{text}</link>) : %(<xref linkend="#{linkend}"/>)
|
498
|
+
end
|
499
|
+
when :link
|
500
|
+
%(<link xl:href="#{node.target}">#{node.text}</link>)
|
501
|
+
when :bibref
|
502
|
+
%(<anchor#{_common_attributes node.id, nil, "[#{node.reftext || node.id}]"}/>#{text})
|
503
|
+
else
|
504
|
+
logger.warn %(unknown anchor type: #{node.type.inspect})
|
505
|
+
nil
|
526
506
|
end
|
507
|
+
end
|
527
508
|
|
528
|
-
|
529
|
-
|
530
|
-
|
509
|
+
def inline_break node
|
510
|
+
%(#{node.text}<?asciidoc-br?>)
|
511
|
+
end
|
531
512
|
|
532
|
-
|
533
|
-
|
534
|
-
|
513
|
+
def inline_button node
|
514
|
+
%(<guibutton>#{node.text}</guibutton>)
|
515
|
+
end
|
535
516
|
|
536
|
-
|
537
|
-
|
538
|
-
|
517
|
+
def inline_callout node
|
518
|
+
%(<co#{_common_attributes node.id}/>)
|
519
|
+
end
|
539
520
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
end
|
521
|
+
def inline_footnote node
|
522
|
+
if node.type == :xref
|
523
|
+
%(<footnoteref linkend="#{node.target}"/>)
|
524
|
+
else
|
525
|
+
%(<footnote#{_common_attributes node.id}><simpara>#{node.text}</simpara></footnote>)
|
546
526
|
end
|
527
|
+
end
|
547
528
|
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
529
|
+
def inline_image node
|
530
|
+
width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
|
531
|
+
depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
|
532
|
+
%(<inlinemediaobject>
|
552
533
|
<imageobject>
|
553
534
|
<imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{width_attribute}#{depth_attribute}/>
|
554
535
|
</imageobject>
|
555
536
|
<textobject><phrase>#{node.alt}</phrase></textobject>
|
556
537
|
</inlinemediaobject>)
|
557
|
-
|
538
|
+
end
|
558
539
|
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
540
|
+
def inline_indexterm node
|
541
|
+
if node.type == :visible
|
542
|
+
%(<indexterm><primary>#{node.text}</primary></indexterm>#{node.text})
|
543
|
+
else
|
544
|
+
terms = node.attr 'terms'
|
545
|
+
result = []
|
546
|
+
if (numterms = terms.size) > 2
|
547
|
+
result << %(<indexterm>
|
567
548
|
<primary>#{terms[0]}</primary><secondary>#{terms[1]}</secondary><tertiary>#{terms[2]}</tertiary>
|
568
549
|
</indexterm>)
|
569
|
-
|
570
|
-
|
571
|
-
|
550
|
+
end
|
551
|
+
if numterms > 1
|
552
|
+
result << %(<indexterm>
|
572
553
|
<primary>#{terms[-2]}</primary><secondary>#{terms[-1]}</secondary>
|
573
554
|
</indexterm>)
|
574
|
-
|
575
|
-
|
555
|
+
end
|
556
|
+
result << %(<indexterm>
|
576
557
|
<primary>#{terms[-1]}</primary>
|
577
558
|
</indexterm>)
|
578
|
-
|
579
|
-
end
|
559
|
+
result.join LF
|
580
560
|
end
|
561
|
+
end
|
581
562
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
end
|
563
|
+
def inline_kbd node
|
564
|
+
if (keys = node.attr 'keys').size == 1
|
565
|
+
%(<keycap>#{keys[0]}</keycap>)
|
566
|
+
else
|
567
|
+
%(<keycombo><keycap>#{keys.join '</keycap><keycap>'}</keycap></keycombo>)
|
588
568
|
end
|
569
|
+
end
|
589
570
|
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
else
|
596
|
-
%(<guimenu>#{menu}</guimenu>)
|
597
|
-
end
|
571
|
+
def inline_menu node
|
572
|
+
menu = node.attr 'menu'
|
573
|
+
if (submenus = node.attr 'submenus').empty?
|
574
|
+
if (menuitem = node.attr 'menuitem')
|
575
|
+
%(<menuchoice><guimenu>#{menu}</guimenu> <guimenuitem>#{menuitem}</guimenuitem></menuchoice>)
|
598
576
|
else
|
599
|
-
%(<
|
577
|
+
%(<guimenu>#{menu}</guimenu>)
|
600
578
|
end
|
579
|
+
else
|
580
|
+
%(<menuchoice><guimenu>#{menu}</guimenu> <guisubmenu>#{submenus.join '</guisubmenu> <guisubmenu>'}</guisubmenu> <guimenuitem>#{node.attr 'menuitem'}</guimenuitem></menuchoice>)
|
601
581
|
end
|
582
|
+
end
|
602
583
|
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
if (@asciimath ||= ((defined? ::AsciiMath) || (Helpers.require_library 'asciimath', true, :warn)).nil? ? :unavailable : :loaded) == :loaded
|
617
|
-
# NOTE fop requires jeuclid to process raw mathml
|
618
|
-
%(<inlineequation>#{(::AsciiMath.parse node.text).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML'}</inlineequation>)
|
584
|
+
def inline_quoted node
|
585
|
+
if (type = node.type) == :asciimath
|
586
|
+
# NOTE fop requires jeuclid to process mathml markup
|
587
|
+
_asciimath_available? ? %(<inlineequation>#{(::AsciiMath.parse node.text).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML'}</inlineequation>) : %(<inlineequation><mathphrase><![CDATA[#{node.text}]]></mathphrase></inlineequation>)
|
588
|
+
elsif type == :latexmath
|
589
|
+
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
590
|
+
%(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>)
|
591
|
+
else
|
592
|
+
open, close, supports_phrase = QUOTE_TAGS[type]
|
593
|
+
text = node.text
|
594
|
+
if node.role
|
595
|
+
if supports_phrase
|
596
|
+
quoted_text = %(#{open}<phrase role="#{node.role}">#{text}</phrase>#{close})
|
619
597
|
else
|
620
|
-
%(
|
598
|
+
quoted_text = %(#{open.chop} role="#{node.role}">#{text}#{close})
|
621
599
|
end
|
622
|
-
elsif type == :latexmath
|
623
|
-
# unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math
|
624
|
-
%(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>)
|
625
600
|
else
|
626
|
-
|
627
|
-
text = node.text
|
628
|
-
if node.role
|
629
|
-
if supports_phrase
|
630
|
-
quoted_text = %(#{open}<phrase role="#{node.role}">#{text}</phrase>#{close})
|
631
|
-
else
|
632
|
-
quoted_text = %(#{open.chop} role="#{node.role}">#{text}#{close})
|
633
|
-
end
|
634
|
-
else
|
635
|
-
quoted_text = %(#{open}#{text}#{close})
|
636
|
-
end
|
637
|
-
|
638
|
-
node.id ? %(<anchor#{common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text
|
601
|
+
quoted_text = %(#{open}#{text}#{close})
|
639
602
|
end
|
603
|
+
|
604
|
+
node.id ? %(<anchor#{_common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text
|
640
605
|
end
|
606
|
+
end
|
641
607
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
608
|
+
private
|
609
|
+
|
610
|
+
def _common_attributes id, role = nil, reftext = nil
|
611
|
+
if id
|
612
|
+
attrs = %( xml:id="#{id}"#{role ? %[ role="#{role}"] : ''})
|
613
|
+
elsif role
|
614
|
+
attrs = %( role="#{role}")
|
615
|
+
else
|
616
|
+
attrs = ''
|
617
|
+
end
|
618
|
+
if reftext
|
619
|
+
if (reftext.include? '<') && ((reftext = reftext.gsub XmlSanitizeRx, '').include? ' ')
|
620
|
+
reftext = (reftext.squeeze ' ').strip
|
651
621
|
end
|
622
|
+
reftext = (reftext.gsub '"', '"') if reftext.include? '"'
|
623
|
+
%(#{attrs} xreflabel="#{reftext}")
|
624
|
+
else
|
652
625
|
attrs
|
653
626
|
end
|
627
|
+
end
|
654
628
|
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
result << %(<email>#{author.email}</email>) if author.email
|
668
|
-
result << '</author>'
|
669
|
-
result.join LF
|
670
|
-
end
|
629
|
+
def _author_tag author
|
630
|
+
result = []
|
631
|
+
result << '<author>'
|
632
|
+
result << '<personname>'
|
633
|
+
result << %(<firstname>#{author.firstname}</firstname>) if author.firstname
|
634
|
+
result << %(<othername>#{author.middlename}</othername>) if author.middlename
|
635
|
+
result << %(<surname>#{author.lastname}</surname>) if author.lastname
|
636
|
+
result << '</personname>'
|
637
|
+
result << %(<email>#{author.email}</email>) if author.email
|
638
|
+
result << '</author>'
|
639
|
+
result.join LF
|
640
|
+
end
|
671
641
|
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
if doc.attr? 'copyright'
|
681
|
-
CopyrightRx =~ (doc.attr 'copyright')
|
682
|
-
result << '<copyright>'
|
683
|
-
result << %(<holder>#{$1}</holder>)
|
684
|
-
result << %(<year>#{$2}</year>) if $2
|
685
|
-
result << '</copyright>'
|
642
|
+
def _document_info_tag doc
|
643
|
+
result = ['<info>']
|
644
|
+
unless doc.notitle
|
645
|
+
if (title = doc.doctitle partition: true, use_fallback: true).subtitle?
|
646
|
+
result << %(<title>#{title.main}</title>
|
647
|
+
<subtitle>#{title.subtitle}</subtitle>)
|
648
|
+
else
|
649
|
+
result << %(<title>#{title}</title>)
|
686
650
|
end
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
651
|
+
end
|
652
|
+
if (date = (doc.attr? 'revdate') ? (doc.attr 'revdate') : ((doc.attr? 'reproducible') ? nil : (doc.attr 'docdate')))
|
653
|
+
result << %(<date>#{date}</date>)
|
654
|
+
end
|
655
|
+
if doc.attr? 'copyright'
|
656
|
+
CopyrightRx =~ (doc.attr 'copyright')
|
657
|
+
result << '<copyright>'
|
658
|
+
result << %(<holder>#{$1}</holder>)
|
659
|
+
result << %(<year>#{$2}</year>) if $2
|
660
|
+
result << '</copyright>'
|
661
|
+
end
|
662
|
+
if doc.header?
|
663
|
+
unless (authors = doc.authors).empty?
|
664
|
+
if authors.size > 1
|
665
|
+
result << '<authorgroup>'
|
666
|
+
authors.each {|author| result << (_author_tag author) }
|
667
|
+
result << '</authorgroup>'
|
668
|
+
else
|
669
|
+
result << _author_tag(author = authors[0])
|
670
|
+
result << %(<authorinitials>#{author.initials}</authorinitials>) if author.initials
|
697
671
|
end
|
698
|
-
|
699
|
-
|
672
|
+
end
|
673
|
+
if (doc.attr? 'revdate') && ((doc.attr? 'revnumber') || (doc.attr? 'revremark'))
|
674
|
+
result << %(<revhistory>
|
700
675
|
<revision>)
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
676
|
+
result << %(<revnumber>#{doc.attr 'revnumber'}</revnumber>) if doc.attr? 'revnumber'
|
677
|
+
result << %(<date>#{doc.attr 'revdate'}</date>) if doc.attr? 'revdate'
|
678
|
+
result << %(<authorinitials>#{doc.attr 'authorinitials'}</authorinitials>) if doc.attr? 'authorinitials'
|
679
|
+
result << %(<revremark>#{doc.attr 'revremark'}</revremark>) if doc.attr? 'revremark'
|
680
|
+
result << %(</revision>
|
706
681
|
</revhistory>)
|
682
|
+
end
|
683
|
+
if (doc.attr? 'front-cover-image') || (doc.attr? 'back-cover-image')
|
684
|
+
if (back_cover_tag = _cover_tag doc, 'back')
|
685
|
+
result << (_cover_tag doc, 'front', true)
|
686
|
+
result << back_cover_tag
|
687
|
+
elsif (front_cover_tag = _cover_tag doc, 'front')
|
688
|
+
result << front_cover_tag
|
707
689
|
end
|
708
|
-
unless use_info_tag_prefix
|
709
|
-
if (doc.attr? 'front-cover-image') || (doc.attr? 'back-cover-image')
|
710
|
-
if (back_cover_tag = cover_tag doc, 'back')
|
711
|
-
result << (cover_tag doc, 'front', true)
|
712
|
-
result << back_cover_tag
|
713
|
-
elsif (front_cover_tag = cover_tag doc, 'front')
|
714
|
-
result << front_cover_tag
|
715
|
-
end
|
716
|
-
end
|
717
|
-
end
|
718
|
-
unless (head_docinfo = doc.docinfo).empty?
|
719
|
-
result << head_docinfo
|
720
|
-
end
|
721
|
-
result << %(<orgname>#{doc.attr 'orgname'}</orgname>) if doc.attr? 'orgname'
|
722
690
|
end
|
723
|
-
result << %(
|
724
|
-
|
725
|
-
|
726
|
-
result << '<refmeta>'
|
727
|
-
result << %(<refentrytitle>#{doc.attr 'mantitle'}</refentrytitle>) if doc.attr? 'mantitle'
|
728
|
-
result << %(<manvolnum>#{doc.attr 'manvolnum'}</manvolnum>) if doc.attr? 'manvolnum'
|
729
|
-
result << %(<refmiscinfo class="source">#{doc.attr 'mansource', ' '}</refmiscinfo>)
|
730
|
-
result << %(<refmiscinfo class="manual">#{doc.attr 'manmanual', ' '}</refmiscinfo>)
|
731
|
-
result << '</refmeta>'
|
732
|
-
result << '<refnamediv>'
|
733
|
-
result += (doc.attr 'mannames').map {|n| %(<refname>#{n}</refname>) } if doc.attr? 'mannames'
|
734
|
-
result << %(<refpurpose>#{doc.attr 'manpurpose'}</refpurpose>) if doc.attr? 'manpurpose'
|
735
|
-
result << '</refnamediv>'
|
691
|
+
result << %(<orgname>#{doc.attr 'orgname'}</orgname>) if doc.attr? 'orgname'
|
692
|
+
unless (docinfo_content = doc.docinfo).empty?
|
693
|
+
result << docinfo_content
|
736
694
|
end
|
737
|
-
|
738
|
-
result.join LF
|
739
695
|
end
|
696
|
+
result << '</info>'
|
740
697
|
|
741
|
-
|
742
|
-
|
698
|
+
if doc.doctype == 'manpage'
|
699
|
+
result << '<refmeta>'
|
700
|
+
result << %(<refentrytitle>#{doc.attr 'mantitle'}</refentrytitle>) if doc.attr? 'mantitle'
|
701
|
+
result << %(<manvolnum>#{doc.attr 'manvolnum'}</manvolnum>) if doc.attr? 'manvolnum'
|
702
|
+
result << %(<refmiscinfo class="source">#{doc.attr 'mansource', ' '}</refmiscinfo>)
|
703
|
+
result << %(<refmiscinfo class="manual">#{doc.attr 'manmanual', ' '}</refmiscinfo>)
|
704
|
+
result << '</refmeta>'
|
705
|
+
result << '<refnamediv>'
|
706
|
+
result += (doc.attr 'mannames').map {|n| %(<refname>#{n}</refname>) } if doc.attr? 'mannames'
|
707
|
+
result << %(<refpurpose>#{doc.attr 'manpurpose'}</refpurpose>) if doc.attr? 'manpurpose'
|
708
|
+
result << '</refnamediv>'
|
743
709
|
end
|
744
710
|
|
745
|
-
|
746
|
-
|
747
|
-
end
|
748
|
-
|
749
|
-
def document_title_tags title
|
750
|
-
if title.subtitle?
|
751
|
-
%(<title>#{title.main}</title>
|
752
|
-
<subtitle>#{title.subtitle}</subtitle>)
|
753
|
-
else
|
754
|
-
%(<title>#{title}</title>)
|
755
|
-
end
|
756
|
-
end
|
711
|
+
result.join LF
|
712
|
+
end
|
757
713
|
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
714
|
+
# FIXME this should be handled through a template mechanism
|
715
|
+
def _enclose_content node
|
716
|
+
node.content_model == :compound ? node.content : %(<simpara>#{node.content}</simpara>)
|
717
|
+
end
|
762
718
|
|
763
|
-
|
764
|
-
|
765
|
-
|
719
|
+
def _title_tag node, optional = true
|
720
|
+
!optional || node.title? ? %(<title>#{node.title}</title>\n) : ''
|
721
|
+
end
|
766
722
|
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
end
|
723
|
+
def _cover_tag doc, face, use_placeholder = false
|
724
|
+
if (cover_image = doc.attr %(#{face}-cover-image))
|
725
|
+
width_attr = ''
|
726
|
+
depth_attr = ''
|
727
|
+
if (cover_image.include? ':') && ImageMacroRx =~ cover_image
|
728
|
+
cover_image = doc.image_uri $1
|
729
|
+
unless $2.empty?
|
730
|
+
attrs = (AttributeList.new $2).parse ['alt', 'width', 'height']
|
731
|
+
if attrs.key? 'scaledwidth'
|
732
|
+
# NOTE scalefit="1" is the default in this case
|
733
|
+
width_attr = %( width="#{attrs['scaledwidth']}")
|
734
|
+
else
|
735
|
+
width_attr = %( contentwidth="#{attrs['width']}") if attrs.key? 'width'
|
736
|
+
depth_attr = %( contentdepth="#{attrs['height']}") if attrs.key? 'height'
|
782
737
|
end
|
783
738
|
end
|
784
|
-
|
739
|
+
end
|
740
|
+
%(<cover role="#{face}">
|
785
741
|
<mediaobject>
|
786
742
|
<imageobject>
|
787
743
|
<imagedata fileref="#{cover_image}"#{width_attr}#{depth_attr}/>
|
788
744
|
</imageobject>
|
789
745
|
</mediaobject>
|
790
746
|
</cover>)
|
791
|
-
|
792
|
-
|
793
|
-
end
|
747
|
+
elsif use_placeholder
|
748
|
+
%(<cover role="#{face}"/>)
|
794
749
|
end
|
750
|
+
end
|
795
751
|
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
752
|
+
def _blockquote_tag node, tag_name = nil
|
753
|
+
if tag_name
|
754
|
+
start_tag, end_tag = %(<#{tag_name}), %(</#{tag_name}>)
|
755
|
+
else
|
756
|
+
start_tag, end_tag = '<blockquote', '</blockquote>'
|
757
|
+
end
|
758
|
+
result = [%(#{start_tag}#{_common_attributes node.id, node.role, node.reftext}>)]
|
759
|
+
result << %(<title>#{node.title}</title>) if node.title?
|
760
|
+
if (node.attr? 'attribution') || (node.attr? 'citetitle')
|
761
|
+
result << '<attribution>'
|
762
|
+
result << (node.attr 'attribution') if node.attr? 'attribution'
|
763
|
+
result << %(<citetitle>#{node.attr 'citetitle'}</citetitle>) if node.attr? 'citetitle'
|
764
|
+
result << '</attribution>'
|
765
|
+
end
|
766
|
+
result << yield
|
767
|
+
result << end_tag
|
768
|
+
result.join LF
|
769
|
+
end
|
770
|
+
|
771
|
+
def _asciimath_available?
|
772
|
+
(@asciimath_status ||= _load_asciimath) == :loaded
|
773
|
+
end
|
774
|
+
|
775
|
+
def _load_asciimath
|
776
|
+
(defined? ::AsciiMath.parse) ? :loaded : (Helpers.require_library 'asciimath', true, :warn).nil? ? :unavailable : :loaded
|
814
777
|
end
|
815
778
|
end
|
779
|
+
end
|