class Asciidoctor::Converter::Html5Converter - asciidoctor-1.5.6.2 Documentation

# class Asciidoctor::Converter::Html5Converter

A built-in {Converter} implementation that generates HTML 5 output consistent with the html5 backend from AsciiDoc Python.

### Constants

DimensionAttributeRx
QUOTE_TAGS
SvgPreambleRx
SvgStartTagRx

### Public Class Methods

new(backend, opts = {}) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 25
    def initialize backend, opts = {}
      @xml_mode = opts[:htmlsyntax] == 'xml'
      @void_element_slash = @xml_mode ? '/' : nil
      @stylesheets = Stylesheets.instance
    end

### Public Instance Methods

admonition(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 362
        def admonition node
          id_attr = node.id ? %Q( id="#{node.id}") : nil
          name = node.attr 'name'
          title_element = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
          if node.document.attr? 'icons'
            if (node.document.attr? 'icons', 'font') && !(node.attr? 'icon')
              label = %Q(<i class="fa icon-#{name}" title="#{node.attr 'textlabel'}"></i>)
            else
              label = %Q(<img src="#{node.icon_uri name}" alt="#{node.attr 'textlabel'}"#{@void_element_slash}>)
            end
          else
            label = %Q(<div class="title">#{node.attr 'textlabel'}</div>)
          end
          %Q(<div#{id_attr} class="admonitionblock #{name}#{(role = node.role) && " #{role}"}">
    <table>
    <tr>
    <td class="icon">
    #{label}
    </td>
    <td class="content">
    #{title_element}#{node.content}
    </td>
    </tr>
    </table>
    </div>)
        end

append_boolean_attribute(name, xml) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1160
    def append_boolean_attribute name, xml
      xml ? %Q( #{name}="#{name}") : %Q( #{name})
    end

audio(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 389
        def audio node
          xml = @xml_mode
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['audioblock', node.role].compact
          class_attribute = %Q( class="#{classes * ' '}")
          title_element = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
          start_t = node.attr 'start', nil, false
          end_t = node.attr 'end', nil, false
          time_anchor = (start_t || end_t) ? %Q(#t=#{start_t}#{end_t ? ',' : nil}#{end_t}) : nil
          %Q(<div#{id_attribute}#{class_attribute}>
    #{title_element}<div class="content">
    <audio src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}>
    Your browser does not support the audio tag.
    </audio>
    </div>
    </div>)
        end

colist(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 407
        def colist node
          result = []
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['colist', node.style, node.role].compact
          class_attribute = %Q( class="#{classes * ' '}")

          result << %Q(<div#{id_attribute}#{class_attribute}>)
          result << %Q(<div class="title">#{node.title}</div>) if node.title?

          if node.document.attr? 'icons'
            result << '<table>'
            font_icons, num = (node.document.attr? 'icons', 'font'), 0
            node.items.each do |item|
              num += 1
              if font_icons
                num_label = %Q(<i class="conum" data-value="#{num}"></i><b>#{num}</b>)
              else
                num_label = %Q(<img src="#{node.icon_uri "callouts/#{num}"}" alt="#{num}"#{@void_element_slash}>)
              end
              result << %Q(<tr>
    <td>#{num_label}</td>
    <td>#{item.text}#{item.blocks? ? LF + item.content : ''}</td>
    </tr>)
            end
            result << '</table>'
          else
            result << '<ol>'
            node.items.each do |item|
              result << %Q(<li>
    <p>#{item.text}</p>#{item.blocks? ? LF + item.content : ''}
    </li>)
            end
            result << '</ol>'
          end

          result << '</div>'
          result * LF
        end

dlist(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 446
    def dlist node
      result = []
      id_attribute = node.id ? %Q( id="#{node.id}") : nil

      classes = case node.style
      when 'qanda'
        ['qlist', 'qanda', node.role]
      when 'horizontal'
        ['hdlist', node.role]
      else
        ['dlist', node.style, node.role]
      end.compact

      class_attribute = %Q( class="#{classes * ' '}")

      result << %Q(<div#{id_attribute}#{class_attribute}>)
      result << %Q(<div class="title">#{node.title}</div>) if node.title?
      case node.style
      when 'qanda'
        result << '<ol>'
        node.items.each do |terms, dd|
          result << '<li>'
          [*terms].each do |dt|
            result << %Q(<p><em>#{dt.text}</em></p>)
          end
          if dd
            result << %Q(<p>#{dd.text}</p>) if dd.text?
            result << dd.content if dd.blocks?
          end
          result << '</li>'
        end
        result << '</ol>'
      when 'horizontal'
        slash = @void_element_slash
        result << '<table>'
        if (node.attr? 'labelwidth') || (node.attr? 'itemwidth')
          result << '<colgroup>'
          col_style_attribute = (node.attr? 'labelwidth') ? %Q( style="width: #{(node.attr 'labelwidth').chomp '%'}%;") : nil
          result << %Q(<col#{col_style_attribute}#{slash}>)
          col_style_attribute = (node.attr? 'itemwidth') ? %Q( style="width: #{(node.attr 'itemwidth').chomp '%'}%;") : nil
          result << %Q(<col#{col_style_attribute}#{slash}>)
          result << '</colgroup>'
        end
        node.items.each do |terms, dd|
          result << '<tr>'
          result << %Q(<td class="hdlist1#{(node.option? 'strong') ? ' strong' : nil}">)
          terms_array = [*terms]
          last_term = terms_array[-1]
          terms_array.each do |dt|
            result << dt.text
            result << %Q(<br#{slash}>) if dt != last_term
          end
          result << '</td>'
          result << '<td class="hdlist2">'
          if dd
            result << %Q(<p>#{dd.text}</p>) if dd.text?
            result << dd.content if dd.blocks?
          end
          result << '</td>'
          result << '</tr>'
        end
        result << '</table>'
      else
        result << '<dl>'
        dt_style_attribute = node.style ? nil : ' class="hdlist1"'
        node.items.each do |terms, dd|
          [*terms].each do |dt|
            result << %Q(<dt#{dt_style_attribute}>#{dt.text}</dt>)
          end
          if dd
            result << '<dd>'
            result << %Q(<p>#{dd.text}</p>) if dd.text?
            result << dd.content if dd.blocks?
            result << '</dd>'
          end
        end
        result << '</dl>'
      end

      result << '</div>'
      result * LF
    end

document(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 31
        def document node
          slash = @void_element_slash
          br = %Q(<br#{slash}>)
          unless (asset_uri_scheme = (node.attr 'asset-uri-scheme', 'https')).empty?
            asset_uri_scheme = %Q(#{asset_uri_scheme}:)
          end
          cdn_base = %Q(#{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 : %Q( lang="#{node.attr 'lang', 'en'}")
          result << %Q(<html#{@xml_mode ? ' xmlns="http://www.w3.org/1999/xhtml"' : nil}#{lang_attribute}>)
          result << %Q(<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 << %Q(<meta name="application-name" content="#{node.attr 'app-name'}"#{slash}>) if node.attr? 'app-name'
          result << %Q(<meta name="description" content="#{node.attr 'description'}"#{slash}>) if node.attr? 'description'
          result << %Q(<meta name="keywords" content="#{node.attr 'keywords'}"#{slash}>) if node.attr? 'keywords'
          result << %Q(<meta name="author" content="#{((authors = node.attr 'authors').include? '<') ? (authors.gsub XmlSanitizeRx, '') : authors}"#{slash}>) if node.attr? 'authors'
          result << %Q(<meta name="copyright" content="#{node.attr 'copyright'}"#{slash}>) if node.attr? 'copyright'
          if node.attr? 'favicon'
            if (icon_href = node.attr 'favicon').empty?
              icon_href, icon_type = 'favicon.ico', 'image/x-icon'
            else
              icon_type = (icon_ext = ::File.extname icon_href) == '.ico' ? 'image/x-icon' : %Q(image/#{icon_ext[1..-1]})
            end
            result << %Q(<link rel="shortcut icon" type="#{icon_type}" href="#{icon_href}">)
          end
          result << %Q(<title>#{node.doctitle :sanitize => true, :use_fallback => true}</title>)

          if DEFAULT_STYLESHEET_KEYS.include?(node.attr 'stylesheet')
            if (webfonts = node.attr 'webfonts')
              result << %Q(<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 << %Q(<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 << %Q(<link rel="stylesheet" href="#{node.normalize_web_path((node.attr 'stylesheet'), (node.attr 'stylesdir', ''))}"#{slash}>)
            else
              result << %Q(<style>
    #{node.read_asset node.normalize_system_path((node.attr 'stylesheet'), (node.attr 'stylesdir', '')), :warn_on_failure => true, :label => 'stylesheet'}
    </style>)
            end
          end

          if node.attr? 'icons', 'font'
            if node.attr? 'iconfont-remote'
              result << %Q(<link rel="stylesheet" href="#{node.attr 'iconfont-cdn', %[#{cdn_base}/font-awesome/4.6.3/css/font-awesome.min.css]}"#{slash}>)
            else
              iconfont_stylesheet = %Q(#{node.attr 'iconfont-name', 'font-awesome'}.css)
              result << %Q(<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 << %Q(<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 << %Q(<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 << %Q(id="#{node.id}") if node.id
          if (sectioned = node.sections?) && (node.attr? 'toc-class') && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
            body_attrs << %Q(class="#{node.doctype} #{node.attr 'toc-class'} toc-#{node.attr 'toc-position', 'header'}")
          else
            body_attrs << %Q(class="#{node.doctype}")
          end
          body_attrs << %Q(style="max-width: #{node.attr 'max-width'};") if node.attr? 'max-width'
          result << %Q(<body #{body_attrs * ' '}>)

          unless node.noheader
            result << '<div id="header">'
            if node.doctype == 'manpage'
              result << %Q(<h1>#{node.doctitle} Manual Page</h1>)
              if sectioned && (node.attr? 'toc') && (node.attr? 'toc-placement', 'auto')
                result << %Q(<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 << %Q(<h2>#{node.attr 'manname-title'}</h2>
    <div class="sectionbody">
    <p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
    </div>)
            else
              if node.has_header?
                result << %Q(<h1>#{node.header.title}</h1>) unless node.notitle
                details = []
                if node.attr? 'author'
                  details << %Q(<span id="author" class="author">#{node.attr 'author'}</span>#{br})
                  if node.attr? 'email'
                    details << %Q(<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 << %Q(<span id="author#{idx}" class="author">#{node.attr "author_#{idx}"}</span>#{br})
                      if node.attr? %Q(email_#{idx})
                        details << %Q(<span id="email#{idx}" class="email">#{node.sub_macros(node.attr "email_#{idx}")}</span>#{br})
                      end
                    end
                  end
                end
                if node.attr? 'revnumber'
                  details << %Q(<span id="revnumber">#{((node.attr 'version-label') || '').downcase} #{node.attr 'revnumber'}#{(node.attr? 'revdate') ? ',' : ''}</span>)
                end
                if node.attr? 'revdate'
                  details << %Q(<span id="revdate">#{node.attr 'revdate'}</span>)
                end
                if node.attr? 'revremark'
                  details << %Q(#{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 << %Q(<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 << %Q(<div id="content">
    #{node.content}
    </div>)

          if node.footnotes? && !(node.attr? 'nofootnotes')
            result << %Q(<div id="footnotes">
    <hr#{slash}>)
            node.footnotes.each do |footnote|
              result << %Q(<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 << %Q(#{node.attr 'version-label'} #{node.attr 'revnumber'}#{br}) if node.attr? 'revnumber'
            result << %Q(#{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', %Q(#{cdn_base}/highlight.js/9.12.0)
            result << %Q(<link rel="stylesheet" href="#{highlightjs_path}/styles/#{node.attr 'highlightjs-theme', 'github'}.min.css"#{slash}>)
            result << %Q(<script src="#{highlightjs_path}/highlight.min.js"></script>
    <script>hljs.initHighlighting()</script>)
          when 'prettify'
            prettify_path = node.attr 'prettifydir', %Q(#{cdn_base}/prettify/r298)
            result << %Q(<link rel="stylesheet" href="#{prettify_path}/#{node.attr 'prettify-theme', 'prettify'}.min.css"#{slash}>)
            result << %Q(<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.empty?
            eqnums_opt = %Q( equationNumbers: { autoNumber: "#{eqnums_val}" } )
            # IMPORTANT inspect calls on delimiter arrays are intentional for JavaScript compat (emulates JSON.stringify)
            result << %Q(<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 * LF
        end

embedded(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 255
        def embedded node
          result = []
          if node.doctype == 'manpage'
            # QUESTION should notitle control the manual page title?
            unless node.notitle
              id_attr = node.id ? %Q( id="#{node.id}") : nil
              result << %Q(<h1#{id_attr}>#{node.doctitle} Manual Page</h1>)
            end
            # QUESTION should this h2 have an auto-generated id?
            result << %Q(<h2>#{node.attr 'manname-title'}</h2>
    <div class="sectionbody">
    <p>#{node.attr 'manname'} - #{node.attr 'manpurpose'}</p>
    </div>)
          else
            if node.has_header? && !node.notitle
              id_attr = node.id ? %Q( id="#{node.id}") : nil
              result << %Q(<h1#{id_attr}>#{node.header.title}</h1>)
            end
          end

          if node.sections? && (node.attr? 'toc') && (toc_p = node.attr 'toc-placement') != 'macro' && toc_p != 'preamble'
            result << %Q(<div id="toc" class="toc">
    <div id="toctitle">#{node.attr 'toc-title'}</div>
    #{outline node}
    </div>)
          end

          result << node.content

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

          result * LF
        end

encode_quotes(val) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1164
    def encode_quotes val
      (val.include? '"') ? (val.gsub '"', '&quot;') : val
    end

example(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 529
        def example node
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          title_element = node.title? ? %Q(<div class="title">#{node.captioned_title}</div>\n) : nil

          %Q(<div#{id_attribute} class="exampleblock#{(role = node.role) && " #{role}"}">
    #{title_element}<div class="content">
    #{node.content}
    </div>
    </div>)
        end

floating_title(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 540
    def floating_title node
      tag_name = %Q(h#{node.level + 1})
      id_attribute = node.id ? %Q( id="#{node.id}") : nil
      classes = [node.style, node.role].compact
      %Q(<#{tag_name}#{id_attribute} class="#{classes * ' '}">#{node.title}</#{tag_name}>)
    end

image(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 547
        def image node
          target = node.attr 'target'
          width_attr = (node.attr? 'width') ? %Q( width="#{node.attr 'width'}") : nil
          height_attr = (node.attr? 'height') ? %Q( height="#{node.attr 'height'}") : nil
          if ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) && node.document.safe < SafeMode::SECURE &&
              ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
            if svg
              img = (read_svg_contents node, target) || %Q(<span class="alt">#{node.alt}</span>)
            elsif obj
              fallback = (node.attr? 'fallback') ? %Q(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_quotes node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>) : %Q(<span class="alt">#{node.alt}</span>)
              img = %Q(<object type="image/svg+xml" data="#{node.image_uri target}"#{width_attr}#{height_attr}>#{fallback}</object>)
            end
          end
          img ||= %Q(<img src="#{node.image_uri target}" alt="#{encode_quotes node.alt}"#{width_attr}#{height_attr}#{@void_element_slash}>)
          if node.attr? 'link'
            window_attr = %Q( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window'
            img = %Q(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
          end
          id_attr = node.id ? %Q( id="#{node.id}") : nil
          classes = ['imageblock', node.role].compact
          class_attr = %Q( class="#{classes * ' '}")
          styles = []
          styles << %Q(text-align: #{node.attr 'align'}) if node.attr? 'align'
          styles << %Q(float: #{node.attr 'float'}) if node.attr? 'float'
          style_attr = styles.empty? ? nil : %Q( style="#{styles * ';'}")
          title_el = node.title? ? %Q(\n<div class="title">#{node.captioned_title}</div>) : nil
          %Q(<div#{id_attr}#{class_attr}#{style_attr}>
    <div class="content">
    #{img}
    </div>#{title_el}
    </div>)
        end

inline_anchor(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1024
    def inline_anchor node
      case node.type
      when :xref
        unless (text = node.text) || (text = node.attributes['path'])
          if AbstractNode === (ref = node.document.catalog[:refs][refid = node.attributes['refid']])
            text = ref.xreftext((@xrefstyle ||= node.document.attributes['xrefstyle'])) || %Q([#{refid}])
          else
            text = %Q([#{refid}])
          end
        end
        %Q(<a href="#{node.target}">#{text}</a>)
      when :ref
        %Q(<a id="#{node.id}"></a>)
      when :link
        attrs = node.id ? [%Q( id="#{node.id}")] : []
        if (role = node.role)
          attrs << %Q( class="#{role}")
        end
        attrs << %Q( title="#{node.attr 'title'}") if node.attr? 'title', nil, false
        attrs << %Q( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window', nil, false
        %Q(<a href="#{node.target}"#{attrs.join}>#{node.text}</a>)
      when :bibref
        # NOTE technically node.text should be node.reftext, but subs have already been applied to text
        %Q(<a id="#{node.id}"></a>#{node.text})
      else
        warn %Q(asciidoctor: WARNING: unknown anchor type: #{node.type.inspect})
      end
    end

inline_break(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1053
    def inline_break node
      %Q(#{node.text}<br#{@void_element_slash}>)
    end

inline_button(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1057
    def inline_button node
      %Q(<b class="button">#{node.text}</b>)
    end

inline_callout(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1061
    def inline_callout node
      if node.document.attr? 'icons', 'font'
        %Q(<i class="conum" data-value="#{node.text}"></i><b>(#{node.text})</b>)
      elsif node.document.attr? 'icons'
        src = node.icon_uri("callouts/#{node.text}")
        %Q(<img src="#{src}" alt="#{node.text}"#{@void_element_slash}>)
      else
        %Q(<b class="conum">(#{node.text})</b>)
      end
    end

inline_footnote(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1072
    def inline_footnote node
      if (index = node.attr 'index', nil, false)
        if node.type == :xref
          %Q(<sup class="footnoteref">[<a class="footnote" href="#_footnote_#{index}" title="View footnote.">#{index}</a>]</sup>)
        else
          id_attr = node.id ? %Q( id="_footnote_#{node.id}") : nil
          %Q(<sup class="footnote"#{id_attr}>[<a id="_footnoteref_#{index}" class="footnote" href="#_footnote_#{index}" title="View footnote.">#{index}</a>]</sup>)
        end
      elsif node.type == :xref
        %Q(<sup class="footnoteref red" title="Unresolved footnote reference.">[#{node.text}]</sup>)
      end
    end

inline_image(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1085
    def inline_image node
      if (type = node.type) == 'icon' && (node.document.attr? 'icons', 'font')
        class_attr_val = %Q(fa fa-#{node.target})
        {'size' => 'fa-', 'rotate' => 'fa-rotate-', 'flip' => 'fa-flip-'}.each do |key, prefix|
          class_attr_val = %Q(#{class_attr_val} #{prefix}#{node.attr key}) if node.attr? key
        end
        title_attr = (node.attr? 'title') ? %Q( title="#{node.attr 'title'}") : nil
        img = %Q(<i class="#{class_attr_val}"#{title_attr}></i>)
      elsif type == 'icon' && !(node.document.attr? 'icons')
        img = %Q([#{node.alt}])
      else
        target = node.target
        attrs = ['width', 'height', 'title'].map {|name| (node.attr? name) ? %Q( #{name}="#{node.attr name}") : nil }.join
        if type != 'icon' && ((node.attr? 'format', 'svg', false) || (target.include? '.svg')) &&
            node.document.safe < SafeMode::SECURE && ((svg = (node.option? 'inline')) || (obj = (node.option? 'interactive')))
          if svg
            img = (read_svg_contents node, target) || %Q(<span class="alt">#{node.alt}</span>)
          elsif obj
            fallback = (node.attr? 'fallback') ? %Q(<img src="#{node.image_uri(node.attr 'fallback')}" alt="#{encode_quotes node.alt}"#{attrs}#{@void_element_slash}>) : %Q(<span class="alt">#{node.alt}</span>)
            img = %Q(<object type="image/svg+xml" data="#{node.image_uri target}"#{attrs}>#{fallback}</object>)
          end
        end
        img ||= %Q(<img src="#{type == 'icon' ? (node.icon_uri target) : (node.image_uri target)}" alt="#{encode_quotes node.alt}"#{attrs}#{@void_element_slash}>)
      end
      if node.attr? 'link'
        window_attr = %Q( target="#{window = node.attr 'window'}"#{window == '_blank' || (node.option? 'noopener') ? ' rel="noopener"' : ''}) if node.attr? 'window'
        img = %Q(<a class="image" href="#{node.attr 'link'}"#{window_attr}>#{img}</a>)
      end
      class_attr_val = (role = node.role) ? %Q(#{type} #{role}) : type
      style_attr = (node.attr? 'float') ? %Q( style="float: #{node.attr 'float'}") : nil
      %Q(<span class="#{class_attr_val}"#{style_attr}>#{img}</span>)
    end

inline_indexterm(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1118
    def inline_indexterm node
      node.type == :visible ? node.text : ''
    end

inline_kbd(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1122
    def inline_kbd node
      if (keys = node.attr 'keys').size == 1
        %Q(<kbd>#{keys[0]}</kbd>)
      else
        %Q(<span class="keyseq"><kbd>#{keys * '</kbd>+<kbd>'}</kbd></span>)
      end
    end

inline_quoted(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1145
    def inline_quoted node
      open, close, is_tag = QUOTE_TAGS[node.type]
      if node.role
        if is_tag
          quoted_text = %Q(#{open.chop} class="#{node.role}">#{node.text}#{close})
        else
          quoted_text = %Q(<span class="#{node.role}">#{open}#{node.text}#{close}</span>)
        end
      else
        quoted_text = %Q(#{open}#{node.text}#{close})
      end

      node.id ? %Q(<a id="#{node.id}"></a>#{quoted_text}) : quoted_text
    end

listing(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 580
        def listing node
          nowrap = !(node.document.attr? 'prewrap') || (node.option? 'nowrap')
          if node.style == 'source'
            if (language = node.attr 'language', nil, false)
              code_attrs = %Q( data-lang="#{language}")
            else
              code_attrs = nil
            end
            case node.document.attr 'source-highlighter'
            when 'coderay'
              pre_class = %Q( class="CodeRay highlight#{nowrap ? ' nowrap' : nil}")
            when 'pygments'
              pre_class = %Q( class="pygments highlight#{nowrap ? ' nowrap' : nil}")
            when 'highlightjs', 'highlight.js'
              pre_class = %Q( class="highlightjs highlight#{nowrap ? ' nowrap' : nil}")
              code_attrs = %Q( class="language-#{language} hljs"#{code_attrs}) if language
            when 'prettify'
              pre_class = %Q( class="prettyprint highlight#{nowrap ? ' nowrap' : nil}#{(node.attr? 'linenums', nil, false) ? ' linenums' : nil}")
              code_attrs = %Q( class="language-#{language}"#{code_attrs}) if language
            when 'html-pipeline'
              pre_class = language ? %Q( lang="#{language}") : nil
              code_attrs = nil
            else
              pre_class = %Q( class="highlight#{nowrap ? ' nowrap' : nil}")
              code_attrs = %Q( class="language-#{language}"#{code_attrs}) if language
            end
            pre_start = %Q(<pre#{pre_class}><code#{code_attrs}>)
            pre_end = '</code></pre>'
          else
            pre_start = %Q(<pre#{nowrap ? ' class="nowrap"' : nil}>)
            pre_end = '</pre>'
          end

          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          title_element = node.title? ? %Q(<div class="title">#{node.captioned_title}</div>\n) : nil
          %Q(<div#{id_attribute} class="listingblock#{(role = node.role) && " #{role}"}">
    #{title_element}<div class="content">
    #{pre_start}#{node.content}#{pre_end}
    </div>
    </div>)
        end

literal(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 622
        def literal node
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          title_element = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
          nowrap = !(node.document.attr? 'prewrap') || (node.option? 'nowrap')
          %Q(<div#{id_attribute} class="literalblock#{(role = node.role) && " #{role}"}">
    #{title_element}<div class="content">
    <pre#{nowrap ? ' class="nowrap"' : nil}>#{node.content}</pre>
    </div>
    </div>)
        end

olist(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 649
    def olist node
      result = []
      id_attribute = node.id ? %Q( id="#{node.id}") : nil
      classes = ['olist', node.style, node.role].compact
      class_attribute = %Q( class="#{classes * ' '}")

      result << %Q(<div#{id_attribute}#{class_attribute}>)
      result << %Q(<div class="title">#{node.title}</div>) if node.title?

      type_attribute = (keyword = node.list_marker_keyword) ? %Q( type="#{keyword}") : nil
      start_attribute = (node.attr? 'start') ? %Q( start="#{node.attr 'start'}") : nil
      reversed_attribute = (node.option? 'reversed') ? (append_boolean_attribute 'reversed', @xml_mode) : nil
      result << %Q(<ol class="#{node.style}"#{type_attribute}#{start_attribute}#{reversed_attribute}>)

      node.items.each do |item|
        result << '<li>'
        result << %Q(<p>#{item.text}</p>)
        result << item.content if item.blocks?
        result << '</li>'
      end

      result << '</ol>'
      result << '</div>'
      result * LF
    end

open(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 675
        def open node
          if (style = node.style) == 'abstract'
            if node.parent == node.document && node.document.doctype == 'book'
              warn 'asciidoctor: WARNING: abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
              ''
            else
              id_attr = node.id ? %Q( id="#{node.id}") : nil
              title_el = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
              %Q(<div#{id_attr} class="quoteblock abstract#{(role = node.role) && " #{role}"}">
    #{title_el}<blockquote>
    #{node.content}
    </blockquote>
    </div>)
            end
          elsif style == 'partintro' && (node.level > 0 || node.parent.context != :section || node.document.doctype != 'book')
            warn 'asciidoctor: ERROR: partintro block can only be used when doctype is book and it\s a child of a book part. Excluding block content.'
            ''
          else
              id_attr = node.id ? %Q( id="#{node.id}") : nil
              title_el = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
            %Q(<div#{id_attr} class="openblock#{style && style != 'open' ? " #{style}" : ''}#{(role = node.role) && " #{role}"}">
    #{title_el}<div class="content">
    #{node.content}
    </div>
    </div>)
          end
        end

outline(node, opts = {}) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 298
    def outline node, opts = {}
      return unless node.sections?
      sectnumlevels = opts[:sectnumlevels] || (node.document.attr 'sectnumlevels', 3).to_i
      toclevels = opts[:toclevels] || (node.document.attr 'toclevels', 2).to_i
      sections = node.sections
      # FIXME top level is incorrect if a multipart book starts with a special section defined at level 0
      result = [%Q(<ul class="sectlevel#{sections[0].level}">)]
      sections.each do |section|
        slevel = section.level
        if section.caption
          stitle = section.captioned_title
        elsif section.numbered && slevel <= sectnumlevels
          stitle = %Q(#{section.sectnum} #{section.title})
        else
          stitle = section.title
        end
        if slevel < toclevels && (child_toc_level = outline section, :toclevels => toclevels, :secnumlevels => sectnumlevels)
          result << %Q(<li><a href="##{section.id}">#{stitle}</a>)
          result << child_toc_level
          result << '</li>'
        else
          result << %Q(<li><a href="##{section.id}">#{stitle}</a></li>)
        end
      end
      result << '</ul>'
      result * LF
    end

page_break(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 703
    def page_break node
      '<div style="page-break-after: always;"></div>'
    end

paragraph(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 707
        def paragraph node
          class_attribute = node.role ? %Q(class="paragraph #{node.role}") : 'class="paragraph"'
          attributes = node.id ? %Q(id="#{node.id}" #{class_attribute}) : class_attribute

          if node.title?
            %Q(<div #{attributes}>
    <div class="title">#{node.title}</div>
    <p>#{node.content}</p>
    </div>)
          else
            %Q(<div #{attributes}>
    <p>#{node.content}</p>
    </div>)
          end
        end

preamble(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 723
        def preamble node
          if (doc = node.document).attr?('toc-placement', 'preamble') && doc.sections? && (doc.attr? 'toc')
            toc = %Q(
    <div id="toc" class="#{doc.attr 'toc-class', 'toc'}">
    <div id="toctitle">#{doc.attr 'toc-title'}</div>
    #{outline doc}
    </div>)
          else
            toc = nil
          end

          %Q(<div id="preamble">
    <div class="sectionbody">
    #{node.content}
    </div>#{toc}
    </div>)
        end

quote(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 741
        def quote node
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['quoteblock', node.role].compact
          class_attribute = %Q( class="#{classes * ' '}")
          title_element = node.title? ? %Q(\n<div class="title">#{node.title}</div>) : nil
          attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
          citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
          if attribution || citetitle
            cite_element = citetitle ? %Q(<cite>#{citetitle}</cite>) : nil
            attribution_text = attribution ? %Q(&#8212; #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" : nil}) : nil
            attribution_element = %Q(\n<div class="attribution">\n#{attribution_text}#{cite_element}\n</div>)
          else
            attribution_element = nil
          end

          %Q(<div#{id_attribute}#{class_attribute}>#{title_element}
    <blockquote>
    #{node.content}
    </blockquote>#{attribution_element}
    </div>)
        end

read_svg_contents(node, target) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 1168
    def read_svg_contents node, target
      if (svg = node.read_contents target, :start => (node.document.attr 'imagesdir'), :normalize => true, :label => 'SVG')
        svg = svg.sub SvgPreambleRx, '' unless svg.start_with? '<svg'
        old_start_tag = new_start_tag = nil
        # NOTE width, height and style attributes are removed if either width or height is specified
        ['width', 'height'].each do |dim|
          if node.attr? dim
            new_start_tag = (old_start_tag = (svg.match SvgStartTagRx)[0]).gsub DimensionAttributeRx, '' unless new_start_tag
            # QUESTION should we add px since it's already the default?
            new_start_tag = %Q(#{new_start_tag.chop} #{dim}="#{node.attr dim}px">)
          end
        end
        svg = %Q(#{new_start_tag}#{svg[old_start_tag.length..-1]}) if new_start_tag
      end
      svg
    end

section(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 326
        def section node
          slevel = node.level
          htag = %Q(h#{slevel + 1})
          id_attr = anchor = link_start = link_end = nil
          if node.id
            id_attr = %Q( id="#{id = node.id}")
            if (doc = node.document).attr? 'sectanchors'
              anchor = %Q(<a class="anchor" href="##{id}"></a>)
              # possible idea - anchor icons GitHub-style
              #if doc.attr? 'icons', 'font'
              #  anchor = %(<a class="anchor" href="##{id}"><i class="fa fa-anchor"></i></a>)
              #else
              #  anchor = %(<a class="anchor" href="##{id}"></a>)
              #end
            end
            if doc.attr? 'sectlinks'
              link_start = %Q(<a class="link" href="##{id}">)
              link_end = '</a>'
            end
          end

          if slevel == 0
            %Q(<h1#{id_attr} class="sect0">#{anchor}#{link_start}#{node.title}#{link_end}</h1>
    #{node.content})
          else
            class_attr = (role = node.role) ? %Q( class="sect#{slevel} #{role}") : %Q( class="sect#{slevel}")
            sectnum = if node.numbered && !node.caption && slevel <= (node.document.attr 'sectnumlevels', 3).to_i
              %Q(#{node.sectnum} )
            end
            %Q(<div#{class_attr}>
    <#{htag}#{id_attr}>#{anchor}#{link_start}#{sectnum}#{node.captioned_title}#{link_end}</#{htag}>
    #{slevel == 1 ? %[<div class="sectionbody">\n#{node.content}\n</div>] : node.content}
    </div>)
          end
        end

stem(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 633
        def stem node
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          title_element = node.title? ? %Q(<div class="title">#{node.title}</div>\n) : nil
          open, close = BLOCK_MATH_DELIMITERS[node.style.to_sym]

          unless ((equation = node.content).start_with? open) && (equation.end_with? close)
            equation = %Q(#{open}#{equation}#{close})
          end

          %Q(<div#{id_attribute} class="stemblock#{(role = node.role) && " #{role}"}">
    #{title_element}<div class="content">
    #{equation}
    </div>
    </div>)
        end

table(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 777
        def table node
          result = []
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['tableblock', %Q(frame-#{node.attr 'frame', 'all'}), %Q(grid-#{node.attr 'grid', 'all'})]
          styles = []
          unless (node.option? 'autowidth') && !(node.attr? 'width', nil, false)
            if node.attr? 'tablepcwidth', 100
              classes << 'spread'
            else
              styles << %Q(width: #{node.attr 'tablepcwidth'}%;)
            end
          end
          if (role = node.role)
            classes << role
          end
          class_attribute = %Q( class="#{classes * ' '}")
          styles << %Q(float: #{node.attr 'float'};) if node.attr? 'float'
          style_attribute = styles.empty? ? nil : %Q( style="#{styles * ' '}")

          result << %Q(<table#{id_attribute}#{class_attribute}#{style_attribute}>)
          result << %Q(<caption class="title">#{node.captioned_title}</caption>) if node.title?
          if (node.attr 'rowcount') > 0
            slash = @void_element_slash
            result << '<colgroup>'
            if node.option? 'autowidth'
              tag = %Q(<col#{slash}>)
              node.columns.size.times do
                result << tag
              end
            else
              node.columns.each do |col|
                result << %Q(<col style="width: #{col.attr 'colpcwidth'}%;"#{slash}>)
              end
            end
            result << '</colgroup>'
            node.rows.by_section.each do |tsec, rows|
              next if rows.empty?
              result << %Q(<t#{tsec}>)
              rows.each do |row|
                result << '<tr>'
                row.each do |cell|
                  if tsec == :head
                    cell_content = cell.text
                  else
                    case cell.style
                    when :asciidoc
                      cell_content = %Q(<div>#{cell.content}</div>)
                    when :verse
                      cell_content = %Q(<div class="verse">#{cell.text}</div>)
                    when :literal
                      cell_content = %Q(<div class="literal"><pre>#{cell.text}</pre></div>)
                    else
                      cell_content = (cell_content = cell.content).empty? ? '' : %Q(<p class="tableblock">#{cell_content * '</p>
    <p class="tableblock">'}</p>)
                    end
                  end

                  cell_tag_name = (tsec == :head || cell.style == :header ? 'th' : 'td')
                  cell_class_attribute = %Q( class="tableblock halign-#{cell.attr 'halign'} valign-#{cell.attr 'valign'}")
                  cell_colspan_attribute = cell.colspan ? %Q( colspan="#{cell.colspan}") : nil
                  cell_rowspan_attribute = cell.rowspan ? %Q( rowspan="#{cell.rowspan}") : nil
                  cell_style_attribute = (node.document.attr? 'cellbgcolor') ? %Q( style="background-color: #{node.document.attr 'cellbgcolor'};") : nil
                  result << %Q(<#{cell_tag_name}#{cell_class_attribute}#{cell_colspan_attribute}#{cell_rowspan_attribute}#{cell_style_attribute}>#{cell_content}</#{cell_tag_name}>)
                end
                result << '</tr>'
              end
              result << %Q(</t#{tsec}>)
            end
          end
          result << '</table>'
          result * LF
        end

thematic_break(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 763
    def thematic_break node
      %Q(<hr#{@void_element_slash}>)
    end

ulist(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 872
    def ulist node
      result = []
      id_attribute = node.id ? %Q( id="#{node.id}") : nil
      div_classes = ['ulist', node.style, node.role].compact
      marker_checked = nil
      marker_unchecked = nil
      if (checklist = node.option? 'checklist')
        div_classes.unshift div_classes.shift, 'checklist'
        ul_class_attribute = ' class="checklist"'
        if node.option? 'interactive'
          if @xml_mode
            marker_checked = '<input type="checkbox" data-item-complete="1" checked="checked"/> '
            marker_unchecked = '<input type="checkbox" data-item-complete="0"/> '
          else
            marker_checked = '<input type="checkbox" data-item-complete="1" checked> '
            marker_unchecked = '<input type="checkbox" data-item-complete="0"> '
          end
        else
          if node.document.attr? 'icons', 'font'
            marker_checked = '<i class="fa fa-check-square-o"></i> '
            marker_unchecked = '<i class="fa fa-square-o"></i> '
          else
            marker_checked = '&#10003; '
            marker_unchecked = '&#10063; '
          end
        end
      else
        ul_class_attribute = node.style ? %Q( class="#{node.style}") : nil
      end
      result << %Q(<div#{id_attribute} class="#{div_classes * ' '}">)
      result << %Q(<div class="title">#{node.title}</div>) if node.title?
      result << %Q(<ul#{ul_class_attribute}>)

      node.items.each do |item|
        result << '<li>'
        if checklist && (item.attr? 'checkbox')
          result << %Q(<p>#{(item.attr? 'checked') ? marker_checked : marker_unchecked}#{item.text}</p>)
        else
          result << %Q(<p>#{item.text}</p>)
        end
        result << item.content if item.blocks?
        result << '</li>'
      end

      result << '</ul>'
      result << '</div>'
      result * LF
    end

verse(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 921
        def verse node
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['verseblock', node.role].compact
          class_attribute = %Q( class="#{classes * ' '}")
          title_element = node.title? ? %Q(\n<div class="title">#{node.title}</div>) : nil
          attribution = (node.attr? 'attribution') ? (node.attr 'attribution') : nil
          citetitle = (node.attr? 'citetitle') ? (node.attr 'citetitle') : nil
          if attribution || citetitle
            cite_element = citetitle ? %Q(<cite>#{citetitle}</cite>) : nil
            attribution_text = attribution ? %Q(&#8212; #{attribution}#{citetitle ? "<br#{@void_element_slash}>\n" : nil}) : nil
            attribution_element = %Q(\n<div class="attribution">\n#{attribution_text}#{cite_element}\n</div>)
          else
            attribution_element = nil
          end

          %Q(<div#{id_attribute}#{class_attribute}>#{title_element}
    <pre class="content">#{node.content}</pre>#{attribution_element}
    </div>)
        end

video(node) click to toggle source

    # File lib/asciidoctor/converter/html5.rb, line 941
        def video node
          xml = @xml_mode
          id_attribute = node.id ? %Q( id="#{node.id}") : nil
          classes = ['videoblock', node.role].compact
          class_attribute = %Q( class="#{classes * ' '}")
          title_element = node.title? ? %Q(\n<div class="title">#{node.title}</div>) : nil
          width_attribute = (node.attr? 'width') ? %Q( width="#{node.attr 'width'}") : nil
          height_attribute = (node.attr? 'height') ? %Q( height="#{node.attr 'height'}") : nil
          case node.attr 'poster'
          when 'vimeo'
            unless (asset_uri_scheme = (node.document.attr 'asset-uri-scheme', 'https')).empty?
              asset_uri_scheme = %Q(#{asset_uri_scheme}:)
            end
            start_anchor = (node.attr? 'start', nil, false) ? %Q(#at=#{node.attr 'start'}) : nil
            delimiter = '?'
            autoplay_param = (node.option? 'autoplay') ? %Q(#{delimiter}autoplay=1) : nil
            delimiter = '&amp;' if autoplay_param
            loop_param = (node.option? 'loop') ? %Q(#{delimiter}loop=1) : nil
            %Q(<div#{id_attribute}#{class_attribute}>#{title_element}
    <div class="content">
    <iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//player.vimeo.com/video/#{node.attr 'target'}#{start_anchor}#{autoplay_param}#{loop_param}" frameborder="0"#{(node.option? 'nofullscreen') ? nil : (append_boolean_attribute 'allowfullscreen', xml)}></iframe>
    </div>
    </div>)
          when 'youtube'
            unless (asset_uri_scheme = (node.document.attr 'asset-uri-scheme', 'https')).empty?
              asset_uri_scheme = %Q(#{asset_uri_scheme}:)
            end
            rel_param_val = (node.option? 'related') ? 1 : 0
            # NOTE start and end must be seconds (t parameter allows XmYs where X is minutes and Y is seconds)
            start_param = (node.attr? 'start', nil, false) ? %Q(&amp;start=#{node.attr 'start'}) : nil
            end_param = (node.attr? 'end', nil, false) ? %Q(&amp;end=#{node.attr 'end'}) : nil
            autoplay_param = (node.option? 'autoplay') ? '&amp;autoplay=1' : nil
            loop_param = (node.option? 'loop') ? '&amp;loop=1' : nil
            controls_param = (node.option? 'nocontrols') ? '&amp;controls=0' : nil
            # cover both ways of controlling fullscreen option
            if node.option? 'nofullscreen'
              fs_param = '&amp;fs=0'
              fs_attribute = nil
            else
              fs_param = nil
              fs_attribute = append_boolean_attribute 'allowfullscreen', xml
            end
            modest_param = (node.option? 'modest') ? '&amp;modestbranding=1' : nil
            theme_param = (node.attr? 'theme', nil, false) ? %Q(&amp;theme=#{node.attr 'theme'}) : nil
            hl_param = (node.attr? 'lang') ? %Q(&amp;hl=#{node.attr 'lang'}) : nil

            # parse video_id/list_id syntax where list_id (i.e., playlist) is optional
            target, list = (node.attr 'target').split '/', 2
            if (list ||= (node.attr 'list', nil, false))
              list_param = %Q(&amp;list=#{list})
            else
              # parse dynamic playlist syntax: video_id1,video_id2,...
              target, playlist = target.split ',', 2
              if (playlist ||= (node.attr 'playlist', nil, false))
                # INFO playlist bar doesn't appear in Firefox unless showinfo=1 and modestbranding=1
                list_param = %Q(&amp;playlist=#{playlist})
              else
                # NOTE for loop to work, playlist must be specified; use VIDEO_ID if there's no explicit playlist
                list_param = loop_param ? %Q(&amp;playlist=#{target}) : nil
              end
            end

            %Q(<div#{id_attribute}#{class_attribute}>#{title_element}
    <div class="content">
    <iframe#{width_attribute}#{height_attribute} src="#{asset_uri_scheme}//www.youtube.com/embed/#{target}?rel=#{rel_param_val}#{start_param}#{end_param}#{autoplay_param}#{loop_param}#{controls_param}#{list_param}#{fs_param}#{modest_param}#{theme_param}#{hl_param}" frameborder="0"#{fs_attribute}></iframe>
    </div>
    </div>)
          else
            poster_attribute = (val = node.attr 'poster', nil, false).nil_or_empty? ? nil : %Q( poster="#{node.media_uri val}")
            preload_attribute = (val = node.attr 'preload', nil, false).nil_or_empty? ? nil : %Q( preload="#{val}")
            start_t = node.attr 'start', nil, false
            end_t = node.attr 'end', nil, false
            time_anchor = (start_t || end_t) ? %Q(#t=#{start_t}#{end_t ? ',' : nil}#{end_t}) : nil
            %Q(<div#{id_attribute}#{class_attribute}>#{title_element}
    <div class="content">
    <video src="#{node.media_uri(node.attr 'target')}#{time_anchor}"#{width_attribute}#{height_attribute}#{poster_attribute}#{(node.option? 'autoplay') ? (append_boolean_attribute 'autoplay', xml) : nil}#{(node.option? 'nocontrols') ? nil : (append_boolean_attribute 'controls', xml)}#{(node.option? 'loop') ? (append_boolean_attribute 'loop', xml) : nil}#{preload_attribute}>
    Your browser does not support the video tag.
    </video>
    </div>
    </div>)
          end
        end