<commit_before>/*
---
 
script: Script/Interpolation.js
 
description: Tools to find and evaluate interpolated strings in text content and attributes
 
license: Public domain (http://unlicense.org).

authors: <NAME>
 
requires:
  - LSD.Script.Function
  - LSD.Script.Scope
  
provides:
  - LSD.Script.Interpolation
  
...
*/

LSD.Script.Interpolation = function(object, source) {
  if (object.nodeType) {
    if (object.nodeType == 3)
      return LSD.Script.Interpolation.Textnode(object, source)
  } else if (Type.isEnumerable(object)) {
    for (var i = 0, attribute; attribute = object[i++];)
      LSD.Script.Interpolation.Attribute(attribute.name, attribute.value, source, attribute)
  } else if (type.toObject) {
    for (var name in type) {
      if (type.hasProperty(type))
        LSD.Script.Interpolation.Attribute(name, type[name], source)
    }
  }
};

LSD.Script.Interpolation.Attribute = function(name, value, source, attribute, forgiving) {
  var count = 0, last = 0, index, args;
  var regex = forgiving ? LSD.Layout.Interpolation.rForgivingBoundaries : LSD.Script.Interpolation.rBoundaries;
  for (var match, compiled; match = regex.exec(value);) {
    index = match.index;
    if (!args) args = [];
    if (index > last) args.push(value.substring(last, index));
    if (match[2] == "}") {
      args.push(LSD.Script({
        input: match[1],
        source: source,
        placeholder: match[0]
      }));
    }
    last = index + match[0].length;
  }
  if (args && last < value.length) args.push(value.substring(last, value.length));
  if (args) {
    if (!attribute) attribute = source.getAttributeNode(name);
    return new LSD.Script.Function(args, source, attribute, 'concat')
  }
};

LSD.Script.Interpolation.Textnode = function(node, source, forgiving) {
  var content = node.textContent, finder, length = content.length;
  var regex = forgiving ? LSD.Layout.Interpolation.rForgivingBoundaries : LSD.Script.Interpolation.rBoundaries;
  for (var match, index, last, next, compiled; match = regex.exec(content);) {
    last = index || 0
    var index = match.index + match[0].length;
    expression = node;
    var cut = index - last;
    if (cut < node.textContent.length) node = node.splitText(index - last);
    if ((cut = (match.index - last))) expression = expression.splitText(cut);
    compiled = LSD.Script({
      input: match[1],
      source: source,
      output: expression,
      placeholder: match[0]
    });
    Element.store(expression, 'interpolation', compiled);
    last = index;
  }
}<commit_msg>Attach attribute interpolations from the start<commit_after>/*
---
 
script: Script/Interpolation.js
 
description: Tools to find and evaluate interpolated strings in text content and attributes
 
license: Public domain (http://unlicense.org).

authors: <NAME>
 
requires:
  - LSD.Script.Function
  - LSD.Script.Scope
  
provides:
  - LSD.Script.Interpolation
  
...
*/

LSD.Script.Interpolation = function(object, source) {
  if (object.nodeType) {
    if (object.nodeType == 3)
      return LSD.Script.Interpolation.Textnode(object, source)
  } else if (Type.isEnumerable(object)) {
    for (var i = 0, attribute; attribute = object[i++];)
      LSD.Script.Interpolation.Attribute(attribute.name, attribute.value, source, attribute)
  } else if (type.toObject) {
    for (var name in type) {
      if (type.hasProperty(type))
        LSD.Script.Interpolation.Attribute(name, type[name], source)
    }
  }
};

LSD.Script.Interpolation.Attribute = function(name, value, source, attribute, forgiving) {
  var count = 0, last = 0, index, args;
  var regex = forgiving ? LSD.Layout.Interpolation.rForgivingBoundaries : LSD.Script.Interpolation.rBoundaries;
  for (var match, compiled; match = regex.exec(value);) {
    index = match.index;
    if (!args) args = [];
    if (index > last) args.push(value.substring(last, index));
    if (match[2] == "}" || match[2] == null) {
      args.push(LSD.Script({
        input: match[1],
        source: source,
        placeholder: match[0]
      }));
    }
    last = index + match[0].length;
  }
  if (args && last < value.length) args.push(value.substring(last, value.length));
  if (args) {
    if (!attribute) attribute = source.getAttributeNode(name);
    return new LSD.Script.Function(args, source, attribute, 'concat').attach();
  }
};

LSD.Script.Interpolation.Textnode = function(node, source, forgiving) {
  var content = node.textContent, finder, length = content.length;
  var regex = forgiving ? LSD.Layout.Interpolation.rForgivingBoundaries : LSD.Script.Interpolation.rBoundaries;
  for (var match, index, last, next, compiled; match = regex.exec(content);) {
    last = index || 0
    var index = match.index + match[0].length;
    expression = node;
    var cut = index - last;
    if (cut < node.textContent.length) node = node.splitText(index - last);
    if ((cut = (match.index - last))) expression = expression.splitText(cut);
    compiled = LSD.Script({
      input: match[1],
      source: source,
      output: expression,
      placeholder: match[0]
    });
    Element.store(expression, 'interpolation', compiled);
    last = index;
  }
}
{'fraction_non_alphanumeric': 0.14022140221402213, 'fraction_numerical': 0.004855311711011847, 'mean_word_length': 3.382978723404255, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, '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': '5692200', 'n_tokens_mistral': 1639, 'n_tokens_neox': 1617, 'n_words': 393}