Class: Asciidoctor::Section

Inherits:
AbstractBlock show all
Defined in:
lib/asciidoctor/section.rb

Overview

> 1

Constant Summary

Constants included from Substitutors

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

Instance Attribute Summary collapse

Attributes inherited from AbstractBlock

#blocks, #content_model, #level, #numeral, #source_location, #style, #subs

Attributes inherited from AbstractNode

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

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractBlock

#alt, #assign_caption, #block?, #blocks?, #captioned_title, #content, #context=, #convert, #file, #find_by, #inline?, #lineno, #list_marker_keyword, #next_adjacent_block, #number, #remove_sub, #sections, #sections?, #sub?, #title, #title=, #title?

Methods inherited from AbstractNode

#add_role, #attr, #attr?, #block?, #converter, #enabled_options, #generate_data_uri, #generate_data_uri_from_uri, #has_role?, #icon_uri, #image_uri, #inline?, #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?, #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 = nil, level = nil, numbered = false, opts = {}) ⇒ Section

Initialize an Asciidoctor::Section object.

Parameters:

  • parent (defaults to: nil)

    The parent AbstractBlock. If set, must be a Document or Section object (default: nil)

  • level (defaults to: nil)

    The Integer level of this section (default: 1 more than parent level or 1 if parent not defined)

  • numbered (defaults to: false)

    A Boolean indicating whether numbering is enabled for this Section (default: false)

  • opts (defaults to: {})

    An optional Hash of options (default: {})



46
47
48
49
50
51
52
53
54
55
# File 'lib/asciidoctor/section.rb', line 46

def initialize parent = nil, level = nil, numbered = false, opts = {}
  super parent, :section, opts
  if Section === parent
    @level, @special = level || (parent.level + 1), parent.special
  else
    @level, @special = level || 1, false
  end
  @numbered = numbered
  @index = 0
end

Instance Attribute Details

#captionObject (readonly)

Get the caption for this section (only relevant for appendices)



38
39
40
# File 'lib/asciidoctor/section.rb', line 38

def caption
  @caption
end

#indexObject

Get/Set the 0-based index order of this section within the parent block



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

def index
  @index
end

#numberedObject

Get/Set the flag to indicate whether this section should be numbered. The sectnum method should only be called if this flag is true.



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

def numbered
  @numbered
end

#sectnameObject

Get/Set the section name of this section



28
29
30
# File 'lib/asciidoctor/section.rb', line 28

def sectname
  @sectname
end

#specialObject

Get/Set the flag to indicate whether this is a special section or a child of one



31
32
33
# File 'lib/asciidoctor/section.rb', line 31

def special
  @special
end

Class Method Details

.generate_id(title, document) ⇒ String

Generate a String ID from the given section title.

The generated ID is prefixed with value of the ‘idprefix’ attribute, which is an underscore (_) by default. Invalid characters are then removed and spaces are replaced with the value of the ‘idseparator’ attribute, which is an underscore (_) by default.

If the generated ID is already in use in the document, a count is appended, offset by the separator, until a unique ID is found.

Section ID generation can be disabled by unsetting the ‘sectids’ document attribute.

Examples:

Section.generate_id 'Foo', document
=> "_foo"

Returns:

  • (String)

    Returns the generated String ID.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/asciidoctor/section.rb', line 191

def self.generate_id title, document
  attrs = document.attributes
  pre = attrs['idprefix'] || '_'
  if (sep = attrs['idseparator'])
    if sep.length == 1 || (!(no_sep = sep.empty?) && (sep = attrs['idseparator'] = sep.chr))
      sep_sub = sep == '-' || sep == '.' ? ' .-' : %( #{sep}.-)
    end
  else
    sep, sep_sub = '_', ' _.-'
  end
  gen_id = %(#{pre}#{title.downcase.gsub InvalidSectionIdCharsRx, ''})
  if no_sep
    gen_id = gen_id.delete ' '
  else
    # replace space with separator and remove repeating and trailing separator characters
    gen_id = gen_id.tr_s sep_sub, sep
    gen_id = gen_id.chop if gen_id.end_with? sep
    # ensure id doesn't begin with idseparator if idprefix is empty (assuming idseparator is not empty)
    gen_id = gen_id.slice 1, gen_id.length if pre.empty? && (gen_id.start_with? sep)
  end
  if document.catalog[:refs].key? gen_id
    ids = document.catalog[:refs]
    cnt = Compliance.unique_id_start_index
    cnt += 1 while ids[candidate_id = %(#{gen_id}#{sep}#{cnt})]
    candidate_id
  else
    gen_id
  end
end

Instance Method Details

#<<(block) ⇒ The

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

If the child block is a Section, assign an index to it.

Parameters:

  • block

    The child Block to append to this parent Block

Returns:

  • (The)

    parent Block



159
160
161
162
# File 'lib/asciidoctor/section.rb', line 159

def << block
  assign_numeral block if block.context == :section
  super
end

#generate_idObject

Generate a String ID from the title of this section.

See Section.generate_id for details.



63
64
65
# File 'lib/asciidoctor/section.rb', line 63

def generate_id
  Section.generate_id title, @document
end

#sectnum(delimiter = '.', append = nil) ⇒ Object

Get the section number for the current Section

The section number is a dot-separated String that uniquely describes the position of this Section in the document. Each entry represents a level of nesting. The value of each entry is the 1-based outline number of the Section amongst its numbered sibling Sections.

This method assumes that both the @level and @parent instance variables have been assigned. The method also assumes that the value of @parent is either a Document or Section.

Examples:

sect1 = Section.new(document)
sect1.level = 1
sect1_1 = Section.new(sect1)
sect1_1.level = 2
sect1_2 = Section.new(sect1)
sect1_2.level = 2
sect1 << sect1_1
sect1 << sect1_2
sect1_1_1 = Section.new(sect1_1)
sect1_1_1.level = 3
sect1_1 << sect1_1_1
sect1.sectnum
# => 1.
sect1_1.sectnum
# => 1.1.
sect1_2.sectnum
# => 1.2.
sect1_1_1.sectnum
# => 1.1.1.
sect1_1_1.sectnum(',', false)
# => 1,1,1

Parameters:

  • delimiter (defaults to: '.')

    the delimiter to separate the number for each level

  • append (defaults to: nil)

    the String to append at the end of the section number or Boolean to indicate the delimiter should not be appended to the final level (default: nil)

Returns:

  • the section number as a String



112
113
114
115
# File 'lib/asciidoctor/section.rb', line 112

def sectnum(delimiter = '.', append = nil)
  append ||= (append == false ? '' : delimiter)
  @level > 1 && Section === @parent ? %(#{@parent.sectnum(delimiter, delimiter)}#{@numeral}#{append}) : %(#{@numeral}#{append})
end

#to_sObject



164
165
166
167
168
169
170
171
# File 'lib/asciidoctor/section.rb', line 164

def to_s
  if @title
    formal_title = @numbered ? %(#{sectnum} #{@title}) : @title
    %(#<#{self.class}@#{object_id} {level: #{@level}, title: #{formal_title.inspect}, blocks: #{@blocks.size}}>)
  else
    super
  end
end

#xreftext(xrefstyle = nil) ⇒ Object

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



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/asciidoctor/section.rb', line 118

def xreftext xrefstyle = nil
  if (val = reftext) && !val.empty?
    val
  elsif xrefstyle
    if @numbered
      case xrefstyle
      when 'full'
        if (type = @sectname) == 'chapter' || type == 'appendix'
          quoted_title = sub_placeholder (sub_quotes '_%s_'), title
        else
          quoted_title = sub_placeholder (sub_quotes @document.compat_mode ? %q(``%s'') : '"`%s`"'), title
        end
        if (signifier = @document.attributes[%(#{type}-refsig)])
          %(#{signifier} #{sectnum '.', ','} #{quoted_title})
        else
          %(#{sectnum '.', ','} #{quoted_title})
        end
      when 'short'
        if (signifier = @document.attributes[%(#{@sectname}-refsig)])
          %(#{signifier} #{sectnum '.', ''})
        else
          sectnum '.', ''
        end
      else # 'basic'
        (type = @sectname) == 'chapter' || type == 'appendix' ? (sub_placeholder (sub_quotes '_%s_'), title) : title
      end
    else # apply basic styling
      (type = @sectname) == 'chapter' || type == 'appendix' ? (sub_placeholder (sub_quotes '_%s_'), title) : title
    end
  else
    title
  end
end