linny-r 1.5.8 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -307,6 +307,26 @@ function indexOfMatchingBracket(str, offset) {
307
307
  return -1;
308
308
  }
309
309
 
310
+ function monoSpaced(vbl) {
311
+ // Removes all non-essential spaces from variable reference `vbl`.
312
+ // First reduce all whitespace to a single space.
313
+ return vbl.replace(/\s+/g, ' ')
314
+ // Then remove spaces after the opening bracket.
315
+ .replace(/\[\s+/g, '[')
316
+ // Also remove spaces after a leading colon (if any).
317
+ .replace(/\[:\s+/g, '[:')
318
+ // Also remove spaces before closing bracket.
319
+ .replace(/\s+\]/, ']');
320
+ }
321
+
322
+ function monoSpacedVariables(xt) {
323
+ // Return expression text `xt` with all non-functional whitespace
324
+ // *inside* its variable references (i.e., substrings like
325
+ // "[entity name|attribute]") removed.
326
+ // NOTE: All spacing *outside* variable references is preserved.
327
+ return xt.replace(/\[[^\]]*\]/g, monoSpaced);
328
+ }
329
+
310
330
  function patternList(str) {
311
331
  // Returns the &|^-pattern defined by `str`
312
332
  // Pattern operators: & (and), ^ (not) and | (or) in sequence, e.g.,
@@ -510,13 +530,19 @@ function compareWithTailNumbers(s1, s2) {
510
530
 
511
531
  function compareSelectors(s1, s2) {
512
532
  // Dataset selectors comparison is case-insensitive, and puts wildcards
513
- // last, where * comes later than ?
514
- // NOTE: without wildcards, strings that are identical except for the
515
- // digits they *end* on are sorted on this "end number" (so abc12 > abc2)
516
- // NOTE: this also applies to percentages ("end number"+ %)
533
+ // last, where * comes later than ?, and leading colons come AFTER
534
+ // regular selector names.
535
+ // NOTE: Without wildcards, strings that are identical except for the
536
+ // digits they *end* on are sorted on this "end number" (so abc12 > abc2).
537
+ // NOTE: This also applies to percentages ("end number"+ %).
517
538
  if(s1 === s2) return 0;
518
539
  if(s1 === '*') return 1;
519
540
  if(s2 === '*') return -1;
541
+ // Replace leading colon by | because | has a higher ASCII value than
542
+ // all other characters. This will move selectors with leading colons
543
+ // to the end of the list.
544
+ if(s1.startsWith(':')) s1 = '|' + s1.substring(1);
545
+ if(s2.startsWith(':')) s2 = '|' + s2.substring(1);
520
546
  const
521
547
  star1 = s1.indexOf('*'),
522
548
  star2 = s2.indexOf('*');
@@ -525,10 +551,10 @@ function compareSelectors(s1, s2) {
525
551
  return ciCompare(s1, s2);
526
552
  }
527
553
  if(star2 >= 0) return -1;
528
- // Replace ? by | because | has a higher ASCII value than all other chars
554
+ // Now replace ? by | to make it sort further down than other characters.
529
555
  let s_1 = s1.replace('?', '|').toLowerCase(),
530
556
  s_2 = s2.replace('?', '|').toLowerCase(),
531
- // NOTE: treat selectors ending on a number or percentage as special case
557
+ // NOTE: Selectors ending on a number or percentage are special.
532
558
  n_1 = endsWithDigits(s_1),
533
559
  p_1 = (s1.endsWith('%') ? endsWithDigits(s1.slice(0, -1)) : '');
534
560
  if(n_1) {
@@ -546,10 +572,11 @@ function compareSelectors(s1, s2) {
546
572
  return parseInt(p_1) - parseInt(p_2);
547
573
  }
548
574
  }
549
- // Also sort selectors ending on minuses lower than those ending on plusses,
550
- // and such that X-- comes before X-, like X+ automatically comes before X++
551
- // ASCII(+) = 43, ASCII(-) = 45, so replace trailing minuses by as many spaces
552
- // (ASCII 32) and add a '!' (ASCII 33) -- this then "sorts things out"
575
+ // Also sort selectors ending on minuses lower than those ending on
576
+ // plusses, and so that X-- comes before X-, like X+ automatically comes
577
+ // before X++. ASCII(+) = 43, ASCII(-) = 45, so replace trailing minuses
578
+ // by as many spaces (ASCII 32) and add a '!' (ASCII 33). This will then
579
+ // "sorts things out".
553
580
  let n = s_1.length,
554
581
  i = n - 1;
555
582
  while(i >= 0 && s_1[i] === '-') i--;
@@ -830,10 +857,22 @@ function randomID() {
830
857
  }
831
858
 
832
859
  function escapedSingleQuotes(s) {
833
- // Returns string `s` with "escaped" single quotes
860
+ // Return string `s` with "escaped" single quotes.
834
861
  return s.replace('\'', '\\\'');
835
862
  }
836
863
 
864
+ function safeDoubleQuotes(s) {
865
+ // Return string `s` with ASCII quotes " replaced by curly quotes to
866
+ // ensure that it does not break HTML attribute strings.
867
+ const q = ['\u201C', '\u201D'];
868
+ let index = 0;
869
+ while(s.indexOf('"') >= 0) {
870
+ s = s.replace('"', q[index]);
871
+ index = 1 - index;
872
+ }
873
+ return s;
874
+ }
875
+
837
876
  function nameToLines(name, actor_name = '') {
838
877
  // Return the name of a Linny-R entity as a string-with-line-breaks
839
878
  // that fits nicely in an oblong box. For efficiency reasons, a fixed