code: function parsePair(name, value, pos, isOption) {
      if (!name || !value || !name.length || !value.length) {
          return new Issue('E050', pos);
      }
  
      var nameRegex = /^[a-zA-Z0-9-_]+$/;
      if (!nameRegex.test(name)) {
          return new Issue('E051', pos, {name: name});
      }
  
      // Strip quotes and replace single quotes with double quotes
      var squote = '\'', dquote = '"'; // Single and double quote, for sanity
      if (value[0] === squote  ||  value[0] === dquote) {
          value = value.substr(1, value.length - 2);
      }
      value = value.replace(/\'/g, dquote);
  
      // Treat _ and - interchangeably
      name = name.replace(/_/g, '-');
  
      // check if our value is for a preset.
      if (name === 'preset') {
          if (value !== '$previous' && !presets.presets[value]) {
              return new Issue('E052', pos, {preset: value});
          } else {
              return { type: 'preset', value: value };
          }
      }
  
      // it's not a preset.
      var parsed = null;
      if (value === '$previous') {
          parsed = '$previous';
      } else if (value[0] === '$') {
          var vs = value.substr(1);
          if (!presets.presets[vs]) {
              return new Issue('E052', pos, {preset: vs});
          }
          parsed = presets.presets[vs][name];
      } else {
          if (!isOption(name)) {
              return new Issue('E054', pos, {name: name});
          }
          try {
              parsed = JSON.parse(value);
          } catch (e) {
              if (!nameRegex.test(value)) {
                  return new Issue('E053', pos, {rule: name, value: value});
              }
              parsed = value;
          }
      }
  
      return { type: 'rule', name: name, value: parsed };
  }
docs: Accept an attribute and return either a parsed config pair object
  or an error string.
  @param {string} name - The attribute name.
  @param {string} value - The attribute raw value.