lib/asciidoctor/block.rb in asciidoctor-1.5.1 vs lib/asciidoctor/block.rb in asciidoctor-1.5.2

- old
+ new

@@ -1,16 +1,17 @@ +# encoding: UTF-8 module Asciidoctor # Public: Methods for managing blocks of Asciidoc content in a section. # # Examples # # block = Asciidoctor::Block.new(parent, :paragraph, :source => '_This_ is a <test>') # block.content # => "<em>This</em> is a &lt;test&gt;" class Block < AbstractBlock - DEFAULT_CONTENT_MODEL = ::Hash.new(:simple).merge({ + DEFAULT_CONTENT_MODEL = { # TODO should probably fill in all known blocks :audio => :empty, :image => :empty, :listing => :verbatim, :literal => :verbatim, @@ -18,11 +19,12 @@ :open => :compound, :page_break => :empty, :pass => :raw, :thematic_break => :empty, :video => :empty - }) + } + DEFAULT_CONTENT_MODEL.default = :simple # Public: Create alias for context to be consistent w/ AsciiDoc alias :blockname :context # Public: Get/Set the original Array content for this block, if applicable @@ -35,28 +37,59 @@ # opts - a Hash of options to customize block initialization: (default: {}) # * :content_model indicates whether blocks can be nested in this Block (:compound), otherwise # how the lines should be processed (:simple, :verbatim, :raw, :empty). (default: :simple) # * :attributes a Hash of attributes (key/value pairs) to assign to this Block. (default: {}) # * :source a String or Array of raw source for this Block. (default: nil) + # + # IMPORTANT: If you don't specify the `:subs` option, you must explicitly call + # the `lock_in_subs` method to resolve and assign the substitutions to this + # block (which are resolved from the `subs` attribute, if specified, or the + # default substitutions based on this block's context). If you want to use the + # default subs for a block, pass the option `:subs => :default`. You can + # override the default subs using the `:default_subs` option. #-- # QUESTION should we store source_data as lines for blocks that have compound content models? def initialize parent, context, opts = {} super @content_model = opts[:content_model] || DEFAULT_CONTENT_MODEL[context] - if opts.has_key? :subs - # FIXME this is a bit funky - # we have to be defensive to avoid lock_in_subs wiping out the override - if !(subs = opts[:subs]) || (subs.is_a? ::Array) - @subs = subs || [] - @default_subs = @subs.dup - @attributes.delete('subs') + if opts.key? :subs + # FIXME feels funky; we have to be defensive to get lock_in_subs to honor override + # FIXME does not resolve substitution groups inside Array (e.g., [:normal]) + if (subs = opts[:subs]) + # e.g., :subs => :defult + # subs attribute is honored; falls back to opts[:default_subs], then built-in defaults based on context + if subs == :default + @default_subs = opts[:default_subs] + # e.g., :subs => [:quotes] + # subs attribute is not honored + elsif ::Array === subs + @default_subs = subs.dup + @attributes.delete 'subs' + # e.g., :subs => :normal or :subs => 'normal' + # subs attribute is not honored + else + @default_subs = nil + # interpolation is the fastest way to dup subs as a string + @attributes['subs'] = %(#{subs}) + end + # resolve the subs eagerly only if subs option is specified + lock_in_subs + # e.g., :subs => nil else - @attributes['subs'] = %(#{subs}) + @subs = [] + # prevent subs from being resolved + @default_subs = [] + @attributes.delete 'subs' end + # defer subs resolution; subs attribute is honored + else + @subs = [] + # QUESTION should we honor :default_subs option (i.e., @default_subs = opts[:default_subs])? + @default_subs = nil end - if !(raw_source = opts[:source]) + if (raw_source = opts[:source]).nil_or_empty? @lines = [] - elsif raw_source.is_a? ::String + elsif ::String === raw_source @lines = Helpers.normalize_lines_from_string raw_source else @lines = raw_source.dup end end