lib/asciidoctor/section.rb in asciidoctor-1.5.6.2 vs lib/asciidoctor/section.rb in asciidoctor-1.5.7
- old
+ new
@@ -36,18 +36,23 @@
# Public: Get the caption for this section (only relevant for appendices)
attr_reader :caption
# Public: Initialize an Asciidoctor::Section object.
#
- # parent - The parent Asciidoc Object.
- def initialize parent = nil, level = nil, numbered = true, opts = {}
+ # parent - The parent AbstractBlock. If set, must be a Document or Section object (default: nil)
+ # level - The Integer level of this section (default: 1 more than parent level or 1 if parent not defined)
+ # numbered - A Boolean indicating whether numbering is enabled for this Section (default: false)
+ # opts - An optional Hash of options (default: {})
+ def initialize parent = nil, level = nil, numbered = false, opts = {}
super parent, :section, opts
- @level = level ? level : (parent ? (parent.level + 1) : 1)
- @numbered = numbered && @level > 0
- @special = parent && parent.context == :section && parent.special
+ if Section === parent
+ @level, @special = level || (parent.level + 1), parent.special
+ else
+ @level, @special = level || 1, false
+ end
+ @numbered = numbered
@index = 0
- @number = 1
end
# Public: The name of this section, an alias of the section title
alias name title
@@ -58,15 +63,17 @@
Section.generate_id title, @document
end
# Public: Get the section number for the current Section
#
- # The section number is a unique, dot separated String
- # where each entry represents one level of nesting and
- # the value of each entry is the 1-based outline number
- # of the Section amongst its numbered sibling Sections
+ # 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.
+ #
# delimiter - the delimiter to separate the number for each level
# append - 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)
@@ -101,14 +108,16 @@
# # => 1,1,1
#
# Returns the section number as a String
def sectnum(delimiter = '.', append = nil)
append ||= (append == false ? '' : delimiter)
- if @level && @level > 1 && @parent && @parent.context == :section
- %(#{@parent.sectnum(delimiter)}#{@number}#{append})
- else
+ if @level == 1
%(#{@number}#{append})
+ elsif @level > 1
+ Section === @parent ? %(#{@parent.sectnum(delimiter)}#{@number}#{append}) : %(#{@number}#{append})
+ else # @level == 0
+ %(#{Helpers.int_to_roman @number}#{append})
end
end
# (see AbstractBlock#xreftext)
def xreftext xrefstyle = nil
@@ -151,11 +160,11 @@
#
# block - The child Block to append to this parent Block
#
# Returns The parent Block
def << block
- enumerate_section block if block.context == :section
+ assign_numeral block if block.context == :section
super
end
def to_s
if @title
@@ -167,35 +176,43 @@
end
# Public: 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 replaced with the
- # value of the 'idseparator' attribute, which is an underscore by default.
+ # 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
- # until a unique id is found.
+ # 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 undefining the 'sectids' attribute.
+ # Section ID generation can be disabled by unsetting the 'sectids' document attribute.
#
# Examples
#
# Section.generate_id 'Foo', document
# => "_foo"
#
+ # Returns the generated [String] ID.
def self.generate_id title, document
attrs = document.attributes
- sep = attrs['idseparator'] || '_'
pre = attrs['idprefix'] || '_'
- gen_id = %(#{pre}#{title.downcase.gsub InvalidSectionIdCharsRx, sep})
- unless sep.empty?
- # remove repeat and trailing separator characters
- gen_id = gen_id.tr_s sep, sep
- gen_id = gen_id.chop if gen_id.end_with? sep
- # ensure id doesn't begin with idseparator if idprefix is empty and idseparator is not empty
- if pre.empty?
- gen_id = gen_id.slice 1, gen_id.length while gen_id.start_with? sep
+ 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[:ids].key? gen_id
ids, cnt = document.catalog[:ids], Compliance.unique_id_start_index
cnt += 1 while ids.key?(candidate_id = %(#{gen_id}#{sep}#{cnt}))
candidate_id