lib/asciidoctor/helpers.rb in asciidoctor-1.5.2 vs lib/asciidoctor/helpers.rb in asciidoctor-1.5.3

- old
+ new

@@ -3,28 +3,43 @@ module Helpers # Internal: Require the specified library using Kernel#require. # # Attempts to load the library specified in the first argument using the # Kernel#require. Rescues the LoadError if the library is not available and - # passes a message to Kernel#fail to communicate to the user that processing - # is being aborted. If a gem_name is specified, the failure message - # communicates that a required gem is not installed. + # passes a message to Kernel#fail if on_failure is :abort or Kernel#warn if + # on_failure is :warn to communicate to the user that processing is being + # aborted or functionality is disabled, respectively. If a gem_name is + # specified, the message communicates that a required gem is not installed. # - # name - the String name of the library to require. - # gem - a Boolean that indicates whether this library is provided by a RubyGem, - # or the String name of the RubyGem if it differs from the library name - # (default: true) + # name - the String name of the library to require. + # gem_name - a Boolean that indicates whether this library is provided by a RubyGem, + # or the String name of the RubyGem if it differs from the library name + # (default: true) + # on_failure - a Symbol that indicates how to handle a load failure (:abort, :warn, :ignore) (default: :abort) # - # returns the return value of Kernel#require if the library is available, - # otherwise Kernel#fail is called with an appropriate message. - def self.require_library name, gem = true + # returns The return value of Kernel#require if the library is available and can be, or was previously, loaded. + # Otherwise, Kernel#fail is called with an appropriate message if on_failure is :abort. + # Otherwise, Kernel#warn is called with an appropriate message and nil returned if on_failure is :warn. + # Otherwise, nil is returned. + def self.require_library name, gem_name = true, on_failure = :abort require name rescue ::LoadError => e - if gem - fail %(asciidoctor: FAILED: required gem '#{gem == true ? name : gem}' is not installed. Processing aborted.) + if gem_name + gem_name = name if gem_name == true + case on_failure + when :abort + fail %(asciidoctor: FAILED: required gem '#{gem_name}' is not installed. Processing aborted.) + when :warn + warn %(asciidoctor: WARNING: optional gem '#{gem_name}' is not installed. Functionality disabled.) + end else - fail %(asciidoctor: FAILED: #{e.message.chomp '.'}. Processing aborted.) + case on_failure + when :abort + fail %(asciidoctor: FAILED: #{e.message.chomp '.'}. Processing aborted.) + when :warn + warn %(asciidoctor: WARNING: #{e.message.chomp '.'}. Functionality disabled.) + end end end # Public: Normalize the data to prepare for parsing # @@ -107,10 +122,34 @@ end end data.each_line.map {|line| line.rstrip } end + # Public: Efficiently checks whether the specified String resembles a URI + # + # Uses the Asciidoctor::UriSniffRx regex to check whether the String begins + # with a URI prefix (e.g., http://). No validation of the URI is performed. + # + # str - the String to check + # + # returns true if the String is a URI, false if it is not + def self.uriish? str + (str.include? ':') && str =~ UriSniffRx + end + + # Public: Efficiently retrieves the URI prefix of the specified String + # + # Uses the Asciidoctor::UriSniffRx regex to match the URI prefix in the + # specified String (e.g., http://), if present. + # + # str - the String to check + # + # returns the string URI prefix if the string is a URI, otherwise nil + def self.uri_prefix str + (str.include? ':') && str =~ UriSniffRx ? $& : nil + end + # Matches the characters in a URI to encode REGEXP_ENCODE_URI_CHARS = /[^\w\-.!~*';:@=+$,()\[\]]/ # Public: Encode a string for inclusion in a URI # @@ -132,11 +171,29 @@ # Helpers.rootname('part1/chapter1.adoc') # # => "part1/chapter1" # # Returns the String filename with the file extension removed def self.rootname(file_name) - # alternatively, this could be written as ::File.basename file_name, ((::File.extname file_name) || '') (ext = ::File.extname(file_name)).empty? ? file_name : file_name[0...-ext.length] + end + + # Public: Retrieves the basename of the filename, optionally removing the extension, if present + # + # file_name - The String file name to process + # drop_extname - A Boolean flag indicating whether to drop the extension (default: false) + # + # Examples + # + # Helpers.basename('images/tiger.png', true) + # # => "tiger" + # + # Returns the String filename with leading directories removed and, if specified, the extension removed + def self.basename(file_name, drop_extname = false) + if drop_extname + ::File.basename file_name, ((::File.extname file_name) || '') + else + ::File.basename file_name + end end def self.mkdir_p(dir) unless ::File.directory? dir parent_dir = ::File.dirname(dir)