<commit_before>/*
  postcss-inrule (v1.0.2)
  github.com/salsita/postcss-inrule
  2016 | MIT
  ============================== */

var postcss = require('postcss'),
    assign = require('object-assign');

// Get index of inRule tags
function getTagIndex(string, tag) {
  var tags = string.match('^' + tag + '+');
  return tags && tags[0].length || 0;
}

// Lil' Shavy™
function getShavedClone(clone) {
  var element, current, first = true;
  // Find current element and remove its props
  clone.walkAtRules('in', function (inRule) {
    if (first) {
      first = false;
      current = element = inRule.parent;
      element.removeAll();
    }
  });
  // Clean all parent props that don't lead to current element
  while (current.parent) {
    current.parent.each(function (node) {
      node !== current && node.remove();
    });
    current = current.parent;
  }
  return element;
}

// Process modifications on clone
function processModifications(clone, params, options, inRule) {
  for (var param of params) {
    var appendIndex = getTagIndex(param, options.tagAppend),
        insertIndex = getTagIndex(param, options.tagInsert),
        replaceIndex = getTagIndex(param, options.tagReplace),
        currentIndex = Math.max(appendIndex, insertIndex, replaceIndex),
        modifier = param.slice(currentIndex, param.length),
        current = clone,
        modified = false,
        nodeCount = 0;
    while (current.parent && !modified) {
      var selectors = current.parent.selectors;
      current.type !== 'rule' && nodeCount--;
      if (selectors) {
        nodeCount++;
        if (nodeCount >= currentIndex && clone.parent.type !== 'root') {
          // Append
          if (appendIndex > 0) {
            current.parent.selectors = selectors.map(function (selector) {
              return selector + modifier;
            });
          // Insert
          } else if (insertIndex > 0) {
            current.parent.selectors = selectors.map(function (selector) {
              return selector + ' ' + modifier;
            });
          // Replace
          } else if (replaceIndex > 0) {
            current.parent.selectors = [modifier];
          } else {
            throw inRule.error('No valid tag found', { word: param });
          }
          modified = true;
        }
      }
      current = current.parent;
    }
    if (!modified) {
      throw inRule.error('No parent to modify found', { word: param });
    }
  }
  return clone;
}

module.exports = postcss.plugin('postcss-inrule', function (options) {
  return function (css) {

    // improve tagIndex regex
    // remove immediate at-rules that have no decls from original node

    // Options
    options = options || {};
    var defaultOptions = {
      tagAppend: '<',
      tagInsert: '\\^',
      tagReplace: '@'
    };
    options = assign({
      tagAppend: options.tagAppend || defaultOptions.tagAppend,
      tagInsert: options.tagInsert || defaultOptions.tagInsert,
      tagReplace: options.tagReplace || defaultOptions.tagReplace
    }, options);

    // Process @in at-rules
    css.walkAtRules('in', function (inRule) {

      // Clone a prop-less tree clone for every ',' param
      for (var params of inRule.params.split(',')) {
        var clone = getShavedClone(inRule.root().clone());

        // Process modifications and append new rule to root
        params = postcss.list.space(params);
        processModifications(clone, params, options, inRule);
        clone.append(inRule.nodes);
        css.append(clone.root());
      }
      // Remove original @in rule and all children
      inRule.removeAll().remove();
    });
  };<commit_msg>child length error, empty node cleanup<commit_after>/*
  postcss-inrule (v1.1.0)
  github.com/salsita/postcss-inrule
  2016 | MIT
  ============================== */

var postcss = require('postcss'),
    assign = require('object-assign');

// Get index of inRule tags
function getTagIndex(string, tag) {
  var tags = string.match('^' + tag + '+');
  return tags && tags[0].length || 0;
}

// Lil' Shavy™
function getShavedClone(clone) {
  var element, current, first = true;
  // Find current element and remove its props
  clone.walkAtRules('in', function (inRule) {
    if (first) {
      first = false;
      current = element = inRule.parent;
      element.removeAll();
    }
  });
  // Clean all parent props that don't lead to current element
  while (current.parent) {
    current.parent.each(function (node) {
      node !== current && node.remove();
    });
    current = current.parent;
  }
  return element;
}

// Process modifications on clone
function processModifications(clone, params, options, inRule) {
  for (var param of params) {
    var appendIndex = getTagIndex(param, options.tagAppend),
        insertIndex = getTagIndex(param, options.tagInsert),
        replaceIndex = getTagIndex(param, options.tagReplace),
        currentIndex = Math.max(appendIndex, insertIndex, replaceIndex),
        modifier = param.slice(currentIndex, param.length),
        current = clone,
        modified = false,
        nodeCount = 0;
    while (current.parent && !modified) {
      var selectors = current.parent.selectors;
      current.type !== 'rule' && nodeCount--;
      if (selectors) {
        nodeCount++;
        if (nodeCount >= currentIndex && clone.parent.type !== 'root') {
          // Append
          if (appendIndex > 0) {
            current.parent.selectors = selectors.map(function (selector) {
              return selector + modifier;
            });
          // Insert
          } else if (insertIndex > 0) {
            current.parent.selectors = selectors.map(function (selector) {
              return selector + ' ' + modifier;
            });
          // Replace
          } else if (replaceIndex > 0) {
            current.parent.selectors = [modifier];
          } else {
            throw inRule.error('No valid tag found', { word: param });
          }
          modified = true;
        }
      }
      current = current.parent;
    }
    if (!modified) {
      throw inRule.error('No parent to modify found', { word: param });
    }
  }
  return clone;
}

module.exports = postcss.plugin('postcss-inrule', function (options) {
  return function (css) {

    // improve tagIndex regex
    // remove immediate at-rules that have no decls from original node

    // Options
    options = options || {};
    var defaultOptions = {
      tagAppend: '<',
      tagInsert: '\\^',
      tagReplace: '@'
    };
    options = assign({
      tagAppend: options.tagAppend || defaultOptions.tagAppend,
      tagInsert: options.tagInsert || defaultOptions.tagInsert,
      tagReplace: options.tagReplace || defaultOptions.tagReplace
    }, options);

    // Process @in at-rules
    css.walkAtRules('in', function (inRule) {

      // Clone a prop-less tree clone for every ',' param
      for (var params of inRule.params.split(',')) {
        var clone = getShavedClone(inRule.root().clone());

        // Process modifications and append new rule to root
        params = postcss.list.space(params);
        processModifications(clone, params, options, inRule);
        if (inRule.nodes.length > 0) {
          clone.append(inRule.nodes);
        } else {
          throw inRule.error('No declarations or other children', { word: inRule });
        }
        css.append(clone.root());
      }
      // Remove empty nodes from original tree
      while (!inRule.parent.nodes.some(function (node){
        return node.type ===  'decl';
      }) && inRule.parent.type !== 'root') { inRule = inRule.parent; }
      // Remove original @in rule and all children
      inRule.removeAll().remove();
    });
  };
{'fraction_non_alphanumeric': 0.13547631441957314, 'fraction_numerical': 0.0035137948984903696, 'mean_word_length': 2.382482394366197, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2901568', 'n_tokens_mistral': 2182, 'n_tokens_neox': 2141, 'n_words': 567}