# File lib/asciidoctor/document.rb, line 1022
  def convert opts = {}
    parse unless @parsed
    unless @safe >= SafeMode::SERVER || opts.empty?
      # QUESTION should we store these on the Document object?
      @attributes.delete 'outfile' unless (@attributes['outfile'] = opts['outfile'])
      @attributes.delete 'outdir' unless (@attributes['outdir'] = opts['outdir'])
    end

    # QUESTION should we add processors that execute before conversion begins?
    unless @converter
      fail %(asciidoctor: FAILED: missing converter for backend '#{backend}'. Processing aborted.)
    end

    if doctype == 'inline'
      # QUESTION should we warn if @blocks.size > 0 and the first block is not a paragraph?
      if (block = @blocks[0]) && block.content_model != :compound
        output = block.content
      else
        output = nil
      end
    else
      transform = ((opts.key? :header_footer) ? opts[:header_footer] : @options[:header_footer]) ? 'document' : 'embedded'
      output = @converter.convert self, transform
    end

    unless @parent_document
      if (exts = @extensions) && exts.postprocessors?
        exts.postprocessors.each do |ext|
          output = ext.process_method[self, output]
        end
      end
    end

    output
  end