Class: Asciidoctor::AbstractBlock

Inherits:
AbstractNode show all
Defined in:
lib/asciidoctor/abstract_block.rb

Direct Known Subclasses

Block, Document, List, ListItem, Section, Table, Table::Cell

Constant Summary

Constants included from Substitutors

Substitutors::CAN, Substitutors::CGI, Substitutors::DEL, Substitutors::ESC_R_SB, Substitutors::HighlightedPassSlotRx, Substitutors::PASS_END, Substitutors::PASS_START, Substitutors::PLUS, Substitutors::PassSlotRx, Substitutors::QuotedTextSniffRx, Substitutors::RS, Substitutors::R_SB, Substitutors::SUB_GROUPS, Substitutors::SUB_HINTS, Substitutors::SUB_OPTIONS, Substitutors::SpecialCharsRx, Substitutors::SpecialCharsTr

Instance Attribute Summary collapse

Attributes inherited from AbstractNode

#attributes, #context, #document, #id, #node_name, #parent

Instance Method Summary collapse

Methods inherited from AbstractNode

#add_role, #attr, #attr?, #converter, #enabled_options, #generate_data_uri, #generate_data_uri_from_uri, #has_role?, #icon_uri, #image_uri, #is_uri?, #media_uri, #normalize_asset_path, #normalize_system_path, #normalize_web_path, #option?, #read_asset, #read_contents, #reftext, #reftext?, #remove_attr, #remove_role, #role, #role=, #role?, #roles, #set_attr, #set_option, #update_attributes

Methods included from Substitutors

#apply_header_subs, #apply_normal_subs, #apply_reftext_subs, #apply_subs, #expand_subs, #extract_passthroughs, #highlight_source, #resolve_block_subs, #resolve_lines_to_highlight, #resolve_pass_subs, #resolve_subs, #restore_passthroughs, #sub_attributes, #sub_callouts, #sub_macros, #sub_post_replacements, #sub_quotes, #sub_replacements, #sub_source, #sub_specialchars

Methods included from Logging

#logger, #message_with_context

Constructor Details

#initialize(parent, context, opts = {}) ⇒ AbstractBlock

Returns a new instance of AbstractBlock.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/asciidoctor/abstract_block.rb', line 37

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

Instance Attribute Details

#blocksObject (readonly)

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



6
7
8
# File 'lib/asciidoctor/abstract_block.rb', line 6

def blocks
  @blocks
end

#captionString

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:

  • (String)

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



246
247
248
# File 'lib/asciidoctor/abstract_block.rb', line 246

def caption
  @context == :admonition ? @attributes['textlabel'] : @caption
end

#content_modelObject

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



17
18
19
# File 'lib/asciidoctor/abstract_block.rb', line 17

def content_model
  @content_model
end

#levelObject

Set the Integer level of this Section or the level of the Section to which this Asciidoctor::AbstractBlock belongs.



20
21
22
# File 'lib/asciidoctor/abstract_block.rb', line 20

def level
  @level
end

#numeralObject

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.



25
26
27
# File 'lib/asciidoctor/abstract_block.rb', line 25

def numeral
  @numeral
end

#source_locationObject

Gets/Sets the location in the AsciiDoc source where this block begins. Tracking source location is not enabled by default, and is controlled by the sourcemap option.



29
30
31
# File 'lib/asciidoctor/abstract_block.rb', line 29

def source_location
  @source_location
end

#styleObject

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



32
33
34
# File 'lib/asciidoctor/abstract_block.rb', line 32

def style
  @style
end

#subsObject (readonly)

Substitutions to be applied to content in this block.



35
36
37
# File 'lib/asciidoctor/abstract_block.rb', line 35

def subs
  @subs
end

Instance Method Details

#<<(block) ⇒ The Also known as: append

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

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

Parameters:

  • block

    The new child block.

Returns:

  • (The)

    parent Block



116
117
118
119
120
# File 'lib/asciidoctor/abstract_block.rb', line 116

def << block
  block.parent = self unless block.parent == self
  @blocks << block
  self
end

#altString

Returns the converted alt text for this block image.

Returns:

  • (String)

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



226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/asciidoctor/abstract_block.rb', line 226

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

#assign_caption(value, caption_context = @context) ⇒ void

This method returns an undefined value.

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.

Parameters:

  • value

    The String caption to assign to this block or nil to use document attribute.

  • caption_context (defaults to: @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)



389
390
391
392
393
394
395
396
# File 'lib/asciidoctor/abstract_block.rb', line 389

def assign_caption value, caption_context = @context
  unless @caption || !@title || (@caption = value || @document.attributes['caption']) # rubocop:disable Style/GuardClause
    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

#block?Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/asciidoctor/abstract_block.rb', line 53

def block?
  true
end

#blocks?A

Determine whether this Block contains block content

Returns:

  • (A)

    Boolean indicating whether this Block has block content



128
129
130
# File 'lib/asciidoctor/abstract_block.rb', line 128

def blocks?
  @blocks.empty? ? false : true
end

#captioned_titleObject

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



260
261
262
# File 'lib/asciidoctor/abstract_block.rb', line 260

def captioned_title
  %(#{@caption}#{title})
end

#contentObject

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



85
86
87
# File 'lib/asciidoctor/abstract_block.rb', line 85

def content
  @blocks.map {|b| b.convert }.join LF
end

#context=(context) ⇒ Object

Update the context of this block.

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

Parameters:

  • context

    the context Symbol context to assign to this block

Returns:

  • the specified Symbol context



96
97
98
# File 'lib/asciidoctor/abstract_block.rb', line 96

def context= context
  @node_name = (@context = context).to_s
end

#convertObject Also known as: render

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.



75
76
77
78
# File 'lib/asciidoctor/abstract_block.rb', line 75

def convert
  @document.playback_attributes @attributes
  converter.convert self
end

#fileObject

Get the source file where this block started



62
63
64
# File 'lib/asciidoctor/abstract_block.rb', line 62

def file
  @source_location && @source_location.file
end

#find_by(selector = {}, &block) ⇒ An Also known as: query

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 – TODO support jQuery-style selector (e.g., image.thumb)



177
178
179
180
181
# File 'lib/asciidoctor/abstract_block.rb', line 177

def find_by selector = {}, &block
  find_by_internal selector, (result = []), &block
rescue ::StopIteration
  result
end

#inline?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/asciidoctor/abstract_block.rb', line 57

def inline?
  false
end

#linenoObject

Get the source line number where this block started



67
68
69
# File 'lib/asciidoctor/abstract_block.rb', line 67

def lineno
  @source_location && @source_location.lineno
end

#list_marker_keyword(list_type = nil) ⇒ String

Retrieve the list marker keyword for the specified list type.

For use in the HTML type attribute.

Parameters:

  • list_type (defaults to: nil)

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

Returns:

  • (String)

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



271
272
273
# File 'lib/asciidoctor/abstract_block.rb', line 271

def list_marker_keyword list_type = nil
  ORDERED_LIST_KEYWORDS[list_type || @style]
end

#next_adjacent_blockObject

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.



187
188
189
190
191
192
193
194
# File 'lib/asciidoctor/abstract_block.rb', line 187

def next_adjacent_block
  return if @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

#numberObject

Deprecated.

Do not use this in new code, and replace it when updating old code.

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



144
145
146
# File 'lib/asciidoctor/abstract_block.rb', line 144

def number
  (Integer @numeral) rescue @numeral
end

#number=(val) ⇒ Object

Deprecated.

Do not use this in new code, and replace it when updating old code.

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



149
150
151
# File 'lib/asciidoctor/abstract_block.rb', line 149

def number= val
  @numeral = val.to_s
end

#remove_sub(sub) ⇒ void

This method returns an undefined value.

Remove a substitution from this block

Parameters:

  • sub

    The Symbol substitution name



324
325
326
327
# File 'lib/asciidoctor/abstract_block.rb', line 324

def remove_sub sub
  @subs.delete sub
  nil
end

#sectionsArray

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:

  • (Array)

    Returns an Array of Section objects



218
219
220
# File 'lib/asciidoctor/abstract_block.rb', line 218

def sections
  @blocks.select {|block| block.context == :section }
end

#sections?Boolean

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:

  • (Boolean)

    false



139
140
141
# File 'lib/asciidoctor/abstract_block.rb', line 139

def sections?
  false
end

#sub?(name) ⇒ A

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

Parameters:

  • name

    The Symbol substitution name

Returns:

  • (A)

    Boolean indicating whether the specified substitution is enabled for this block



315
316
317
# File 'lib/asciidoctor/abstract_block.rb', line 315

def sub? name
  @subs.include? name
end

#titleObject

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



288
289
290
291
# File 'lib/asciidoctor/abstract_block.rb', line 288

def title
  # prevent substitutions from being applied to title multiple times
  @converted_title ||= @title && (apply_title_subs @title) # rubocop:disable Naming/MemoizedInstanceVariableName
end

#title=(val) ⇒ Object

Set the String block title.

Returns:

  • the specified String title



303
304
305
306
# File 'lib/asciidoctor/abstract_block.rb', line 303

def title= val
  @converted_title = nil
  @title = val
end

#title?Boolean

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

Returns:

  • (Boolean)

    Returns a Boolean indicating whether this block has a title.



296
297
298
# File 'lib/asciidoctor/abstract_block.rb', line 296

def title?
  @title ? true : false
end

#xreftext(xrefstyle = nil) ⇒ String

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 Asciidoctor::AbstractNode#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.

Parameters:

  • xrefstyle (defaults to: nil)

    An optional String that specifies the style to use to format the xreftext (‘full’, ‘short’, or ‘basic’) (default: nil).

Returns:

  • (String)

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



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/asciidoctor/abstract_block.rb', line 345

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