lib/asciidoctor/section.rb in asciidoctor-1.5.5 vs lib/asciidoctor/section.rb in asciidoctor-1.5.6
- old
+ new
@@ -22,88 +22,42 @@
class Section < AbstractBlock
# Public: Get/Set the 0-based index order of this section within the parent block
attr_accessor :index
- # Public: Get/Set the number of this section within the parent block
- # Only relevant if the attribute numbered is true
- attr_accessor :number
-
# Public: Get/Set the section name of this section
attr_accessor :sectname
# Public: Get/Set the flag to indicate whether this is a special section or a child of one
attr_accessor :special
# Public: Get the state of the numbered attribute at this section (need to preserve for creating TOC)
attr_accessor :numbered
+ # 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 = {}
super parent, :section, opts
- if level
- @level = level
- else
- @level = parent ? (parent.level + 1) : 1
- end
+ @level = level ? level : (parent ? (parent.level + 1) : 1)
@numbered = numbered && @level > 0
@special = parent && parent.context == :section && parent.special
@index = 0
@number = 1
end
# Public: The name of this section, an alias of the section title
- alias :name :title
+ alias name title
- # Public: Generate a String id for this section.
+ # Public: Generate a String ID from the title of this section.
#
- # The generated id is prefixed with value of the 'idprefix' attribute, which
- # is an underscore by default.
- #
- # Section id synthesis can be disabled by undefining the 'sectids' attribute.
- #
- # If the generated id is already in use in the document, a count is appended
- # until a unique id is found.
- #
- # Examples
- #
- # section = Section.new(parent)
- # section.title = "Foo"
- # section.generate_id
- # => "_foo"
- #
- # another_section = Section.new(parent)
- # another_section.title = "Foo"
- # another_section.generate_id
- # => "_foo_1"
- #
- # yet_another_section = Section.new(parent)
- # yet_another_section.title = "Ben & Jerry"
- # yet_another_section.generate_id
- # => "_ben_jerry"
+ # See Section.generate_id for details.
def generate_id
- if @document.attributes.has_key? 'sectids'
- sep = @document.attributes['idseparator'] || '_'
- pre = @document.attributes['idprefix'] || '_'
- base_id = %(#{pre}#{title.downcase.gsub(InvalidSectionIdCharsRx, sep).tr_s(sep, sep).chomp(sep)})
- # ensure id doesn't begin with idseparator if idprefix is empty and idseparator is not empty
- if pre.empty? && !sep.empty? && base_id.start_with?(sep)
- base_id = base_id[1..-1]
- base_id = base_id[1..-1] while base_id.start_with?(sep)
- end
- gen_id = base_id
- cnt = Compliance.unique_id_start_index
- while @document.references[:ids].has_key? gen_id
- gen_id = %(#{base_id}#{sep}#{cnt})
- cnt += 1
- end
- gen_id
- else
- nil
- end
+ Section.generate_id title, @document
end
# Public: Get the section number for the current Section
#
# The section number is a unique, dot separated String
@@ -154,27 +108,101 @@
else
%(#{@number}#{append})
end
end
+ # (see AbstractBlock#xreftext)
+ 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 = sprintf sub_quotes('_%s_'), title
+ else
+ quoted_title = sprintf 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' ? (sprintf sub_quotes('_%s_'), title) : title
+ end
+ else # apply basic styling
+ (type = @sectname) == 'chapter' || type == 'appendix' ? (sprintf sub_quotes('_%s_'), title) : title
+ end
+ else
+ title
+ end
+ end
+
# Public: Append a content block to this block's list of blocks.
#
# If the child block is a Section, assign an index to it.
#
# block - The child Block to append to this parent Block
#
# Returns The parent Block
def << block
- assign_index block if block.context == :section
+ enumerate_section block if block.context == :section
super
end
def to_s
- if @title != nil
- qualified_title = @numbered ? %(#{sectnum} #{@title}) : @title
- %(#<#{self.class}@#{object_id} {level: #{@level}, title: #{qualified_title.inspect}, blocks: #{@blocks.size}}>)
+ 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
+
+ # 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.
+ #
+ # If the generated ID is already in use in the document, a count is appended
+ # until a unique id is found.
+ #
+ # Section ID generation can be disabled by undefining the 'sectids' attribute.
+ #
+ # Examples
+ #
+ # Section.generate_id 'Foo', document
+ # => "_foo"
+ #
+ 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
+ end
+ 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
+ else
+ gen_id
end
end
end
end