eyeling 1.5.26 → 1.5.27
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.
- package/eyeling.js +37 -1
- package/package.json +1 -1
- package/test/api.test.js +15 -0
package/eyeling.js
CHANGED
|
@@ -280,8 +280,41 @@ function lex(inputText) {
|
|
|
280
280
|
continue;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
// String literal
|
|
283
|
+
// String literal: short "..." or long """..."""
|
|
284
284
|
if (c === '"') {
|
|
285
|
+
// Long string literal """ ... """
|
|
286
|
+
if (peek(1) === '"' && peek(2) === '"') {
|
|
287
|
+
i += 3; // consume opening """
|
|
288
|
+
const sChars = [];
|
|
289
|
+
let closed = false;
|
|
290
|
+
while (i < n) {
|
|
291
|
+
// closing delimiter?
|
|
292
|
+
if (peek() === '"' && peek(1) === '"' && peek(2) === '"') {
|
|
293
|
+
i += 3; // consume closing """
|
|
294
|
+
closed = true;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
let cc = chars[i];
|
|
298
|
+
i++;
|
|
299
|
+
if (cc === "\\") {
|
|
300
|
+
// Preserve escapes verbatim (same behavior as short strings)
|
|
301
|
+
if (i < n) {
|
|
302
|
+
const esc = chars[i];
|
|
303
|
+
i++;
|
|
304
|
+
sChars.push("\\");
|
|
305
|
+
sChars.push(esc);
|
|
306
|
+
}
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
sChars.push(cc);
|
|
310
|
+
}
|
|
311
|
+
if (!closed) throw new Error('Unterminated long string literal """..."""');
|
|
312
|
+
const s = '"""' + sChars.join("") + '"""';
|
|
313
|
+
tokens.push(new Token("Literal", s));
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Short string literal " ... "
|
|
285
318
|
i++; // consume opening "
|
|
286
319
|
const sChars = [];
|
|
287
320
|
while (i < n) {
|
|
@@ -1680,6 +1713,9 @@ function literalParts(lit) {
|
|
|
1680
1713
|
}
|
|
1681
1714
|
|
|
1682
1715
|
function stripQuotes(lex) {
|
|
1716
|
+
if (lex.length >= 6 && lex.startsWith('"""') && lex.endsWith('"""')) {
|
|
1717
|
+
return lex.slice(3, -3);
|
|
1718
|
+
}
|
|
1683
1719
|
if (lex.length >= 2 && lex[0] === '"' && lex[lex.length - 1] === '"') {
|
|
1684
1720
|
return lex.slice(1, -1);
|
|
1685
1721
|
}
|
package/package.json
CHANGED
package/test/api.test.js
CHANGED
|
@@ -621,6 +621,21 @@ ${U('s')} ${U('p')} ${U('o')}. # another trailing comment
|
|
|
621
621
|
mustOccurExactly(out, reD, 1, 'diamond subclass should not duplicate x type D');
|
|
622
622
|
},
|
|
623
623
|
},
|
|
624
|
+
|
|
625
|
+
{
|
|
626
|
+
name: '42 literals: language tags are accepted and preserved',
|
|
627
|
+
opt: { proofComments: false },
|
|
628
|
+
input: ` { ?s ${U('p')} ?o } => { ?s ${U('q')} ?o }. ${U('s')} ${U('p')} "colour"@en-GB.`,
|
|
629
|
+
expect: [new RegExp(`${EX}s>\\s+<${EX}q>\\s+"colour"@en-GB\\s*\\.`)],
|
|
630
|
+
},
|
|
631
|
+
|
|
632
|
+
{
|
|
633
|
+
name: '43 literals: long """...""" strings are accepted (with lang tag)',
|
|
634
|
+
opt: { proofComments: false },
|
|
635
|
+
input: ` { ?s ${U('p')} ?o } => { ?s ${U('q')} ?o }. ${U('s')} ${U('p')} """Hello
|
|
636
|
+
world"""@en.`,
|
|
637
|
+
expect: [new RegExp(`${EX}s>\\s+<${EX}q>\\s+(?:"""Hello[\\s\\S]*?world"""@en|"Hello\\\\nworld"@en)\\s*\\.`)],
|
|
638
|
+
},
|
|
624
639
|
];
|
|
625
640
|
|
|
626
641
|
let passed = 0;
|