class Asciidoctor::AbstractBlock

Attributes

blocks[R]

Public: Get the Array of {AbstractBlock} child blocks for this block. Only applies if content model is :compound.

caption[W]

Public: Set the caption for this block.

content_model[RW]

Public: Describes the type of content this block accepts and how it should be converted. Acceptable values are:

  • :compound - this block contains other blocks

  • :simple - this block holds a paragraph of prose that receives normal substitutions

  • :verbatim - this block holds verbatim text (displayed “as is”) that receives verbatim substitutions

  • :raw - this block holds unprocessed content passed directly to the output with no substitutions applied

  • :empty - this block has no content

level[RW]

Public: Set the Integer level of this {Section} or the level of the Section to which this {AbstractBlock} belongs.

numeral[RW]

Public: Get/Set the String numeral of this block (if section, relative to parent, otherwise absolute). Only assigned to section if automatic section numbering is enabled. Only assigned to formal block (block with title) if corresponding caption attribute is present.

source_location[RW]

Public: Gets/Sets the location in the AsciiDoc source where this block begins.

style[RW]

Public: Get/Set the String style (block type qualifier) for this block.

subs[R]

Public: Substitutions to be applied to content in this block.

Public Class Methods

new(parent, context, opts = {}) click to toggle source
Calls superclass method
# File lib/asciidoctor/abstract_block.rb, line 35
def initialize parent, context, opts = {}
  super
  @content_model = :compound
  @blocks = []
  @subs = []
  @id = @title = @caption = @numeral = @style = @default_subs = @source_location = nil
  if context == :document || context == :section
    @level = @next_section_index = 0
    @next_section_ordinal = 1
  elsif AbstractBlock === parent
    @level = parent.level
  else
    @level = nil
  end
end

Public Instance Methods

<<(block) click to toggle source

Public: Append a content block to this block’s list of blocks.

block - The new child block.

Examples

block = Block.new(parent, :preamble, content_model: :compound)

block << Block.new(block, :paragraph, source: 'p1')
block << Block.new(block, :paragraph, source: 'p2')
block.blocks?
# => true
block.blocks.size
# => 2

Returns The parent Block

# File lib/asciidoctor/abstract_block.rb, line 114
def << block
  block.parent = self unless block.parent == self
  @blocks << block
  self
end
Also aliased as: append
alt() click to toggle source

Public: Returns the converted alt text for this block image.

Returns the [String] value of the alt attribute with XML special character and replacement substitutions applied.

# File lib/asciidoctor/abstract_block.rb, line 225
def alt
  if (text = @attributes['alt'])
    if text == @attributes['default-alt']
      sub_specialchars text
    else
      text = sub_specialchars text
      (ReplaceableTextRx.match? text) ? (sub_replacements text) : text
    end
  else
    ''
  end
end
append(block)

NOTE append alias required for adapting to a Java API

Alias for: <<
assign_caption(value, caption_context = @context) click to toggle source

Public: Generate and assign caption to block if not already assigned.

If the block has a title and a caption prefix is available for this block, then build a caption from this information, assign it a number and store it to the caption attribute on the block.

If a caption has already been assigned to this block, do nothing.

The parts of a complete caption are: <prefix> <number>. <title> This partial caption represents the part the precedes the title.

value - The String caption to assign to this block or nil to use document attribute. caption_context - The Symbol context to use when resolving caption-related attributes. If not provided, the name of

the context for this block is used. Only certain contexts allow the caption to be looked up.
(default: @context)

Returns nothing.

# File lib/asciidoctor/abstract_block.rb, line 388
def assign_caption value, caption_context = @context
  unless @caption || !@title || (@caption = value || @document.attributes['caption'])
    if (attr_name = CAPTION_ATTRIBUTE_NAMES[caption_context]) && (prefix = @document.attributes[attr_name])
      @caption = %(#{prefix} #{@numeral = @document.increment_and_store_counter %(#{caption_context}-number), self}. )
      nil
    end
  end
end
assign_numeral(section) click to toggle source

Internal: Assign the next index (0-based) and numeral (1-based) to the section. If the section is an appendix, the numeral is a letter (starting with A). This method also assigns the appendix caption.

section - The section to which to assign the next index and numeral.

Assign to the specified section the next index and, if the section is numbered, the numeral within this block (its parent).

Returns nothing

# File lib/asciidoctor/abstract_block.rb, line 407
def assign_numeral section
  @next_section_index = (section.index = @next_section_index) + 1
  if (like = section.numbered)
    if (sectname = section.sectname) == 'appendix'
      section.numeral = @document.counter 'appendix-number', 'A'
      section.caption = (caption = @document.attributes['appendix-caption']) ? %(#{caption} #{section.numeral}: ) : %(#{section.numeral}. )
    # NOTE currently chapters in a book doctype are sequential even for multi-part books (see #979)
    elsif sectname == 'chapter' || like == :chapter
      section.numeral = (@document.counter 'chapter-number', 1).to_s
    else
      section.numeral = sectname == 'part' ? (Helpers.int_to_roman @next_section_ordinal) : @next_section_ordinal.to_s
      @next_section_ordinal += 1
    end
  end
  nil
end
block?() click to toggle source
# File lib/asciidoctor/abstract_block.rb, line 51
def block?
  true
end
blocks?() click to toggle source

Public: Determine whether this Block contains block content

Returns A Boolean indicating whether this Block has block content

# File lib/asciidoctor/abstract_block.rb, line 126
def blocks?
  @blocks.empty? ? false : true
end
caption() click to toggle source

Gets the caption for this block.

This method routes the deprecated use of the caption method on an admonition block to the textlabel attribute.

Returns the [String] caption for this block (or the value of the textlabel attribute if this is an admonition block).

# File lib/asciidoctor/abstract_block.rb, line 245
def caption
  @context == :admonition ? @attributes['textlabel'] : @caption
end
captioned_title() click to toggle source

Public: Convenience method that returns the interpreted title of the Block with the caption prepended.

Concatenates the value of this Block’s caption instance variable and the return value of this Block’s title method. No space is added between the two values. If the Block does not have a caption, the interpreted title is returned.

Returns the converted String title prefixed with the caption, or just the converted String title if no caption is set

# File lib/asciidoctor/abstract_block.rb, line 259
def captioned_title
  %(#{@caption}#{title})
end
content() click to toggle source

Public: Get the converted result of the child blocks by converting the children appropriate to content model that this block supports.

# File lib/asciidoctor/abstract_block.rb, line 83
def content
  @blocks.map {|b| b.convert }.join LF
end
context=(context) click to toggle source

Public: Update the context of this block.

This method changes the context of this block. It also updates the node name accordingly.

context - the context Symbol context to assign to this block

Returns the specified Symbol context

# File lib/asciidoctor/abstract_block.rb, line 94
def context= context
  @node_name = (@context = context).to_s
end
convert() click to toggle source

Public: Get the converted String content for this Block. If the block has child blocks, the content method should cause them to be converted and returned as content that can be included in the parent block’s template.

# File lib/asciidoctor/abstract_block.rb, line 73
def convert
  @document.playback_attributes @attributes
  converter.convert self
end
Also aliased as: render
file() click to toggle source

Public: Get the source file where this block started

# File lib/asciidoctor/abstract_block.rb, line 60
def file
  @source_location && @source_location.file
end
find_by(selector = {}) click to toggle source

Public: Walk the document tree and find all block-level nodes that match the specified selector (context, style, id, role, and/or custom filter).

If a Ruby block is given, it’s applied as a supplemental filter. If the filter returns true (which implies :accept), the node is accepted and node traversal continues. If the filter returns false (which implies :skip), the node is skipped, but its children are still visited. If the filter returns :reject, the node and all its descendants are rejected. If the filter returns :prune, the node is accepted, but its descendants are rejected. If no selector or filter block is supplied, all block-level nodes in the tree are returned.

Examples

doc.find_by context: :section
#=> Asciidoctor::Section@14459860 { level: 0, title: "Hello, AsciiDoc!", blocks: 0 }
#=> Asciidoctor::Section@14505460 { level: 1, title: "First Section", blocks: 1 }

doc.find_by(context: :section) {|section| section.level == 1 }
#=> Asciidoctor::Section@14505460 { level: 1, title: "First Section", blocks: 1 }

doc.find_by context: :listing, style: 'source'
#=> Asciidoctor::Block@13136720 { context: :listing, content_model: :verbatim, style: "source", lines: 1 }

Returns An Array of block-level nodes that match the filter or an empty Array if no matches are found

# File lib/asciidoctor/abstract_block.rb, line 175
def find_by selector = {}, &block
  find_by_internal selector, (result = []), &block
rescue ::StopIteration
  result
end
Also aliased as: query
inline?() click to toggle source
# File lib/asciidoctor/abstract_block.rb, line 55
def inline?
  false
end
lineno() click to toggle source

Public: Get the source line number where this block started

# File lib/asciidoctor/abstract_block.rb, line 65
def lineno
  @source_location && @source_location.lineno
end
list_marker_keyword(list_type = nil) click to toggle source

Public: Retrieve the list marker keyword for the specified list type.

For use in the HTML type attribute.

list_type - the type of list; default to the @style if not specified

Returns the single-character [String] keyword that represents the marker for the specified list type

# File lib/asciidoctor/abstract_block.rb, line 270
def list_marker_keyword list_type = nil
  ORDERED_LIST_KEYWORDS[list_type || @style]
end
next_adjacent_block() click to toggle source

Move to the next adjacent block in document order. If the current block is the last item in a list, this method will return the following sibling of the list block.

# File lib/asciidoctor/abstract_block.rb, line 185
def next_adjacent_block
  unless @context == :document
    if (p = @parent).context == :dlist && @context == :list_item
      (sib = p.items[(p.items.find_index {|terms, desc| (terms.include? self) || desc == self }) + 1]) ? sib : p.next_adjacent_block
    else
      (sib = p.blocks[(p.blocks.find_index self) + 1]) ? sib : p.next_adjacent_block
    end
  end
end
number() click to toggle source

Deprecated: Legacy property to get the String or Integer numeral of this section.

# File lib/asciidoctor/abstract_block.rb, line 142
def number
  (Integer @numeral) rescue @numeral
end
number=(val) click to toggle source

Deprecated: Legacy property to set the numeral of this section by coercing the value to a String.

# File lib/asciidoctor/abstract_block.rb, line 147
def number= val
  @numeral = val.to_s
end
query(selector = {})
Alias for: find_by
reindex_sections() click to toggle source

Internal: Reassign the section indexes

Walk the descendents of the current Document or Section and reassign the section 0-based index value to each Section as it appears in document order.

IMPORTANT You must invoke this method on a node after removing child sections or else the internal counters will be off.

Returns nothing

# File lib/asciidoctor/abstract_block.rb, line 434
def reindex_sections
  @next_section_index = 0
  @next_section_ordinal = 1
  @blocks.each do |block|
    if block.context == :section
      assign_numeral block
      block.reindex_sections
    end
  end
end
remove_sub(sub) click to toggle source

Public: Remove a substitution from this block

sub - The Symbol substitution name

Returns nothing

# File lib/asciidoctor/abstract_block.rb, line 323
def remove_sub sub
  @subs.delete sub
  nil
end
render()

Deprecated: Use {AbstractBlock#convert} instead.

Alias for: convert
sections() click to toggle source

Public: Get the Array of child Section objects

Only applies to Document and Section instances

Examples

doc << (sect1 = Section.new doc, 1)
sect1.title = 'Section 1'
para1 = Block.new sect1, :paragraph, source: 'Paragraph 1'
para2 = Block.new sect1, :paragraph, source: 'Paragraph 2'
sect1 << para1 << para2
sect1 << (sect1_1 = Section.new sect1, 2)
sect1_1.title = 'Section 1.1'
sect1_1 << (Block.new sect1_1, :paragraph, source: 'Paragraph 3')
sect1.blocks?
# => true
sect1.blocks.size
# => 3
sect1.sections.size
# => 1

Returns an [Array] of Section objects

# File lib/asciidoctor/abstract_block.rb, line 217
def sections
  @blocks.select {|block| block.context == :section }
end
sections?() click to toggle source

Public: Check whether this block has any child Section objects.

Acts an an abstract method that always returns false unless this block is an instance of Document or Section. Both Document and Section provide overrides for this method.

Returns false

# File lib/asciidoctor/abstract_block.rb, line 137
def sections?
  false
end
sub?(name) click to toggle source

Public: A convenience method that checks whether the specified substitution is enabled for this block.

name - The Symbol substitution name

Returns A Boolean indicating whether the specified substitution is enabled for this block

# File lib/asciidoctor/abstract_block.rb, line 314
def sub? name
  @subs.include? name
end
title() click to toggle source

Public: Get the String title of this Block with title substitutions applied

The following substitutions are applied to block and section titles:

:specialcharacters, :quotes, :replacements, :macros, :attributes and :post_replacements

Examples

block.title = "Foo 3^ # {two-colons} Bar(1)"
block.title
=> "Foo 3^ # :: Bar(1)"

Returns the converted String title for this Block, or nil if the source title is falsy

# File lib/asciidoctor/abstract_block.rb, line 287
def title
  # prevent substitutions from being applied to title multiple times
  @converted_title ||= @title && (apply_title_subs @title)
end
title=(val) click to toggle source

Public: Set the String block title.

Returns the specified String title

# File lib/asciidoctor/abstract_block.rb, line 302
def title= val
  @converted_title = nil
  @title = val
end
title?() click to toggle source

Public: A convenience method that checks whether the title of this block is defined.

Returns a [Boolean] indicating whether this block has a title.

# File lib/asciidoctor/abstract_block.rb, line 295
def title?
  @title ? true : false
end
xreftext(xrefstyle = nil) click to toggle source

Public: Generate cross reference text (xreftext) that can be used to refer to this block.

Use the explicit reftext for this block, if specified, retrieved from the {#reftext} method. Otherwise, if this is a section or captioned block (a block with both a title and caption), generate the xreftext according to the value of the xrefstyle argument (e.g., full, short). This logic may leverage the {Substitutors#sub_quotes} method to apply formatting to the text. If this is not a captioned block, return the title, if present, or nil otherwise.

xrefstyle - An optional String that specifies the style to use to format

the xreftext ('full', 'short', or 'basic') (default: nil).

Returns the generated [String] xreftext used to refer to this block or nothing if there isn’t sufficient information to generate one.

# File lib/asciidoctor/abstract_block.rb, line 344
def xreftext xrefstyle = nil
  if (val = reftext) && !val.empty?
    val
  # NOTE xrefstyle only applies to blocks with a title and a caption or number
  elsif xrefstyle && @title && !@caption.nil_or_empty?
    case xrefstyle
    when 'full'
      quoted_title = sub_placeholder (sub_quotes @document.compat_mode ? %q(``%s'') : '"`%s`"'), title
      if @numeral && (caption_attr_name = CAPTION_ATTRIBUTE_NAMES[@context]) && (prefix = @document.attributes[caption_attr_name])
        %(#{prefix} #{@numeral}, #{quoted_title})
      else
        %(#{@caption.chomp '. '}, #{quoted_title})
      end
    when 'short'
      if @numeral && (caption_attr_name = CAPTION_ATTRIBUTE_NAMES[@context]) && (prefix = @document.attributes[caption_attr_name])
        %(#{prefix} #{@numeral})
      else
        @caption.chomp '. '
      end
    else # 'basic'
      title
    end
  else
    title
  end
end

Protected Instance Methods

find_by_internal(selector = {}) { |self)| ... } click to toggle source

Internal: Performs the work for find_by, but does not handle the StopIteration exception.

# File lib/asciidoctor/abstract_block.rb, line 448
def find_by_internal selector = {}, result = [], &block
  if ((any_context = (context_selector = selector[:context]) ? nil : true) || context_selector == @context) &&
      (!(style_selector = selector[:style]) || style_selector == @style) &&
      (!(role_selector = selector[:role]) || (has_role? role_selector)) &&
      (!(id_selector = selector[:id]) || id_selector == @id)
    if block_given?
      if (verdict = yield self)
        case verdict
        when :prune
          result << self
          raise ::StopIteration if id_selector
          return result
        when :reject
          raise ::StopIteration if id_selector
          return result
        when :stop
          raise ::StopIteration
        else
          result << self
          raise ::StopIteration if id_selector
        end
      elsif id_selector
        raise ::StopIteration
      end
    else
      result << self
      raise ::StopIteration if id_selector
    end
  end
  case @context
  when :document
    unless context_selector == :document
      # process document header as a section, if present
      if header? && (any_context || context_selector == :section)
        @header.find_by_internal selector, result, &block
      end
      @blocks.each do |b|
        next if context_selector == :section && b.context != :section # optimization
        b.find_by_internal selector, result, &block
      end
    end
  when :dlist
    # dlist has different structure than other blocks
    if any_context || context_selector != :section # optimization
      # NOTE the list item of a dlist can be nil, so we have to check
      @blocks.flatten.each {|b| b.find_by_internal selector, result, &block if b }
    end
  when :table
    if selector[:traverse_documents]
      rows.head.each {|r| r.each {|c| c.find_by_internal selector, result, &block } }
      selector = selector.merge context: :document if context_selector == :inner_document
      (rows.body + rows.foot).each do |r|
        r.each do |c|
          c.find_by_internal selector, result, &block
          c.inner_document.find_by_internal selector, result, &block if c.style == :asciidoc
        end
      end
    else
      (rows.head + rows.body + rows.foot).each {|r| r.each {|c| c.find_by_internal selector, result, &block } }
    end
  else
    @blocks.each do |b|
      next if context_selector == :section && b.context != :section # optimization
      b.find_by_internal selector, result, &block
    end
  end
  result
end