asciidoctor 1.5.8 → 2.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +11 -0
- data/CHANGELOG.adoc +628 -45
- data/LICENSE +2 -1
- data/README-de.adoc +28 -38
- data/README-fr.adoc +30 -43
- data/README-jp.adoc +255 -201
- data/README-zh_CN.adoc +40 -44
- data/README.adoc +170 -143
- data/asciidoctor.gemspec +22 -34
- data/bin/asciidoctor +5 -4
- data/data/locale/attributes-ar.adoc +4 -3
- data/data/locale/attributes-be.adoc +23 -0
- data/data/locale/attributes-bg.adoc +4 -3
- data/data/locale/attributes-ca.adoc +6 -5
- data/data/locale/attributes-cs.adoc +4 -3
- data/data/locale/attributes-da.adoc +6 -5
- data/data/locale/attributes-de.adoc +6 -5
- data/data/locale/attributes-en.adoc +4 -4
- data/data/locale/attributes-es.adoc +6 -5
- data/data/locale/attributes-fa.adoc +4 -3
- data/data/locale/attributes-fi.adoc +4 -3
- data/data/locale/attributes-fr.adoc +8 -7
- data/data/locale/attributes-hu.adoc +4 -3
- data/data/locale/attributes-id.adoc +4 -3
- data/data/locale/attributes-it.adoc +6 -5
- data/data/locale/attributes-ja.adoc +4 -3
- data/data/locale/{attributes-kr.adoc → attributes-ko.adoc} +4 -3
- data/data/locale/attributes-nb.adoc +4 -3
- data/data/locale/attributes-nl.adoc +6 -5
- data/data/locale/attributes-nn.adoc +4 -3
- data/data/locale/attributes-pl.adoc +8 -7
- data/data/locale/attributes-pt.adoc +6 -5
- data/data/locale/attributes-pt_BR.adoc +6 -5
- data/data/locale/attributes-ro.adoc +4 -3
- data/data/locale/attributes-ru.adoc +6 -5
- data/data/locale/attributes-sr.adoc +4 -4
- data/data/locale/attributes-sr_Latn.adoc +4 -4
- data/data/locale/attributes-sv.adoc +4 -4
- data/data/locale/attributes-th.adoc +23 -0
- data/data/locale/attributes-tr.adoc +4 -3
- data/data/locale/attributes-uk.adoc +6 -5
- data/data/locale/attributes-vi.adoc +23 -0
- data/data/locale/attributes-zh_CN.adoc +4 -3
- data/data/locale/attributes-zh_TW.adoc +4 -3
- data/data/reference/syntax.adoc +296 -0
- data/data/stylesheets/asciidoctor-default.css +120 -114
- data/data/stylesheets/coderay-asciidoctor.css +15 -17
- data/lib/asciidoctor/abstract_block.rb +146 -140
- data/lib/asciidoctor/abstract_node.rb +152 -170
- data/lib/asciidoctor/attribute_list.rb +77 -89
- data/lib/asciidoctor/block.rb +29 -28
- data/lib/asciidoctor/callouts.rb +4 -2
- data/lib/asciidoctor/cli/invoker.rb +20 -24
- data/lib/asciidoctor/cli/options.rb +107 -96
- data/lib/asciidoctor/cli.rb +3 -2
- data/lib/asciidoctor/convert.rb +199 -0
- data/lib/asciidoctor/converter/composite.rb +40 -48
- data/lib/asciidoctor/converter/docbook5.rb +627 -644
- data/lib/asciidoctor/converter/html5.rb +1053 -951
- data/lib/asciidoctor/converter/manpage.rb +581 -532
- data/lib/asciidoctor/converter/template.rb +232 -271
- data/lib/asciidoctor/converter.rb +370 -185
- data/lib/asciidoctor/core_ext/float/truncate.rb +20 -0
- data/lib/asciidoctor/core_ext/hash/merge.rb +8 -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/core_ext.rb +8 -17
- data/lib/asciidoctor/document.rb +503 -461
- data/lib/asciidoctor/extensions.rb +127 -174
- data/lib/asciidoctor/helpers.rb +184 -107
- data/lib/asciidoctor/inline.rb +9 -12
- data/lib/asciidoctor/list.rb +11 -29
- data/lib/asciidoctor/load.rb +119 -0
- data/lib/asciidoctor/logging.rb +22 -17
- data/lib/asciidoctor/parser.rb +673 -719
- data/lib/asciidoctor/path_resolver.rb +48 -33
- data/lib/asciidoctor/reader.rb +383 -338
- data/lib/asciidoctor/rouge_ext.rb +39 -0
- data/lib/asciidoctor/rx.rb +723 -0
- data/lib/asciidoctor/section.rb +17 -16
- data/lib/asciidoctor/stylesheets.rb +19 -37
- data/lib/asciidoctor/substitutors.rb +926 -1022
- data/lib/asciidoctor/syntax_highlighter/coderay.rb +88 -0
- data/lib/asciidoctor/syntax_highlighter/highlightjs.rb +34 -0
- data/lib/asciidoctor/syntax_highlighter/html_pipeline.rb +10 -0
- data/lib/asciidoctor/syntax_highlighter/prettify.rb +30 -0
- data/lib/asciidoctor/syntax_highlighter/pygments.rb +157 -0
- data/lib/asciidoctor/syntax_highlighter/rouge.rb +143 -0
- data/lib/asciidoctor/syntax_highlighter.rb +253 -0
- data/lib/asciidoctor/table.rb +152 -114
- data/lib/asciidoctor/timings.rb +7 -5
- data/lib/asciidoctor/version.rb +2 -1
- data/lib/asciidoctor/writer.rb +30 -0
- data/lib/asciidoctor.rb +266 -1340
- data/man/asciidoctor.1 +49 -47
- data/man/asciidoctor.adoc +54 -45
- metadata +50 -245
- 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/block_paragraph.html.haml +0 -3
- data/test/fixtures/custom-backends/haml/html5/block_sidebar.html.haml +0 -5
- data/test/fixtures/custom-backends/haml/html5-tweaks/block_paragraph.html.haml +0 -1
- 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,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
module Asciidoctor
|
3
3
|
# Public: An abstract base class that provides state and methods for managing a
|
4
4
|
# node of AsciiDoc content. The state and methods on this class are common to
|
@@ -16,30 +16,26 @@ class AbstractNode
|
|
16
16
|
# Public: Get the Asciidoctor::Document to which this node belongs
|
17
17
|
attr_reader :document
|
18
18
|
|
19
|
-
# Public: Get/Set the id of this node
|
19
|
+
# Public: Get/Set the String id of this node
|
20
20
|
attr_accessor :id
|
21
21
|
|
22
22
|
# Public: Get the String name of this node
|
23
23
|
attr_reader :node_name
|
24
24
|
|
25
|
-
# Public: Get the
|
25
|
+
# Public: Get the AbstractBlock parent element of this node
|
26
26
|
attr_reader :parent
|
27
27
|
|
28
28
|
def initialize parent, context, opts = {}
|
29
|
+
# document is a special case, should refer to itself
|
29
30
|
if context == :document
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if parent
|
34
|
-
@document, @parent = parent.document, parent
|
35
|
-
else
|
36
|
-
@document = @parent = nil
|
37
|
-
end
|
31
|
+
@document = self
|
32
|
+
elsif parent
|
33
|
+
@document = (@parent = parent).document
|
38
34
|
end
|
39
35
|
@node_name = (@context = context).to_s
|
40
|
-
#
|
41
|
-
@attributes = (opts
|
42
|
-
@passthroughs =
|
36
|
+
# NOTE the value of the :attributes option may be nil on an Inline node
|
37
|
+
@attributes = (attrs = opts[:attributes]) ? attrs.merge : {}
|
38
|
+
@passthroughs = []
|
43
39
|
end
|
44
40
|
|
45
41
|
# Public: Returns whether this {AbstractNode} is an instance of {Block}
|
@@ -70,56 +66,48 @@ class AbstractNode
|
|
70
66
|
#
|
71
67
|
# parent - The Block to set as the parent of this Block
|
72
68
|
#
|
73
|
-
# Returns the
|
69
|
+
# Returns the the specified Block parent
|
74
70
|
def parent= parent
|
75
71
|
@parent, @document = parent, parent.document
|
76
72
|
end
|
77
73
|
|
78
|
-
# Public: Get the value of the specified attribute
|
79
|
-
#
|
80
|
-
#
|
81
|
-
# this node and return the value of the attribute if found.
|
82
|
-
# this node is
|
83
|
-
# Document node and return
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# return a Boolean indicating whether the attribute exists and, if a
|
114
|
-
# comparison value is specified, whether the value of the attribute matches
|
115
|
-
# the comparison value
|
116
|
-
def attr? name, expect_val = nil, inherit = true
|
117
|
-
name = name.to_s
|
118
|
-
# NOTE if @parent is set, it means @document is also set
|
119
|
-
if expect_val.nil?
|
120
|
-
(@attributes.key? name) || (inherit && @parent && (@document.attributes.key? name))
|
74
|
+
# Public: Get the value of the specified attribute. If the attribute is not found on this node, fallback_name is set,
|
75
|
+
# and this node is not the Document node, get the value of the specified attribute from the Document node.
|
76
|
+
#
|
77
|
+
# Look for the specified attribute in the attributes on this node and return the value of the attribute, if found.
|
78
|
+
# Otherwise, if fallback_name is set (default: same as name) and this node is not the Document node, look for that
|
79
|
+
# attribute on the Document node and return its value, if found. Otherwise, return the default value (default: nil).
|
80
|
+
#
|
81
|
+
# name - The String or Symbol name of the attribute to resolve.
|
82
|
+
# default_value - The Object value to return if the attribute is not found (default: nil).
|
83
|
+
# fallback_name - The String or Symbol of the attribute to resolve on the Document if the attribute is not found on
|
84
|
+
# this node (default: same as name).
|
85
|
+
#
|
86
|
+
# Returns the [Object] value (typically a String) of the attribute or default_value if the attribute is not found.
|
87
|
+
def attr name, default_value = nil, fallback_name = nil
|
88
|
+
@attributes[name.to_s] || (fallback_name && @parent && @document.attributes[(fallback_name == true ? name : fallback_name).to_s] || default_value)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Public: Check if the specified attribute is defined using the same logic as {#attr}, optionally performing a
|
92
|
+
# comparison with the expected value if specified.
|
93
|
+
#
|
94
|
+
# Look for the specified attribute in the attributes on this node. If not found, fallback_name is specified (default:
|
95
|
+
# same as name), and this node is not the Document node, look for that attribute on the Document node. In either case,
|
96
|
+
# if the attribute is found, and the comparison value is truthy, return whether the two values match. Otherwise,
|
97
|
+
# return whether the attribute was found.
|
98
|
+
#
|
99
|
+
# name - The String or Symbol name of the attribute to resolve.
|
100
|
+
# expected_value - The expected Object value of the attribute (default: nil).
|
101
|
+
# fallback_name - The String or Symbol of the attribute to resolve on the Document if the attribute is not found on
|
102
|
+
# this node (default: same as name).
|
103
|
+
#
|
104
|
+
# Returns a [Boolean] indicating whether the attribute exists and, if a truthy comparison value is specified, whether
|
105
|
+
# the value of the attribute matches the comparison value.
|
106
|
+
def attr? name, expected_value = nil, fallback_name = nil
|
107
|
+
if expected_value
|
108
|
+
expected_value == (@attributes[name.to_s] || (fallback_name && @parent ? @document.attributes[(fallback_name == true ? name : fallback_name).to_s] : nil))
|
121
109
|
else
|
122
|
-
|
110
|
+
(@attributes.key? name.to_s) || (fallback_name && @parent ? (@document.attributes.key? (fallback_name == true ? name : fallback_name).to_s) : false)
|
123
111
|
end
|
124
112
|
end
|
125
113
|
|
@@ -153,34 +141,32 @@ class AbstractNode
|
|
153
141
|
# enabled on the current node.
|
154
142
|
#
|
155
143
|
# Check if the option is enabled. This method simply checks to see if the
|
156
|
-
#
|
144
|
+
# <name>-option attribute is defined on the current node.
|
157
145
|
#
|
158
146
|
# name - the String or Symbol name of the option
|
159
147
|
#
|
160
148
|
# return a Boolean indicating whether the option has been specified
|
161
|
-
def option?
|
162
|
-
@attributes
|
149
|
+
def option? name
|
150
|
+
@attributes[%(#{name}-option)] ? true : false
|
163
151
|
end
|
164
152
|
|
165
153
|
# Public: Set the specified option on this node.
|
166
154
|
#
|
167
|
-
# This method sets the specified option on this node
|
168
|
-
# It will add the name to the options attribute and set the <name>-option
|
169
|
-
# attribute.
|
155
|
+
# This method sets the specified option on this node by setting the <name>-option attribute.
|
170
156
|
#
|
171
157
|
# name - the String name of the option
|
172
158
|
#
|
173
|
-
#
|
174
|
-
def set_option
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
159
|
+
# Returns nothing
|
160
|
+
def set_option name
|
161
|
+
@attributes[%(#{name}-option)] = ''
|
162
|
+
nil
|
163
|
+
end
|
164
|
+
|
165
|
+
# Public: Retrieve the Set of option names that are enabled on this node
|
166
|
+
#
|
167
|
+
# Returns a [Set] of option names
|
168
|
+
def enabled_options
|
169
|
+
::Set.new.tap {|accum| @attributes.each_key {|k| accum << (k.slice 0, k.length - 7) if k.to_s.end_with? '-option' } }
|
184
170
|
end
|
185
171
|
|
186
172
|
# Public: Update the attributes of this node with the new values in
|
@@ -189,67 +175,82 @@ class AbstractNode
|
|
189
175
|
# If an attribute already exists with the same key, it's value will
|
190
176
|
# be overwritten.
|
191
177
|
#
|
192
|
-
#
|
178
|
+
# new_attributes - A Hash of additional attributes to assign to this node.
|
193
179
|
#
|
194
|
-
# Returns
|
195
|
-
def update_attributes
|
196
|
-
@attributes.update
|
197
|
-
nil
|
180
|
+
# Returns the updated attributes [Hash] on this node.
|
181
|
+
def update_attributes new_attributes
|
182
|
+
@attributes.update new_attributes
|
198
183
|
end
|
199
184
|
|
200
|
-
# Public:
|
185
|
+
# Public: Retrieves the space-separated String role for this node.
|
186
|
+
#
|
187
|
+
# Returns the role as a space-separated [String].
|
201
188
|
def role
|
202
|
-
@attributes['role']
|
189
|
+
@attributes['role']
|
203
190
|
end
|
204
191
|
|
205
|
-
# Public:
|
192
|
+
# Public: Retrieves the String role names for this node as an Array.
|
206
193
|
#
|
207
|
-
# Returns the role names as
|
194
|
+
# Returns the role names as a String [Array], which is empty if the role attribute is absent on this node.
|
208
195
|
def roles
|
209
|
-
(val = @attributes['role']
|
196
|
+
(val = @attributes['role']) ? val.split : []
|
210
197
|
end
|
211
198
|
|
212
|
-
# Public:
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
199
|
+
# Public: Checks if the role attribute is set on this node and, if an expected value is given, whether the
|
200
|
+
# space-separated role matches that value.
|
201
|
+
#
|
202
|
+
# expected_value - The expected String value of the role (optional, default: nil)
|
203
|
+
#
|
204
|
+
# Returns a [Boolean] indicating whether the role attribute is set on this node and, if an expected value is given,
|
205
|
+
# whether the space-separated role matches that value.
|
206
|
+
def role? expected_value = nil
|
207
|
+
expected_value ? expected_value == @attributes['role'] : (@attributes.key? 'role')
|
219
208
|
end
|
220
209
|
|
221
|
-
# Public:
|
222
|
-
#
|
223
|
-
|
210
|
+
# Public: Checks if the specified role is present in the list of roles for this node.
|
211
|
+
#
|
212
|
+
# name - The String name of the role to find.
|
213
|
+
#
|
214
|
+
# Returns a [Boolean] indicating whether this node has the specified role.
|
215
|
+
def has_role? name
|
224
216
|
# NOTE center + include? is faster than split + include?
|
225
|
-
(val = @attributes['role']
|
217
|
+
(val = @attributes['role']) ? (%( #{val} ).include? %( #{name} )) : false
|
226
218
|
end
|
227
219
|
|
228
|
-
# Public:
|
220
|
+
# Public: Sets the value of the role attribute on this node.
|
229
221
|
#
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
222
|
+
# names - A single role name, a space-separated String of role names, or an Array of role names
|
223
|
+
#
|
224
|
+
# Returns the specified String role name or Array of role names
|
225
|
+
def role= names
|
226
|
+
@attributes['role'] = (::Array === names) ? (names.join ' ') : names
|
227
|
+
end
|
228
|
+
|
229
|
+
# Public: Adds the given role directly to this node.
|
230
|
+
#
|
231
|
+
# Returns a [Boolean] indicating whether the role was added.
|
232
|
+
def add_role name
|
233
|
+
if (val = @attributes['role'])
|
234
|
+
# NOTE center + include? is faster than split + include?
|
235
|
+
if %( #{val} ).include? %( #{name} )
|
236
|
+
false
|
237
|
+
else
|
238
|
+
@attributes['role'] = %(#{val} #{name})
|
239
|
+
true
|
240
|
+
end
|
238
241
|
else
|
239
|
-
@attributes['role'] =
|
242
|
+
@attributes['role'] = name
|
240
243
|
true
|
241
244
|
end
|
242
245
|
end
|
243
246
|
|
244
|
-
# Public:
|
247
|
+
# Public: Removes the given role directly from this node.
|
245
248
|
#
|
246
|
-
# Returns a Boolean indicating whether the role was removed.
|
247
|
-
def remove_role
|
248
|
-
if (val = @attributes['role']).
|
249
|
-
false
|
250
|
-
elsif (val = val.split).delete name
|
249
|
+
# Returns a [Boolean] indicating whether the role was removed.
|
250
|
+
def remove_role name
|
251
|
+
if (val = @attributes['role']) && ((val = val.split).delete name)
|
251
252
|
if val.empty?
|
252
|
-
@attributes.delete
|
253
|
+
@attributes.delete 'role'
|
253
254
|
else
|
254
255
|
@attributes['role'] = val.join ' '
|
255
256
|
end
|
@@ -273,12 +274,12 @@ class AbstractNode
|
|
273
274
|
# specified icon name.
|
274
275
|
#
|
275
276
|
# If the 'icon' attribute is set on this block, the name is ignored and the
|
276
|
-
# value of this attribute is used as the
|
277
|
+
# value of this attribute is used as the target image path. Otherwise,
|
277
278
|
# construct a target image path by concatenating the value of the 'iconsdir'
|
278
|
-
# attribute, the icon name and the value of the 'icontype' attribute
|
279
|
+
# attribute, the icon name, and the value of the 'icontype' attribute
|
279
280
|
# (defaulting to 'png').
|
280
281
|
#
|
281
|
-
# The target image path is then passed through the #image_uri() method.
|
282
|
+
# The target image path is then passed through the #image_uri() method. If
|
282
283
|
# the 'data-uri' attribute is set on the document, the image will be
|
283
284
|
# safely converted to a data URI.
|
284
285
|
#
|
@@ -289,10 +290,9 @@ class AbstractNode
|
|
289
290
|
# Returns A String reference or data URI for an icon image
|
290
291
|
def icon_uri name
|
291
292
|
if attr? 'icon'
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
end
|
293
|
+
icon = attr 'icon'
|
294
|
+
# QUESTION should we be adding the extension if the icon is an absolute URI?
|
295
|
+
icon = %(#{icon}.#{@document.attr 'icontype', 'png'}) unless Helpers.extname? icon
|
296
296
|
else
|
297
297
|
icon = %(#{name}.#{@document.attr 'icontype', 'png'})
|
298
298
|
end
|
@@ -320,14 +320,10 @@ class AbstractNode
|
|
320
320
|
# Returns A String reference or data URI for the target image
|
321
321
|
def image_uri(target_image, asset_dir_key = 'imagesdir')
|
322
322
|
if (doc = @document).safe < SafeMode::SECURE && (doc.attr? 'data-uri')
|
323
|
-
if ((Helpers.uriish? target_image) && (target_image =
|
323
|
+
if ((Helpers.uriish? target_image) && (target_image = Helpers.encode_spaces_in_uri target_image)) ||
|
324
324
|
(asset_dir_key && (images_base = doc.attr asset_dir_key) && (Helpers.uriish? images_base) &&
|
325
325
|
(target_image = normalize_web_path target_image, images_base, false))
|
326
|
-
|
327
|
-
generate_data_uri_from_uri target_image, (doc.attr? 'cache-uri')
|
328
|
-
else
|
329
|
-
target_image
|
330
|
-
end
|
326
|
+
(doc.attr? 'allow-uri-read') ? (generate_data_uri_from_uri target_image, (doc.attr? 'cache-uri')) : target_image
|
331
327
|
else
|
332
328
|
generate_data_uri target_image, asset_dir_key
|
333
329
|
end
|
@@ -367,18 +363,21 @@ class AbstractNode
|
|
367
363
|
#
|
368
364
|
# Returns A String data URI containing the content of the target image
|
369
365
|
def generate_data_uri(target_image, asset_dir_key = nil)
|
370
|
-
ext =
|
371
|
-
|
372
|
-
|
366
|
+
if (ext = Helpers.extname target_image, nil)
|
367
|
+
mimetype = ext == '.svg' ? 'image/svg+xml' : %(image/#{ext.slice 1, ext.length})
|
368
|
+
else
|
369
|
+
mimetype = 'application/octet-stream'
|
370
|
+
end
|
371
|
+
|
373
372
|
if asset_dir_key
|
374
|
-
image_path = normalize_system_path(target_image, @document.attr(asset_dir_key), nil, :
|
373
|
+
image_path = normalize_system_path(target_image, @document.attr(asset_dir_key), nil, target_name: 'image')
|
375
374
|
else
|
376
375
|
image_path = normalize_system_path(target_image)
|
377
376
|
end
|
378
377
|
|
379
378
|
if ::File.readable? image_path
|
380
379
|
# NOTE base64 is autoloaded by reference to ::Base64
|
381
|
-
%(data:#{mimetype};base64,#{::Base64.strict_encode64 ::
|
380
|
+
%(data:#{mimetype};base64,#{::Base64.strict_encode64 ::File.binread image_path})
|
382
381
|
else
|
383
382
|
logger.warn %(image to embed not found or not readable: #{image_path})
|
384
383
|
%(data:#{mimetype};base64,)
|
@@ -404,17 +403,13 @@ class AbstractNode
|
|
404
403
|
# caching requires the open-uri-cached gem to be installed
|
405
404
|
# processing will be automatically aborted if these libraries can't be opened
|
406
405
|
Helpers.require_library 'open-uri/cached', 'open-uri-cached'
|
407
|
-
elsif
|
406
|
+
elsif !RUBY_ENGINE_OPAL
|
408
407
|
# autoload open-uri
|
409
408
|
::OpenURI
|
410
409
|
end
|
411
410
|
|
412
411
|
begin
|
413
|
-
mimetype =
|
414
|
-
bindata = open image_uri, 'rb' do |f|
|
415
|
-
mimetype = f.content_type
|
416
|
-
f.read
|
417
|
-
end
|
412
|
+
mimetype, bindata = ::OpenURI.open_uri(image_uri, URI_READ_MODE) {|f| [f.content_type, f.read] }
|
418
413
|
# NOTE base64 is autoloaded by reference to ::Base64
|
419
414
|
%(data:#{mimetype};base64,#{::Base64.strict_encode64 bindata})
|
420
415
|
rescue
|
@@ -432,8 +427,7 @@ class AbstractNode
|
|
432
427
|
# Delegates to normalize_system_path, with the start path set to the value of
|
433
428
|
# the base_dir instance variable on the Document object.
|
434
429
|
def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true)
|
435
|
-
normalize_system_path(asset_ref, @document.base_dir, nil,
|
436
|
-
:target_name => asset_name, :recover => autocorrect)
|
430
|
+
normalize_system_path(asset_ref, @document.base_dir, nil, target_name: asset_name, recover: autocorrect)
|
437
431
|
end
|
438
432
|
|
439
433
|
# Public: Resolve and normalize a secure path from the target and start paths
|
@@ -469,8 +463,8 @@ class AbstractNode
|
|
469
463
|
start = doc.base_dir
|
470
464
|
end
|
471
465
|
else
|
472
|
-
start
|
473
|
-
jail
|
466
|
+
start ||= doc.base_dir
|
467
|
+
jail ||= doc.base_dir
|
474
468
|
end
|
475
469
|
doc.path_resolver.system_path target, start, jail, opts
|
476
470
|
end
|
@@ -486,7 +480,7 @@ class AbstractNode
|
|
486
480
|
# Returns the resolved [String] path
|
487
481
|
def normalize_web_path(target, start = nil, preserve_uri_target = true)
|
488
482
|
if preserve_uri_target && (Helpers.uriish? target)
|
489
|
-
|
483
|
+
Helpers.encode_spaces_in_uri target
|
490
484
|
else
|
491
485
|
@document.path_resolver.web_path target, start
|
492
486
|
end
|
@@ -507,15 +501,10 @@ class AbstractNode
|
|
507
501
|
# if the file does not exist.
|
508
502
|
def read_asset path, opts = {}
|
509
503
|
# remap opts for backwards compatibility
|
510
|
-
opts = { :
|
504
|
+
opts = { warn_on_failure: (opts != false) } unless ::Hash === opts
|
511
505
|
if ::File.readable? path
|
512
|
-
if
|
513
|
-
|
514
|
-
(Helpers.normalize_lines_array ::File.open(path, 'rb') {|f| f.each_line.to_a }).join LF
|
515
|
-
else
|
516
|
-
# QUESTION should we chomp or rstrip content?
|
517
|
-
::IO.read path
|
518
|
-
end
|
506
|
+
# QUESTION should we chomp content if normalize is false?
|
507
|
+
opts[:normalize] ? ((Helpers.prepare_source_string ::File.read path, mode: FILE_READ_MODE).join LF) : (::File.read path, mode: FILE_READ_MODE)
|
519
508
|
elsif opts[:warn_on_failure]
|
520
509
|
logger.warn %(#{(attr 'docfile') || '<stdin>'}: #{opts[:label] || 'file'} does not exist or cannot be read: #{path})
|
521
510
|
nil
|
@@ -535,6 +524,7 @@ class AbstractNode
|
|
535
524
|
# * :normalize a Boolean that indicates whether the data should be normalized (default: false)
|
536
525
|
# * :start the String relative base path to use when resolving the target (default: nil)
|
537
526
|
# * :warn_on_failure a Boolean that indicates whether warnings are issued if the target cannot be read (default: true)
|
527
|
+
# * :warn_if_empty a Boolean that indicates whether a warning is issued if contents of target is empty (default: false)
|
538
528
|
# Returns the contents of the resolved target or nil if the resolved target cannot be read
|
539
529
|
# --
|
540
530
|
# TODO refactor other methods in this class to use this method were possible (repurposing if necessary)
|
@@ -546,37 +536,29 @@ class AbstractNode
|
|
546
536
|
Helpers.require_library 'open-uri/cached', 'open-uri-cached' if doc.attr? 'cache-uri'
|
547
537
|
begin
|
548
538
|
if opts[:normalize]
|
549
|
-
|
550
|
-
(Helpers.normalize_lines_array ::OpenURI.open_uri(target) {|f| f.each_line.to_a }).join LF
|
539
|
+
contents = (Helpers.prepare_source_string ::OpenURI.open_uri(target, URI_READ_MODE) {|f| f.read }).join LF
|
551
540
|
else
|
552
|
-
::OpenURI.open_uri(target) {|f| f.read }
|
541
|
+
contents = ::OpenURI.open_uri(target, URI_READ_MODE) {|f| f.read }
|
553
542
|
end
|
554
543
|
rescue
|
555
544
|
logger.warn %(could not retrieve contents of #{opts[:label] || 'asset'} at URI: #{target}) if opts.fetch :warn_on_failure, true
|
556
|
-
return
|
557
545
|
end
|
558
|
-
|
559
|
-
logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled))
|
560
|
-
return
|
546
|
+
elsif opts.fetch :warn_on_failure, true
|
547
|
+
logger.warn %(cannot retrieve contents of #{opts[:label] || 'asset'} at URI: #{target} (allow-uri-read attribute not enabled))
|
561
548
|
end
|
562
549
|
else
|
563
|
-
target = normalize_system_path target, opts[:start], nil, :
|
564
|
-
read_asset target, :
|
550
|
+
target = normalize_system_path target, opts[:start], nil, target_name: (opts[:label] || 'asset')
|
551
|
+
contents = read_asset target, normalize: opts[:normalize], warn_on_failure: (opts.fetch :warn_on_failure, true), label: opts[:label]
|
565
552
|
end
|
553
|
+
logger.warn %(contents of #{opts[:label] || 'asset'} is empty: #{target}) if contents && opts[:warn_if_empty] && contents.empty?
|
554
|
+
contents
|
566
555
|
end
|
567
556
|
|
568
|
-
#
|
569
|
-
#
|
570
|
-
# str - the String to encode
|
571
|
-
#
|
572
|
-
# Returns the String with all spaces replaced with %20.
|
573
|
-
def uri_encode_spaces str
|
574
|
-
(str.include? ' ') ? (str.gsub ' ', '%20') : str
|
575
|
-
end
|
576
|
-
|
577
|
-
# Public: Check whether the specified String is a URI by
|
557
|
+
# Deprecated: Check whether the specified String is a URI by
|
578
558
|
# matching it against the Asciidoctor::UriSniffRx regex.
|
579
559
|
#
|
560
|
+
# In use by Asciidoctor PDF
|
561
|
+
#
|
580
562
|
# @deprecated Use Helpers.uriish? instead
|
581
563
|
def is_uri? str
|
582
564
|
Helpers.uriish? str
|