class Asciidoctor::Document

def doctitle opts = {}

or nil if no value can be resolved.
Returns the resolved title as a [Title] if the :partition option is passed or a [String] if not

TODO separate sanitization by type (:cdata for HTML/XML, :plain_text for non-SGML, false for none)

If the :sanitize attribute is specified, XML elements are removed from the value.
If the :partition attribute is specified, the value is parsed into an Document::Title object.

If no value can be resolved, nil is returned.

* document-level attribute named untitled-label (if :use_fallback option is set)
* title of the first section
* header title (known as the document title)
* document-level attribute named title

value:
Searches the locations to find the first non-empty

Public: Resolves the primary title for the document
def doctitle opts = {}
  unless (val = @attributes['title'])
    if (sect = first_section)
      val = sect.title
    elsif !(opts[:use_fallback] && (val = @attributes['untitled-label']))
      return
    end
  end
  if (separator = opts[:partition])
    Title.new val, opts.merge({ separator: (separator == true ? @attributes['title-separator'] : separator) })
  elsif opts[:sanitize] && val.include?('<')
    val.gsub(XmlSanitizeRx, '').squeeze(' ').strip
  else
    val
  end
end