'use strict'

const isVoidElement = require('is-void-element')
const isPresent = require('is-present')
const { load } = require('cheerio')

const SKIP_FORMAT = [ // https://www.w3.org/TR/html5/dom.html#phrasing-content
  'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas', 'cite', 'code', 'data',
  'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen',
  'label', 'map', 'mark', 'math', 'meter', 'noscript', 'object', 'output', 'progress', 'q',
  'ruby', 's', 'samp', 'script', 'select', 'small', 'span', 'strong', 'sub', 'sup', 'svg',
  'template', 'textarea', 'time', 'u', 'var', 'video', 'wbr', 'text'
]

const SKIP_CONTENT_FORMAT = [
  'pre', 'code'
]

const INDENTATION_CHARS = '  '

module.exports = (html, options = {}) => {
  const root = load(html).root()
  const elements = []

  root
    .children()
    .each((_, el) => elements.push(el))

  return elements.map(stringify).join("\n")
}

const stringify = (el, indentLevel = 0) => {
  if (el.children) {
    if (isVoidElement(el.name)) {
      return indent(indentLevel, `<${el.name} ${stringifyAttrs(el)} />`)
    } else {
      const open = `<${el.name} ${stringifyAttrs(el)}>`
      const children = el.children.map(c => stringify(c, indentLevel + 1)).filter(isPresent).join("\n")
      const close = `</${el.name}>`

      return [
        indent(indentLevel, open),
        children,
        indent(indentLevel, close)
      ].join("\n")
    }
  } else {
    return isPresent(el.data) ? indent(indentLevel, el.data.trim()) : ''
  }
}

const indent = (level, str = '') => {
  let indentStr = ''
  for (let i = 0; i < level; i++) {
    indentStr += INDENTATION_CHARS
  }

  return `${indentStr}${str}`
}

const stringifyAttrs = el => Object.keys(el.attribs).map(attr => `${attr}="${el.attribs[attr]}"`).join(' ')

@@ -1070,36 +1070,17 @@
  return 
-indent(indentLevel, 
+%5B
 %60%3C$%7Bel.n
@@ -1075,35 +1075,35 @@
 rn %5B%60%3C$%7Bel.name%7D
- $%7B
+%60, 
 stringifyAttrs(e
@@ -1108,46 +1108,120 @@
 (el)
-%7D /%3E%60)%0A    %7D else %7B%0A      const open =
+, '/%3E'%5D.filter(Boolean).join(' ')%0A    %7D else %7B%0A      const attrs = stringifyAttrs(el)%0A      const open = attrs ?
  %60%3C$
@@ -1253,16 +1253,33 @@
 s(el)%7D%3E%60
+ : %60%3C$%7Bel.name%7D%3E%60
 %0A      c

Remove trailing spaces from void and opening tags