class Asciidoctor::AbstractBlock
def << block
# => 2
block.blocks.size
# => true
block.blocks?
block << Block.new(block, :paragraph, source: 'p2')
block << Block.new(block, :paragraph, source: 'p1')
block = Block.new(parent, :preamble, content_model: :compound)
Examples
block - The new child block.
Public: Append a content block to this block's list of blocks.
def << block block.parent = self unless block.parent == self @blocks << block self end
def alt
Returns the [String] value of the alt attribute with XML special character
Public: Returns the converted alt text for this block image.
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
def assign_caption value, caption_context = @context
(default: @context)
the context for this block is used. Only certain contexts allow the caption to be looked up.
caption_context - The Symbol context to use when resolving caption-related attributes. If not provided, the name of
value - The String caption to assign to this block or nil to use document attribute.
This partial caption represents the part the precedes the title.
The parts of a complete caption are:
If a caption has already been assigned to this block, do nothing.
to the caption attribute on the block.
then build a caption from this information, assign it a number and store it
If the block has a title and a caption prefix is available for this block,
Public: Generate and assign caption to block if not already assigned.
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
def assign_numeral section
numbered, the numeral within this block (its parent).
Assign to the specified section the next index and, if the section is
section - The section to which to assign the next index and numeral.
method also assigns the appendix caption.
If the section is an appendix, the numeral is a letter (starting with A). This
Internal: Assign the next index (0-based) and numeral (1-based) to the section.
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
def block?
def block? true end
def blocks?
Public: Determine whether this Block contains block content
def blocks? @blocks.empty? ? false : true end
def caption
Returns the [String] caption for this block (or the value of the textlabel
admonition block to the textlabel attribute.
This method routes the deprecated use of the caption method on an
Gets the caption for this block.
def caption @context == :admonition ? @attributes['textlabel'] : @caption end
def captioned_title
Returns the converted String title prefixed with the caption, or just the
returned.
two values. If the Block does not have a caption, the interpreted title is
return value of this Block's title method. No space is added between the
Concatenates the value of this Block's caption instance variable and the
with the caption prepended.
Public: Convenience method that returns the interpreted title of the Block
def captioned_title %(#{@caption}#{title}) end
def content
Public: Get the converted result of the child blocks by converting the
def content @blocks.map {|b| b.convert }.join LF end
def context= context
context - the context Symbol context to assign to this block
This method changes the context of this block. It also updates the node name accordingly.
Public: Update the context of this block.
def context= context @node_name = (@context = context).to_s end
def convert
converted and returned as content that can be included in the
has child blocks, the content method should cause them to be
Public: Get the converted String content for this Block. If the block
def convert @document.playback_attributes @attributes converter.convert self end
def file
def file @source_location && @source_location.file end
def find_by selector = {}, &block
--
Returns An Array of block-level nodes that match the filter or an empty Array if no matches are found
#=> Asciidoctor::Block@13136720 { context: :listing, content_model: :verbatim, style: "source", lines: 1 }
doc.find_by context: :listing, style: 'source'
#=> 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 }
#=> Asciidoctor::Section@14459860 { level: 0, title: "Hello, AsciiDoc!", blocks: 0 }
doc.find_by context: :section
Examples
or filter block is supplied, all block-level nodes in the tree are returned.
rejected. If the filter returns :prune, the node is accepted, but its descendants are rejected. If no selector
skipped, but its children are still visited. If the filter returns :reject, the node and all its descendants are
the node is accepted and node traversal continues. If the filter returns false (which implies :skip), the node is
If a Ruby block is given, it's applied as a supplemental filter. If the filter returns true (which implies :accept),
role, and/or custom filter).
Public: Walk the document tree and find all block-level nodes that match the specified selector (context, style, id,
def find_by selector = {}, &block find_by_internal selector, (result = []), &block rescue ::StopIteration result end
def find_by_internal selector = {}, result = [], &block
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
def initialize parent, context, opts = {}
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
def inline?
def inline? false end
def lineno
def lineno @source_location && @source_location.lineno end
def list_marker_keyword list_type = nil
list_type - the type of list; default to the @style if not specified
For use in the HTML type attribute.
Public: Retrieve the list marker keyword for the specified list type.
def list_marker_keyword list_type = nil ORDERED_LIST_KEYWORDS[list_type || @style] end
def next_adjacent_block
Move to the next adjacent block in document order. If the current block is the last
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
def number
def number (Integer @numeral) rescue @numeral end
def number= val
def number= val @numeral = val.to_s end
def reindex_sections
child sections or else the internal counters will be off.
IMPORTANT You must invoke this method on a node after removing
as it appears in document order.
and reassign the section 0-based index value to each Section
Walk the descendents of the current Document or Section
Internal: Reassign the section indexes
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
def remove_sub sub
sub - The Symbol substitution name
Public: Remove a substitution from this block
def remove_sub sub @subs.delete sub nil end
def sections
# => 1
sect1.sections.size
# => 3
sect1.blocks.size
# => true
sect1.blocks?
sect1_1 << (Block.new sect1_1, :paragraph, source: 'Paragraph 3')
sect1_1.title = 'Section 1.1'
sect1 << (sect1_1 = Section.new sect1, 2)
sect1 << para1 << para2
para2 = Block.new sect1, :paragraph, source: 'Paragraph 2'
para1 = Block.new sect1, :paragraph, source: 'Paragraph 1'
sect1.title = 'Section 1'
doc << (sect1 = Section.new doc, 1)
Examples
Only applies to Document and Section instances
Public: Get the Array of child Section objects
def sections @blocks.select {|block| block.context == :section } end
def sections?
Only applies to Document and Section instances
Public: Check whether this block has any child Section objects.
def sections? @next_section_index > 0 end
def sub? name
Returns A Boolean indicating whether the specified substitution is
name - The Symbol substitution name
substitution is enabled for this block.
Public: A convenience method that checks whether the specified
def sub? name @subs.include? name end
def title
=> "Foo 3^ # :: Bar(1)"
block.title
block.title = "Foo 3^ # {two-colons} Bar(1)"
Examples
:specialcharacters, :quotes, :replacements, :macros, :attributes and :post_replacements
The following substitutions are applied to block and section titles:
Public: Get the String title of this Block with title substitions applied
def title # prevent substitutions from being applied to title multiple times @converted_title ||= @title && (apply_title_subs @title) end
def title= val
Public: Set the String block title.
def title= val @converted_title = nil @title = val end
def title?
Public: A convenience method that checks whether the title of this block is defined.
def title? @title ? true : false end
def xreftext xrefstyle = nil
Returns the generated [String] xreftext used to refer to this block or
the xreftext ('full', 'short', or 'basic') (default: nil).
xrefstyle - An optional String that specifies the style to use to format
nil otherwise.
text. If this is not a captioned block, return the title, if present, or
leverage the {Substitutors#sub_quotes} method to apply formatting to the
the value of the xrefstyle argument (e.g., full, short). This logic may
block with both a title and caption), generate the xreftext according to
{#reftext} method. Otherwise, if this is a section or captioned block (a
Use the explicit reftext for this block, if specified, retrieved from the
to this block.
Public: Generate cross reference text (xreftext) that can be used to refer
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