# File lib/asciidoctor/converter/html5.rb, line 32
    def document node
      result = []
      slash = @void_element_slash
      br = %(<br#{slash}>)
      unless (asset_uri_scheme = (node.attr 'asset-uri-scheme', 'https')).empty?
        asset_uri_scheme = %(#{asset_uri_scheme}:)
      end
      cdn_base = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
      linkcss = node.safe >= SafeMode::SECURE || (node.attr? 'linkcss')
      result << '<!DOCTYPE html>'
      lang_attribute = (node.attr? 'nolang') ? nil : %( lang="#{node.attr 'lang', 'en'}")
      result << %(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : nil}#{lang_attribute}>)
      result << %(<head>
<meta charset="#{node.attr 'encoding', 'UTF-8'}"#{slash}>
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"#{slash}><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"#{slash}>
<meta name="generator" content="Asciidoctor #{node.attr 'asciidoctor-version'}"#{slash}>)
      result << %(<meta name="application-name" content="#{node.attr 'app-name'}"#{slash}>) if node.attr? 'app-name'
      result << %(<meta name="description" content="#{node.attr 'description'}"#{slash}>) if node.attr? 'description'
      result << %(<meta name="keywords" content="#{node.attr 'keywords'}"#{slash}>) if node.attr? 'keywords'
      result << %(<meta name="author" content="#{node.attr 'authors'}"#{slash}>) if node.attr? 'authors'
      result << %(<meta name="copyright" content="#{node.attr 'copyright'}"#{slash}>) if node.attr? 'copyright'
      result << %(<title>#{node.doctitle :sanitize => true, :use_fallback => true}</title>)

      if DEFAULT_STYLESHEET_KEYS.include?(node.attr 'stylesheet')
        if (webfonts = node.attr 'webfonts')
          result << %(<link rel="stylesheet" href="#{asset_uri_scheme}//fonts.googleapis.com/css?family=#{webfonts.empty? ? 'Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700' : webfonts}"#{slash}>)
        end
        if linkcss
          result << %(<link rel="stylesheet" href="#{node.normalize_web_path DEFAULT_STYLESHEET_NAME, (node.attr 'stylesdir', ''), false}"#{slash}>)
        else
          result << @stylesheets.embed_primary_stylesheet
        end
      elsif node.attr? 'stylesheet'
        if linkcss
          result << %(<link rel="stylesheet" href="#{node.normalize_web_path((node.attr 'stylesheet'), (node.attr 'stylesdir', ''))}"#{slash}>)
        else
          result << %(<style>
#{node.read_asset node.normalize_system_path((node.attr 'stylesheet'), (node.attr 'stylesdir', '')), :warn_on_failure => true}
</style>)
        end
      end

      if node.attr? 'icons', 'font'
        if node.attr? 'iconfont-remote'
          result << %(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/4.5.0/css/font-awesome.min.css]}"#{slash}>)
        else
          iconfont_stylesheet = %(#{node.attr 'iconfont-name', 'font-awesome'}.css)
          result << %(<link rel="stylesheet" href="#{node.normalize_web_path iconfont_stylesheet, (node.attr 'stylesdir', ''), false}"#{slash}>)
        end
      end

      case (highlighter = node.attr 'source-highlighter')
      when 'coderay'
        if (node.attr 'coderay-css', 'class') == 'class'
          if linkcss
            result << %(<link rel="stylesheet" href="#{node.normalize_web_path @stylesheets.coderay_stylesheet_name, (node.attr 'stylesdir', ''), false}"#{slash}>)
          else
            result << @stylesheets.embed_coderay_stylesheet
          end
        end
      when 'pygments'
        if (node.attr 'pygments-css', 'class') == 'class'
          pygments_style = node.attr 'pygments-style'
          if linkcss
            result << %(<link rel="stylesheet" href="#{node.normalize_web_path @stylesheets.pygments_stylesheet_name(pygments_style), (node.attr 'stylesdir', ''), false}"#{slash}>)
          else
            result << (@stylesheets.embed_pygments_stylesheet pygments_style)
          end
        end
      end

      unless (docinfo_content = node.docinfo).empty?
        result << docinfo_content
      end

      result << '</head>'
      body_attrs = []
      body_attrs << %(id="#{node.id}") if node.id
      if (sectioned = node.sections?) && (node.attr? 'toc-class') && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
        body_attrs << %(class="#{node.doctype} #{node.attr 'toc-class'} toc-#{node.attr 'toc-position', 'header'}")
      else
        body_attrs << %(class="#{node.doctype}")
      end
      body_attrs << %(style="max-width: #{node.attr 'max-width'};") if node.attr? 'max-width'
      result << %(<body #{body_attrs * ' '}>)

      unless node.noheader
        result << '<div id="header">'
        if node.doctype == 'manpage'
          result << %(<h1>#{node.doctitle} Manual Page</h1>)
          if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
            result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
<div id="toctitle">#{node.attr 'toc-title'}</div>
#{outline node}
</div>)
          end
          # QUESTION should this h2 have an auto-generated id?
          result << %(<h2>#{node.attr 'manname-title'}</h2>
<div class="sectionbody">
<p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
</div>)
        else
          if node.has_header?
            result << %(<h1>#{node.header.title}</h1>) unless node.notitle
            details = []
            if node.attr? 'author'
              details << %(<span id="author" class="author">#{node.attr 'author'}</span>#{br})
              if node.attr? 'email'
                details << %(<span id="email" class="email">#{node.sub_macros(node.attr 'email')}</span>#{br})
              end
              if (authorcount = (node.attr 'authorcount').to_i) > 1
                (2..authorcount).each do |idx|
                  details << %(<span id="author#{idx}" class="author">#{node.attr "author_#{idx}"}</span>#{br})
                  if node.attr? %(email_#{idx})
                    details << %(<span id="email#{idx}" class="email">#{node.sub_macros(node.attr "email_#{idx}")}</span>#{br})
                  end
                end
              end
            end
            if node.attr? 'revnumber'
              details << %(<span id="revnumber">#{((node.attr 'version-label') || '').downcase} #{node.attr 'revnumber'}#{(node.attr? 'revdate') ? ',' : ''}</span>)
            end
            if node.attr? 'revdate'
              details << %(<span id="revdate">#{node.attr 'revdate'}</span>)
            end
            if node.attr? 'revremark'
              details << %(#{br}<span id="revremark">#{node.attr 'revremark'}</span>)
            end
            unless details.empty?
              result << '<div class="details">'
              result.concat details
              result << '</div>'
            end
          end

          if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
            result << %(<div id="toc" class="#{node.attr 'toc-class', 'toc'}">
<div id="toctitle">#{node.attr 'toc-title'}</div>
#{outline node}
</div>)
          end
        end
        result << '</div>'
      end

      result << %(<div id="content">
#{node.content}
</div>)

      if node.footnotes? && !(node.attr? 'nofootnotes')
        result << %(<div id="footnotes">
<hr#{slash}>)
        node.footnotes.each do |footnote|
          result << %(<div class="footnote" id="_footnote_#{footnote.index}">
<a href="#_footnoteref_#{footnote.index}">#{footnote.index}</a>. #{footnote.text}
</div>)
        end
        result << '</div>'
      end

      unless node.nofooter
        result << '<div id="footer">'
        result << '<div id="footer-text">'
        result << %(#{node.attr 'version-label'} #{node.attr 'revnumber'}#{br}) if node.attr? 'revnumber'
        result << %(#{node.attr 'last-update-label'} #{node.attr 'docdatetime'}) if (node.attr? 'last-update-label') && !(node.attr? 'reproducible')
        result << '</div>'
        result << '</div>'
      end

      unless (docinfo_content = node.docinfo :footer).empty?
        result << docinfo_content
      end

      # Load Javascript at the end of body for performance
      # See http://www.html5rocks.com/en/tutorials/speed/script-loading/
      case highlighter
      when 'highlightjs', 'highlight.js'
        highlightjs_path = node.attr 'highlightjsdir', %(#{cdn_base}/highlight.js/8.9.1)
        result << %(<link rel="stylesheet" href="#{highlightjs_path}/styles/#{node.attr 'highlightjs-theme', 'github'}.min.css"#{slash}>)
        result << %(<script src="#{highlightjs_path}/highlight.min.js"></script>
<script>hljs.initHighlighting()</script>)
      when 'prettify'
        prettify_path = node.attr 'prettifydir', %(#{cdn_base}/prettify/r298)
        result << %(<link rel="stylesheet" href="#{prettify_path}/#{node.attr 'prettify-theme', 'prettify'}.min.css"#{slash}>)
        result << %(<script src="#{prettify_path}/prettify.min.js"></script>
<script>prettyPrint()</script>)
      end

      if node.attr? 'stem'
        eqnums_val = node.attr 'eqnums', 'none'
        eqnums_val = 'AMS' if eqnums_val == ''
        eqnums_opt = %( equationNumbers: { autoNumber: "#{eqnums_val}" } )
        # IMPORTANT inspect calls on delimiter arrays are intentional for JavaScript compat (emulates JSON.stringify)
        result << %(<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  messageStyle: "none",
  tex2jax: {
    inlineMath: [#{INLINE_MATH_DELIMITERS[:latexmath].inspect}],
    displayMath: [#{BLOCK_MATH_DELIMITERS[:latexmath].inspect}],
    ignoreClass: "nostem|nolatexmath"
  },
  asciimath2jax: {
    delimiters: [#{BLOCK_MATH_DELIMITERS[:asciimath].inspect}],
    ignoreClass: "nostem|noasciimath"
  },
  TeX: {#{eqnums_opt}}
});
</script>
<script src="#{cdn_base}/mathjax/2.6.0/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>)
      end

      result << '</body>'
      result << '</html>'
      result * EOL
    end