code: function parseAttrs(str, pcex) {
    var
      list = [],
      match,
      k, v, t, e,
      DQ = '"'
  
    HTML_ATTR.lastIndex = 0
  
    str = str.replace(/\s+/g, ' ')
  
    while (match = HTML_ATTR.exec(str)) {
  
      // all attribute names are converted to lower case
      k = match[1].toLowerCase()
      v = match[2]
  
      if (!v) {
        list.push(k)          // boolean attribute without explicit value
      }
      else {
        // attribute values must be enclosed in double quotes
        if (v[0] !== DQ)
          v = DQ + (v[0] === "'" ? v.slice(1, -1) : v) + DQ
  
        if (k === 'type' && SPEC_TYPES.test(v)) {
          t = v
        }
        else {
          if (/\u0001\d/.test(v)) {
            // renames special attributes with expressiones in their value.
            if (k === 'value') e = 1
            else if (BOOL_ATTRS.test(k)) k = '__' + k
            else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
          }
          // join the key-value pair, with no spaces between the parts
          list.push(k + '=' + v)
        }
      }
    }
    // update() will evaluate `type` after the value, avoiding warnings
    if (t) {
      if (e) t = DQ + pcex._bp[0] + "'" + v.slice(1, -1) + "'" + pcex._bp[1] + DQ
      list.push('type=' + t)
    }
    return list.join(' ')     // returns the attribute list
  }
docs: Parses and format attributes.
  
  @param   {string} str  - Attributes, with expressions replaced by their hash
  @param   {Array}  pcex - Has a _bp property with info about brackets
  @returns {string} Formated attributes