<commit_before>/*
  Regularity.js: Regular expressions for humans
  Author: <NAME>
  License: MIT
  Url: https://github.com/oinak/regularity
*/

// souvenirs from Crockford-land:
Function.prototype.method = function(name, func){
  this.prototype[name] = func;
  return this;
};

Function.method('bind', function(that){
  var method = this,
      slice = Array.prototype.slice,
      args = slice.apply(arguments, [1]);
  return function(){
    return method.apply(that,
      args.concat(slice.apply(arguments, [0])));
  };
});

var Regularity = function() {

  /* PRIVATE state and auxiliary data*/
  var _regexpSource     = '',
    _flags      = '',
    _escapedChars = [ '*', '.', '?', '^', '+', '$', '|', '(', ')', '[', ']', '{', '}' ],
    _patterns     = {
      'digit'       : '[0-9]',
      'lowercase'   : '[a-z]',
      'uppercase'   : '[A-Z]',
      'letter'      : '[A-Za-z]',
      'alphanumeric': '[A-Za-z0-9]',
      'whitespace'  : '\\s',
      'space'       : ' ',
      'tab'         : '\t'
    };

  /* PRIVATE Helpers */

  //Javascript, the good parts: Douglas Crockford
  var isArray = function (value) {
    return value &&
      typeof value === 'object' &&
      typeof value.length === 'number' &&
      typeof value.splice === 'function' &&
      !(value.propertyIsEnumerable('length'));
  };

  var write = function(str, args){
    //console.log('write(str:'+str+' args:'+JSON.stringify(args)+')');
    var toAdd = ( args === null ? str : str.replace("%s", args ) );
    _regexpSource = _regexpSource + toAdd;
    return this;
  }.bind(this);

  // Translate/escape characters etc and return regex-ready string
  function interpret(){
    //console.log('  interpret(arguments: '+JSON.stringify(arguments)+')');
    //console.log('  interpret(flat:'+JSON.stringify(flat)+') <flat.length:'+flat.length+'>');
    switch (arguments.length) {
      case 2:
        return numberedConstraint(arguments[0],arguments[1]);
      case 1:
        return patternedConstraint(arguments[0]);
      default:
        var argumentError = new Error('interpret: wrong number of arguments, ' + arguments.length + ' for 1,2');
        throw(argumentError);
    }
  }

  // Ex: (2, 'x') or (3, 'digits')
  function numberedConstraint(count, type){
    var replaced = '',
        pattern = patternedConstraint(type);
    //console.log('    numberedConstraint('+count+', '+type+')');
    replaced = '%s{%c}'.replace('%s', pattern).replace('%c', count);
    return replaced;
  }

  // Ex: ('aa') or ('$')
  function patternedConstraint(pattern){
    //console.log('  patternedConstraint('+JSON.stringify(pattern)+')');
    if (pattern === null){
      var patternError = new Error('Unrecognized pattern');
      throw( patternError );
    }
    return translate( escapeStr(pattern));
  }

  // Escape special regex characters in a string
  // Ex:
  //   escapeStr("one.two")
  //   # => "one\.two"
  function escapeStr(pattern){
    return Array.prototype.map.call(pattern, function(character) {
          return ((_escapedChars.indexOf(character) !== -1) ? ('\\' + character) : character);
    }).join('');
  }

  // Translate an identifier such as 'digits' to [0-9], etc
  // Returns the original identifier if no character class found
  function translate(pattern){
    return _patterns[singularizeWord(pattern)] || pattern;
  }

  // Remove a trailing 's', if there is one
  function singularizeWord(word){
    if ((typeof(word) === 'string') && (word[word.length - 1] === 's')) {
      return word.substring(0, word.length - 1);
    }

    return word;
  }

  function empty(){
    return (_regexpSource === '');
  }

  var _enableFlag = function(flagIdentifier) {
    if (_flags.indexOf(flagIdentifier) !== -1) {
      throw new Error('can\'t enable the "' + flagIdentifier + '"" flag more than once!');
    }

    _flags += flagIdentifier;
  };

  var isValidRange = function(range) {
      return (isArray(range) &&
        (range.length === 2) &&
        (typeof(range[0]) === 'number' || typeof(range[1]) === 'number'));
  };

/* PUBLIC OBJECT API: */

  // The line must start with the specified pattern
  this.startWith = function() {
    if (empty()) {
      return write('^%s', interpret(arguments));
    }

    throw new Error('startWith called multiple times');
  };

  // Append a pattern to the end (Also aliased to then)
  this.append = function(){
    return write(interpret(arguments));
  };

  // The line must end with the specified pattern
  this.endWith = function(){
    //console.log('  endWith => arguments:'+JSON.stringify(arguments)+' flat:'+JSON.stringify(flat)+'');
    return write('%s$', interpret(arguments));
  };

  // Zero or one of the specified pattern
  this.maybe = function(){
    return write('%s?', interpret(arguments));
  };

  // Specify an alternation, e.g. one_of(['a', 'b', 'c'])
  this.oneOf = function(){
    var choices = Array.prototype.slice.call(arguments)
      .map(escapeStr) // missing interpret?
      .join('|');

    return write('[%s]', choices);
  };

  //: Specify a bounded repetition, e.g. between([2,4], 'digits')
  this.between = function(range, pattern){
    if (isValidRange(range)) {
      var values = [interpret(pattern), range[0] || '0', range[1] || '0'];<commit_msg>Rewrite 'if' as guard clause.<commit_after>/*
  Regularity.js: Regular expressions for humans
  Author: <NAME>
  License: MIT
  Url: https://github.com/oinak/regularity
*/

// souvenirs from Crockford-land:
Function.prototype.method = function(name, func){
  this.prototype[name] = func;
  return this;
};

Function.method('bind', function(that){
  var method = this,
      slice = Array.prototype.slice,
      args = slice.apply(arguments, [1]);
  return function(){
    return method.apply(that,
      args.concat(slice.apply(arguments, [0])));
  };
});

var Regularity = function() {

  /* PRIVATE state and auxiliary data*/
  var _regexpSource     = '',
    _flags      = '',
    _escapedChars = [ '*', '.', '?', '^', '+', '$', '|', '(', ')', '[', ']', '{', '}' ],
    _patterns     = {
      'digit'       : '[0-9]',
      'lowercase'   : '[a-z]',
      'uppercase'   : '[A-Z]',
      'letter'      : '[A-Za-z]',
      'alphanumeric': '[A-Za-z0-9]',
      'whitespace'  : '\\s',
      'space'       : ' ',
      'tab'         : '\t'
    };

  /* PRIVATE Helpers */

  //Javascript, the good parts: <NAME>
  var isArray = function (value) {
    return value &&
      typeof value === 'object' &&
      typeof value.length === 'number' &&
      typeof value.splice === 'function' &&
      !(value.propertyIsEnumerable('length'));
  };

  var write = function(str, args){
    //console.log('write(str:'+str+' args:'+JSON.stringify(args)+')');
    var toAdd = ( args === null ? str : str.replace("%s", args ) );
    _regexpSource = _regexpSource + toAdd;
    return this;
  }.bind(this);

  // Translate/escape characters etc and return regex-ready string
  function interpret(){
    //console.log('  interpret(arguments: '+JSON.stringify(arguments)+')');
    //console.log('  interpret(flat:'+JSON.stringify(flat)+') <flat.length:'+flat.length+'>');
    switch (arguments.length) {
      case 2:
        return numberedConstraint(arguments[0],arguments[1]);
      case 1:
        return patternedConstraint(arguments[0]);
      default:
        var argumentError = new Error('interpret: wrong number of arguments, ' + arguments.length + ' for 1,2');
        throw(argumentError);
    }
  }

  // Ex: (2, 'x') or (3, 'digits')
  function numberedConstraint(count, type){
    var replaced = '',
        pattern = patternedConstraint(type);
    //console.log('    numberedConstraint('+count+', '+type+')');
    replaced = '%s{%c}'.replace('%s', pattern).replace('%c', count);
    return replaced;
  }

  // Ex: ('aa') or ('$')
  function patternedConstraint(pattern){
    //console.log('  patternedConstraint('+JSON.stringify(pattern)+')');
    if (pattern === null){
      var patternError = new Error('Unrecognized pattern');
      throw( patternError );
    }
    return translate( escapeStr(pattern));
  }

  // Escape special regex characters in a string
  // Ex:
  //   escapeStr("one.two")
  //   # => "one\.two"
  function escapeStr(pattern){
    return Array.prototype.map.call(pattern, function(character) {
          return ((_escapedChars.indexOf(character) !== -1) ? ('\\' + character) : character);
    }).join('');
  }

  // Translate an identifier such as 'digits' to [0-9], etc
  // Returns the original identifier if no character class found
  function translate(pattern){
    return _patterns[singularizeWord(pattern)] || pattern;
  }

  // Remove a trailing 's', if there is one
  function singularizeWord(word){
    if ((typeof(word) === 'string') && (word[word.length - 1] === 's')) {
      return word.substring(0, word.length - 1);
    }

    return word;
  }

  function empty(){
    return (_regexpSource === '');
  }

  var _enableFlag = function(flagIdentifier) {
    if (_flags.indexOf(flagIdentifier) !== -1) {
      throw new Error('can\'t enable the "' + flagIdentifier + '"" flag more than once!');
    }

    _flags += flagIdentifier;
  };

  var isValidRange = function(range) {
      return (isArray(range) &&
        (range.length === 2) &&
        (typeof(range[0]) === 'number' || typeof(range[1]) === 'number'));
  };

/* PUBLIC OBJECT API: */

  // The line must start with the specified pattern
  this.startWith = function() {
    if (!empty()) throw new Error('startWith called multiple times');

    return write('^%s', interpret(arguments));
  };

  // Append a pattern to the end (Also aliased to then)
  this.append = function(){
    return write(interpret(arguments));
  };

  // The line must end with the specified pattern
  this.endWith = function(){
    //console.log('  endWith => arguments:'+JSON.stringify(arguments)+' flat:'+JSON.stringify(flat)+'');
    return write('%s$', interpret(arguments));
  };

  // Zero or one of the specified pattern
  this.maybe = function(){
    return write('%s?', interpret(arguments));
  };

  // Specify an alternation, e.g. one_of(['a', 'b', 'c'])
  this.oneOf = function(){
    var choices = Array.prototype.slice.call(arguments)
      .map(escapeStr) // missing interpret?
      .join('|');

    return write('[%s]', choices);
  };

  //: Specify a bounded repetition, e.g. between([2,4], 'digits')
  this.between = function(range, pattern){
    if (isValidRange(range)) {
      var values = [interpret(pattern), range[0] || '0', range[1] || '0'];
{'fraction_non_alphanumeric': 0.18497330282227306, 'fraction_numerical': 0.005911517925247902, 'mean_word_length': 3.020314296665389, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 12, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4693435', 'n_tokens_mistral': 3344, 'n_tokens_neox': 3235, 'n_words': 788}