text: // Regexps to match html elements
  
  'use strict';
  
  
  function replace(regex, options) {
    regex = regex.source;
    options = options || '';
  
    return function self(name, val) {
      if (!name) {
        return new RegExp(regex, options);
      }
      val = val.source || val;
      regex = regex.replace(name, val);
      return self;
    };
  }
  
  
  var attr_name     = /[a-zA-Z_:][a-zA-Z0-9:._-]*/;
  
  var unquoted      = /[^"'=<>`\x00-\x20]+/;
  var single_quoted = /'[^']*'/;
  var double_quoted = /"[^"]*"/;
  
  /*eslint no-spaced-func:0*/
  var attr_value  = replace(/(?:unquoted|single_quoted|double_quoted)/)
                      ('unquoted', unquoted)
                      ('single_quoted', single_quoted)
                      ('double_quoted', double_quoted)
                      ();
  
  var attribute   = replace(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)
                      ('attr_name', attr_name)
                      ('attr_value', attr_value)
                      ();
  
  var open_tag    = replace(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)
                      ('attribute', attribute)
                      ();
  
  var close_tag   = /<\/[A-Za-z][A-Za-z0-9]*\s*>/;
  var comment     = /<!--([^-]+|[-][^-]+)*-->/;
  var processing  = /<[?].*?[?]>/;
  var declaration = /<![A-Z]+\s+[^>]*>/;
  var cdata       = /<!\[CDATA\[([^\]]+|\][^\]]|\]\][^>])*\]\]>/;
  
  var HTML_TAG_RE = replace(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)
    ('open_tag', open_tag)
    ('close_tag', close_tag)
    ('comment', comment)
    ('processing', processing)
    ('declaration', declaration)
    ('cdata', cdata)
    ();
  
  
  module.exports.HTML_TAG_RE = HTML_TAG_RE;
  