class Asciidoctor::Document

noheader - The header block (h1 heading, author, revision info) should not be shown
notitle - The h1 heading should not be shown
Keep in mind that you’ll want to honor these document settings:
header.title - title of section level 0
first_section.title - title of first section in document, if present
title - value of the title attribute, or nil if not present
name - an alias of doctitle
otherwise nil
otherwise title of first section in document, if present
doctitle - value of title attribute, if assigned and non-empty,
There are several strategies for getting the title of the document:
using erb templates.
Public: Methods for parsing Asciidoc documents and rendering them

def content

def content
  # per AsciiDoc-spec, remove the title after rendering the header
  @attributes.delete('title')
  @blocks.map {|b| b.render }.join
end

def doctitle

We need to be able to return some semblance of a title
def doctitle
  if !(title = @attributes.fetch('title', '')).empty?
    title
  elsif !(sect = first_section).nil? && sect.title?
    sect.title
  else
    nil
  end
end

def doctype

def doctype
  @attributes['doctype']
end

def first_section

QUESTION move to AbstractBlock?
def first_section
  has_header? ? @header : (@blocks || []).detect{|e| e.is_a? Section}
end

def has_header?

def has_header?
  !@header.nil?
end

def initialize(data = [], options = {}, &block)

puts doc.render
doc = Asciidoctor::Document.new(data)
data = File.readlines(filename)

Examples

data to include in this document.
block - A block that can be used to retrieve external Asciidoc
(default: {})
suppressing the header/footer (:header_footer) and attribute overrides (:attributes)
options - A Hash of options to control processing, such as setting the safe mode (:safe),
data - The Array of Strings holding the Asciidoc source document. (default: [])

Public: Initialize an Asciidoc object.
def initialize(data = [], options = {}, &block)
  super(self, :document)
  @renderer = nil
  if options[:parent]
    @parent_document = options.delete(:parent)
    # should we dup here?
    options[:attributes] = @parent_document.attributes
    @renderer = @parent_document.renderer
  else
    @parent_document = nil
  end
  @header = nil
  @references = {
    :ids => {},
    :links => [],
    :images => []
  }
  @callouts = Callouts.new
  @options = options
  @safe = @options.fetch(:safe, SafeMode::SECURE).to_i
  @options[:header_footer] = @options.fetch(:header_footer, true)
  @attributes['asciidoctor'] = true
  @attributes['asciidoctor-version'] = VERSION
  @attributes['sectids'] = true
  @attributes['encoding'] = 'UTF-8'
  attribute_overrides = options[:attributes] || {}
  # the only way to set the include-depth attribute is via the document options
  # 10 is the AsciiDoc default, though currently Asciidoctor only supports 1 level
  attribute_overrides['include-depth'] ||= 10
  # TODO we should go with one or the other, this is confusing
  # for now, base_dir takes precedence if set
  if options.has_key? :base_dir
    @base_dir = attribute_overrides['docdir'] = options[:base_dir]
  else
    attribute_overrides['docdir'] ||= Dir.pwd
    @base_dir = attribute_overrides['docdir']
  end
  # restrict document from setting source-highlighter in SECURE safe mode
  # it can only be set via the constructor
  if @safe >= SafeMode::SECURE
    attribute_overrides['source-highlighter'] ||= nil
  end
  
  attribute_overrides.each {|key, val|
    # a nil or negative key undefines the attribute 
    if (val.nil? || key[-1..-1] == '!')
      @attributes.delete(key.chomp '!')
    # otherwise it's an attribute assignment
    else
      @attributes[key] = val
    end
  }
  @attributes['backend'] ||= DEFAULT_BACKEND
  update_backend_attributes
  if nested?
    # don't need to do the extra processing within our own document
    @reader = Reader.new(data)
  else
    @reader = Reader.new(data, self, attribute_overrides, &block)
  end
  # dynamic intrinstic attribute values
  @attributes['doctype'] ||= DEFAULT_DOCTYPE
  now = Time.new
  @attributes['localdate'] ||= now.strftime('%Y-%m-%d')
  @attributes['localtime'] ||= now.strftime('%H:%m:%S %Z')
  @attributes['localdatetime'] ||= [@attributes['localdate'], @attributes['localtime']].join(' ')
  
  # docdate and doctime should default to localdate and localtime if not otherwise set
  @attributes['docdate'] ||= @attributes['localdate']
  @attributes['doctime'] ||= @attributes['localtime']
  
  @attributes['iconsdir'] ||= File.join(@attributes.fetch('imagesdir', 'images'), 'icons')
  # Now parse the lines in the reader into blocks
  Lexer.parse(@reader, self) 
  # or we could make it...
  #self << *Lexer.parse(@reader, self)
  @callouts.rewind
  Asciidoctor.debug {
    msg = []
    msg << "Found #{@blocks.size} blocks in this document:"
    @blocks.each {|b|
      msg << b
    }
    msg * "\n"
  }
end

def nested?

def nested?
  !@parent_document.nil?
end

def noheader

def noheader
  @attributes.has_key? 'noheader'
end

def notitle

def notitle
  @attributes.has_key? 'notitle'
end

def register(type, value)

def register(type, value)
  if type == :ids
    if value.is_a?(Array)
      @references[:ids][value[0]] = (value[1] || '[' + value[0] + ']')
    else
      @references[:ids][value] = '[' + value + ']'
    end
  elsif @options[:catalog_assets]
    @references[type] << value
  end
end

def render(opts = {})

using the appropriate built-in template.
or a template is missing, the renderer will fall back to
loaded by Renderer. If a :template_dir is not specified,
Public: Render the Asciidoc document using the templates
def render(opts = {})
  r = renderer(opts)
  @options.merge(opts)[:header_footer] ? r.render('document', self) : r.render('embedded', self)
end

def renderer(opts = {})

def renderer(opts = {})
  return @renderer if @renderer
  
  render_options = {}
  # Load up relevant Document @options
  if @options[:template_dir]
    render_options[:template_dir] = @options[:template_dir]
  end
  
  render_options[:backend] = @attributes.fetch('backend', 'html5')
  render_options[:eruby] = @options.fetch(:eruby, 'erb')
  render_options[:compact] = @options.fetch(:compact, false)
  
  # Override Document @option settings with options passed in
  render_options.merge! opts
  @renderer = Renderer.new(render_options)
end

def source

Make the raw source for the Document available.
def source
  @reader.source if @reader
end

def splain

def splain
  Asciidoctor.debug {
    msg = ''
    if @header
      msg = "Header is #{@header}"
    else
      msg = "No header"
    end
    msg += "I have #{@blocks.count} blocks"
    @blocks.each_with_index do |block, i|
      msg += "v" * 60
      msg += "Block ##{i} is a #{block.class}"
      msg += "Name is #{block.title rescue 'n/a'}"
      block.splain(0) if block.respond_to? :splain
      msg += "^" * 60
    end
  }
  nil
end

def title

The title explicitly defined in the document attributes
def title
  @attributes['title']
end

def title=(title)

def title=(title)
  @header = Section.new self
  @header.title = title
end

def to_s

def to_s
  %[#{super.to_s} - #{doctitle}]  
end

def update_backend_attributes()

Public: Update the backend attributes to reflect a change in the selected backend
def update_backend_attributes()
  backend = @attributes['backend']
  basebackend = backend.sub(/[[:digit:]]+$/, '')
  page_width = DEFAULT_PAGE_WIDTHS[basebackend]
  if page_width
    @attributes['pagewidth'] = page_width
  else
    @attributes.delete('pagewidth')
  end
  @attributes['backend-' + backend] = 1
  @attributes['basebackend'] = basebackend
  @attributes['basebackend-' + basebackend] = 1
end