lib/asciidoctor/section.rb in asciidoctor-0.0.7 vs lib/asciidoctor/section.rb in asciidoctor-0.0.9
- old
+ new
@@ -1,115 +1,85 @@
-# Public: Methods for managing sections of Asciidoc content in a document.
+# Public: Methods for managing sections of AsciiDoc content in a document.
# The section responds as an Array of content blocks by delegating
# block-related methods to its @blocks Array.
#
# Examples
#
# section = Asciidoctor::Section.new
-# section.name = 'DESCRIPTION'
-# section.anchor = 'DESCRIPTION'
+# section.title = 'Section 1'
+# section.id = 'sect1'
#
# section.size
# => 0
#
-# section.section_id
-# => "_description"
+# section.id
+# => "sect1"
#
# section << new_block
# section.size
# => 1
-class Asciidoctor::Section
- # Public: Get/Set the Integer section level.
- attr_accessor :level
+class Asciidoctor::Section < Asciidoctor::AbstractBlock
- # Public: Set the String section name.
- attr_writer :name
+ # Public: Get/Set the Integer index of this section within the parent block
+ attr_accessor :index
- # Public: Get/Set the String section caption.
- attr_accessor :caption
-
- # Public: Get/Set the String section anchor name.
- attr_accessor :anchor
- alias :id :anchor
-
- # Public: Get the Hash of attributes for this block
- attr_accessor :attributes
-
- # Public: Get the Array of section blocks.
- attr_reader :blocks
-
# Public: Initialize an Asciidoctor::Section object.
#
# parent - The parent Asciidoc Object.
- def initialize(parent)
- @parent = parent
- @attributes = {}
- @blocks = []
+ def initialize(parent = nil, level = nil)
+ super(parent, :section)
+ if level.nil? && !parent.nil?
+ @level = parent.level + 1
+ end
+ @index = 0
end
- # Public: Get the String section name with intrinsics converted
+ # Public: The name of this section, an alias of the section title
+ alias :name :title
+
+ # Public: Generate a String id for this section.
#
- # Examples
+ # The generated id is prefixed with value of the 'idprefix' attribute, which
+ # is an underscore by default.
#
- # section.name = "git-web{litdd}browse(1) Manual Page"
- # section.name
- # => "git-web--browse(1) Manual Page"
+ # Section id synthesis can be disabled by undefining the 'sectids' attribute.
#
- # Returns the String section name
- def name
- @name &&
- @name.gsub(/(^|[^\\])\{(\w[\w\-]+\w)\}/) { $1 + Asciidoctor::INTRINSICS[$2] }.
- gsub( /`([^`]+)`/, '<tt>\1</tt>' )
- end
-
- # Public: Get the String section id prefixed with value of idprefix attribute, otherwise an underscore
+ # If the generated id is already in use in the document, a count is appended
+ # until a unique id is found.
#
- # Section ID synthesis can be disabled by undefining the sectids attribute.
- #
# Examples
#
# section = Section.new(parent)
- # section.name = "Foo"
- # section.section_id
+ # section.title = "Foo"
+ # section.generate_id
# => "_foo"
- def section_id
- if self.document.attributes.has_key? 'sectids'
- self.document.attributes.fetch('idprefix', '_') + "#{name && name.downcase.gsub(/\W+/,'_').gsub(/_+$/, '')}".tr_s('_', '_')
+ #
+ # another_section = Section.new(parent)
+ # another_section.title = "Foo"
+ # another_section.generate_id
+ # => "_foo_1"
+ def generate_id
+ if @document.attr?('sectids')
+ base_id = @document.attr('idprefix', '_') + title.downcase.gsub(/&#[0-9]+;/, '_').
+ gsub(/\W+/, '_').tr_s('_', '_').gsub(/^_?(.*?)_?$/, '\1')
+ gen_id = base_id
+ cnt = 2
+ while @document.references[:ids].has_key? gen_id
+ gen_id = "#{base_id}_#{cnt}"
+ cnt += 1
+ end
+ @document.references[:ids][gen_id] = title
+ gen_id
else
nil
end
end
- # Public: Get the Asciidoctor::Document instance to which this Block belongs
- def document
- @parent.is_a?(Asciidoctor::Document) ? @parent : @parent.document
- end
-
- def attr(name, default = nil)
- default.nil? ? @attributes.fetch(name.to_s, self.document.attr(name)) :
- @attributes.fetch(name.to_s, self.document.attr(name, default))
- end
-
- def attr?(name)
- @attributes.has_key?(name.to_s) || self.document.attr?(name)
- end
-
- def update_attributes(attributes)
- @attributes.update(attributes)
- end
-
- # Public: Get the Asciidoctor::Renderer instance being used for the ancestor
- # Asciidoctor::Document instance.
- def renderer
- Asciidoctor.debug "Section#renderer: Looking for my renderer up in #{@parent}"
- @parent.renderer
- end
-
# Public: Get the rendered String content for this Section and all its child
# Blocks.
def render
- Asciidoctor.debug "Now rendering section for #{self}"
+ Asciidoctor.debug { "Now rendering section for #{self}" }
renderer.render('section', self)
end
# Public: Get the String section content by aggregating rendered section blocks.
#
@@ -120,131 +90,72 @@
# section << 'bar'
# section << 'baz'
# section.content
# "<div class=\"paragraph\"><p>foo</p></div>\n<div class=\"paragraph\"><p>bar</p></div>\n<div class=\"paragraph\"><p>baz</p></div>"
def content
- @blocks.map do |block|
- Asciidoctor.debug "Begin rendering block #{block.is_a?(Asciidoctor::Section) ? block.name : 'n/a'} #{block} (context: #{block.is_a?(Asciidoctor::Block) ? block.context : 'n/a' })"
- poo = block.render
- Asciidoctor.debug "===> Done rendering block #{block.is_a?(Asciidoctor::Section) ? block.name : 'n/a'} #{block} (context: #{block.is_a?(Asciidoctor::Block) ? block.context : 'n/a' })"
- poo
- end.join
+ @blocks.map {|b| b.render }.join
end
- # Public: The title of this section, an alias of the section name
- def title
- @name
- end
-
- # Public: Get the Integer number of blocks in the section.
+ # Public: Get the section number for the current Section
#
- # Examples
+ # 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 index of
+ # the Section amongst its sibling Sections
#
- # section = Section.new
+ # 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)
#
- # section.size
- # => 0
+ # Examples
#
- # section << 'foo'
- # section << 'bar'
- # section.size
- # => 2
- def size
- @blocks.size
- end
-
- # Public: Get the element at i in the array of section blocks.
+ # 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
#
- # i - The Integer array index number.
+ # sect1.sectnum
+ # # => 1.
#
- # section = Section.new
+ # sect1_1.sectnum
+ # # => 1.1.
#
- # section << 'foo'
- # section << 'bar'
- # section[1]
- # => "bar"
- def [](i)
- @blocks[i]
- end
-
- # Public: Delete the element at i in the array of section blocks,
- # returning that element or nil if i is out of range.
+ # sect1_2.sectnum
+ # # => 1.2.
#
- # i - The Integer array index number.
+ # sect1_1_1.sectnum
+ # # => 1.1.1.
#
- # section = Section.new
+ # sect1_1_1.sectnum(',', false)
+ # # => 1,1,1
#
- # section << 'foo'
- # section << 'bar'
- # section.delete_at(1)
- # => "bar"
- #
- # section.blocks
- # => ["foo"]
- def delete_at(i)
- @blocks.delete_at(i)
+ # Returns the section number as a String
+ def sectnum(delimiter = '.', append = nil)
+ append ||= (append == false ? '' : delimiter)
+ if !@level.nil? && @level > 1 && @parent.is_a?(::Asciidoctor::Section)
+ "#{@parent.sectnum(delimiter)}#{@index + 1}#{append}"
+ else
+ "#{@index + 1}#{append}"
+ end
end
- # Public: Append a content block to this section's list of blocks.
- #
- # block - The new section block.
- #
- # section = Section.new
- #
- # section << 'foo'
- # section << 'bar'
- # section.blocks
- # => ["foo", "bar"]
- def <<(block)
- @blocks << block
- end
-
- # Public: Clear this Section's list of blocks.
- #
- # section = Section.new
- #
- # section << 'foo'
- # section << 'bar'
- # section.blocks
- # => ["foo", "bar"]
- # section.clear_blocks
- # section.blocks
- # => []
- def clear_blocks
- @blocks = []
- end
-
- # Public: Insert a content block at the specified index in this section's
- # list of blocks.
- #
- # i - The Integer array index number.
- # val = The content block to insert.
- #
- # section = Section.new
- #
- # section << 'foo'
- # section << 'baz'
- # section.insert(1, 'bar')
- # section.blocks
- # ["foo", "bar", "baz"]
- def insert(i, block)
- @blocks.insert(i, block)
- end
-
- # Public: Get the Integer index number of the first content block element
- # for which the provided block returns true. Returns nil if no match is
- # found.
- #
- # block - A block that can be used to determine whether a supplied element
- # is a match.
- #
- # section = Section.new
- #
- # section << 'foo'
- # section << 'bar'
- # section << 'baz'
- # section.index{|el| el =~ /^ba/}
- # => 1
- def index(&block)
- @blocks.index(&block)
+ def to_s
+ if @title
+ if @level && @index
+ %[#{super.to_s} - #{sectnum} #@title [blocks:#{@blocks.size}]]
+ else
+ %[#{super.to_s} - #@title [blocks:#{@blocks.size}]]
+ end
+ else
+ super.to_s
+ end
end
end