"Fossies" - the Fresh Open Source Software Archive

Member "asciidoctor-2.0.10/lib/asciidoctor/block.rb" (1 Jun 2019, 5642 Bytes) of package /linux/www/asciidoctor-2.0.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 # frozen_string_literal: true
    2 module Asciidoctor
    3 # Public: Methods for managing AsciiDoc content blocks.
    4 #
    5 # Examples
    6 #
    7 #   block = Asciidoctor::Block.new(parent, :paragraph, source: '_This_ is a <test>')
    8 #   block.content
    9 #   => "<em>This</em> is a &lt;test&gt;"
   10 class Block < AbstractBlock
   11 
   12   (DEFAULT_CONTENT_MODEL = {
   13     # TODO should probably fill in all known blocks
   14     audio: :empty,
   15     image: :empty,
   16     listing: :verbatim,
   17     literal: :verbatim,
   18     stem: :raw,
   19     open: :compound,
   20     page_break: :empty,
   21     pass: :raw,
   22     thematic_break: :empty,
   23     video: :empty,
   24   }).default = :simple
   25 
   26   # Public: Create alias for context to be consistent w/ AsciiDoc
   27   alias blockname context
   28 
   29   # Public: Get/Set the original Array content for this block, if applicable
   30   attr_accessor :lines
   31 
   32   # Public: Initialize an Asciidoctor::Block object.
   33   #
   34   # parent        - The parent AbstractBlock with a compound content model to which this Block will be appended.
   35   # context       - The Symbol context name for the type of content (e.g., :paragraph).
   36   # opts          - a Hash of options to customize block initialization: (default: {})
   37   #                 * :content_model indicates whether blocks can be nested in this Block (:compound), otherwise
   38   #                     how the lines should be processed (:simple, :verbatim, :raw, :empty). (default: :simple)
   39   #                 * :attributes a Hash of attributes (key/value pairs) to assign to this Block. (default: {})
   40   #                 * :source a String or Array of raw source for this Block. (default: nil)
   41   #
   42   # IMPORTANT: If you don't specify the `:subs` option, you must explicitly call
   43   # the `commit_subs` method to resolve and assign the substitutions to this
   44   # block (which are resolved from the `subs` attribute, if specified, or the
   45   # default substitutions based on this block's context). If you want to use the
   46   # default subs for a block, pass the option `subs: :default`. You can
   47   # override the default subs using the `:default_subs` option.
   48   #--
   49   # QUESTION should we store source_data as lines for blocks that have compound content models?
   50   def initialize parent, context, opts = {}
   51     super
   52     @content_model = opts[:content_model] || DEFAULT_CONTENT_MODEL[context]
   53     if opts.key? :subs
   54       # FIXME feels funky; we have to be defensive to get commit_subs to honor override
   55       # FIXME does not resolve substitution groups inside Array (e.g., [:normal])
   56       if (subs = opts[:subs])
   57         # e.g., subs: :defult
   58         # subs attribute is honored; falls back to opts[:default_subs], then built-in defaults based on context
   59         if subs == :default
   60           @default_subs = opts[:default_subs]
   61         # e.g., subs: [:quotes]
   62         # subs attribute is not honored
   63         elsif ::Array === subs
   64           @default_subs = subs.drop 0
   65           @attributes.delete 'subs'
   66         # e.g., subs: :normal or subs: 'normal'
   67         # subs attribute is not honored
   68         else
   69           @default_subs = nil
   70           # interpolation is the fastest way to dup subs as a string
   71           @attributes['subs'] = %(#{subs})
   72         end
   73         # resolve the subs eagerly only if subs option is specified
   74         # QUESTION should we skip subsequent calls to commit_subs?
   75         commit_subs
   76       # e.g., subs: nil
   77       else
   78         # NOTE @subs is initialized as empty array by super constructor
   79         # prevent subs from being resolved
   80         @default_subs = []
   81         @attributes.delete 'subs'
   82       end
   83     # defer subs resolution; subs attribute is honored
   84     else
   85       # NOTE @subs is initialized as empty array by super constructor
   86       # QUESTION should we honor :default_subs option (i.e., @default_subs = opts[:default_subs])?
   87       @default_subs = nil
   88     end
   89     if (raw_source = opts[:source]).nil_or_empty?
   90       @lines = []
   91     elsif ::String === raw_source
   92       @lines = Helpers.prepare_source_string raw_source
   93     else
   94       @lines = raw_source.drop 0
   95     end
   96   end
   97 
   98   # Public: Get the converted result of the child blocks by converting the
   99   # children appropriate to content model that this block supports.
  100   #
  101   # Examples
  102   #
  103   #   doc = Asciidoctor::Document.new
  104   #   block = Asciidoctor::Block.new(doc, :paragraph,
  105   #       source: '_This_ is what happens when you <meet> a stranger in the <alps>!')
  106   #   block.content
  107   #   => "<em>This</em> is what happens when you &lt;meet&gt; a stranger in the &lt;alps&gt;!"
  108   def content
  109     case @content_model
  110     when :compound
  111       super
  112     when :simple
  113       apply_subs((@lines.join LF), @subs)
  114     when :verbatim, :raw
  115       # QUESTION could we use strip here instead of popping empty lines?
  116       # maybe apply_subs can know how to strip whitespace?
  117       result = apply_subs @lines, @subs
  118       if result.size < 2
  119         result[0]
  120       else
  121         result.shift while (first = result[0]) && first.rstrip.empty?
  122         result.pop while (last = result[-1]) && last.rstrip.empty?
  123         result.join LF
  124       end
  125     else
  126       logger.warn %(Unknown content model '#{@content_model}' for block: #{to_s}) unless @content_model == :empty
  127       nil
  128     end
  129   end
  130 
  131   # Public: Returns the preprocessed source of this block
  132   #
  133   # Returns the a String containing the lines joined together or empty string
  134   # if there are no lines
  135   def source
  136     @lines.join LF
  137   end
  138 
  139   def to_s
  140     content_summary = @content_model == :compound ? %(blocks: #{@blocks.size}) : %(lines: #{@lines.size})
  141     %(#<#{self.class}@#{object_id} {context: #{@context.inspect}, content_model: #{@content_model.inspect}, style: #{@style.inspect}, #{content_summary}}>)
  142   end
  143 end
  144 end