lib/asciidoctor/abstract_node.rb in asciidoctor-0.1.0 vs lib/asciidoctor/abstract_node.rb in asciidoctor-0.1.1
- old
+ new
@@ -1,11 +1,12 @@
+module Asciidoctor
# Public: An abstract base class that provides state and methods for managing a
# node of AsciiDoc content. The state and methods on this class are comment to
# all content segments in an AsciiDoc document.
-class Asciidoctor::AbstractNode
+class AbstractNode
- include Asciidoctor::Substituters
+ include Substituters
# Public: Get the element which is the parent of this node
attr_reader :parent
# Public: Get the Asciidoctor::Document to which this node belongs
@@ -22,34 +23,76 @@
def initialize(parent, context)
@parent = (context != :document ? parent : nil)
if !parent.nil?
- @document = parent.is_a?(Asciidoctor::Document) ? parent : parent.document
+ @document = parent.is_a?(Document) ? parent : parent.document
else
@document = nil
end
@context = context
@attributes = {}
@passthroughs = []
end
+ # Public: Get the value of the specified attribute
+ #
+ # Get the value for the specified attribute. First look in the attributes on
+ # this node and return the value of the attribute if found. Otherwise, if
+ # this node is a child of the Document node, look in the attributes of the
+ # Document node and return the value of the attribute if found. Otherwise,
+ # return the default value, which defaults to nil.
+ #
+ # name - the name of the attribute to lookup as a String or Symbol
+ # default - the value to return if the attribute is not found (default: nil)
+ #
+ # return the value of the attribute or the default value if the attribute
+ # is not found in the attributes of this node or the document node
def attr(name, default = nil)
+ name = name.to_s if name.is_a?(Symbol)
if self == @document
- default.nil? ? @attributes[name.to_s] : @attributes.fetch(name.to_s, default)
+ default.nil? ? @attributes[name] : @attributes.fetch(name, default)
else
- default.nil? ? @attributes.fetch(name.to_s, @document.attr(name)) :
- @attributes.fetch(name.to_s, @document.attr(name, default))
+ default.nil? ? @attributes.fetch(name, @document.attr(name)) :
+ @attributes.fetch(name, @document.attr(name, default))
end
end
- def attr?(name)
- if self == @document
- @attributes.has_key? name.to_s
+ # Public: Check if the attribute is defined, optionally performing a
+ # comparison of its value
+ #
+ # Check if the attribute is defined. First look in the attributes on this
+ # node. If not found, and this node is a child of the Document node, look in
+ # the attributes of the Document node. If the attribute is found and a
+ # comparison value is specified, return whether the two values match.
+ # Otherwise, return whether the attribute was found.
+ #
+ # name - the name of the attribute to lookup as a String or Symbol
+ # expect - the expected value of the attribute (default: nil)
+ #
+ # return a Boolean indicating whether the attribute exists and, if a
+ # comparison value is specified, whether the value of the attribute matches
+ # the comparison value
+ def attr?(name, expect = nil)
+ name = name.to_s if name.is_a?(Symbol)
+ if expect.nil?
+ if @attributes.has_key? name
+ true
+ elsif self != @document
+ @document.attributes.has_key? name
+ else
+ false
+ end
else
- @attributes.has_key?(name.to_s) || @document.attr?(name)
+ if @attributes.has_key? name
+ @attributes[name] == expect
+ elsif self != @document && @document.attributes.has_key?(name)
+ @document.attributes[name] == expect
+ else
+ false
+ end
end
end
# Public: Get the execution context of this object (via Kernel#binding).
#
@@ -117,10 +160,12 @@
end
end
# Public: Construct a reference or data URI to the target image.
#
+ # If the target image is a URI reference, then leave it untouched.
+ #
# The target image is resolved relative to the directory retrieved from the
# specified attribute key, if provided.
#
# If the 'data-uri' attribute is set on the document, and the safe mode level
# is less than SafeMode::SECURE, the image will be safely converted to a data URI
@@ -133,11 +178,13 @@
# asset_dir_key - The String attribute key used to lookup the directory where
# the image is located (default: 'imagesdir')
#
# Returns A String reference or data URI for the target image
def image_uri(target_image, asset_dir_key = 'imagesdir')
- if @document.safe < Asciidoctor::SafeMode::SECURE && @document.attr?('data-uri')
+ if target_image.include?(':') && target_image.match(Asciidoctor::REGEXP[:uri_sniff])
+ target_image
+ elsif @document.safe < Asciidoctor::SafeMode::SECURE && @document.attr?('data-uri')
generate_data_uri(target_image, asset_dir_key)
elsif asset_dir_key && attr?(asset_dir_key)
File.join(@document.attr(asset_dir_key), target_image)
else
target_image
@@ -155,11 +202,11 @@
# asset_dir_key - The String attribute key used to lookup the directory where
# the image is located (default: nil)
#
# Returns A String data URI containing the content of the target image
def generate_data_uri(target_image, asset_dir_key = nil)
- Asciidoctor.require_library 'base64'
+ Helpers.require_library 'base64'
mimetype = 'image/' + File.extname(target_image)[1..-1]
if asset_dir_key
image_path = File.join(normalize_asset_path(@document.attr(asset_dir_key, '.'), asset_dir_key), target_image)
else
@@ -223,26 +270,26 @@
# TODO this method is missing a coordinate; it should be able to resolve
# both the directory reference and the path to an asset in it; callers
# of this method are still doing a File.join to finish the task
def normalize_asset_path(asset_ref, asset_name = 'path', autocorrect = true)
# TODO we may use pathname enough to make it a top-level require
- Asciidoctor.require_library 'pathname'
+ Helpers.require_library 'pathname'
input_path = @document.base_dir
asset_path = Pathname.new(asset_ref)
if asset_path.relative?
asset_path = File.expand_path(File.join(input_path, asset_ref))
else
asset_path = asset_path.cleanpath.to_s
end
- if @document.safe >= Asciidoctor::SafeMode::SAFE
+ if @document.safe >= SafeMode::SAFE
relative_asset_path = Pathname.new(asset_path).relative_path_from(Pathname.new(input_path)).to_s
if relative_asset_path.start_with?('..')
if autocorrect
- puts 'asciidoctor: WARNING: ' + asset_name + ' has illegal reference to ancestor of base directory'
+ puts "asciidoctor: WARNING: #{asset_name} has illegal reference to ancestor of base directory"
else
raise SecurityError, "#{asset_name} has reference to path outside of base directory, disallowed in safe mode: #{asset_path}"
end
relative_asset_path.sub!(/^(?:\.\.\/)*/, '')
# just to be absolutely sure ;)
@@ -254,6 +301,7 @@
end
asset_path
end
+end
end