@weborigami/language 0.2.10 → 0.2.12
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/main.js +1 -1
- package/package.json +6 -6
- package/src/compiler/isOrigamiFrontMatter.js +26 -0
- package/src/compiler/origami.pegjs +56 -10
- package/src/compiler/parse.js +623 -349
- package/src/compiler/parserHelpers.js +107 -3
- package/src/runtime/errors.js +19 -2
- package/src/runtime/evaluate.js +1 -9
- package/src/runtime/ops.js +33 -4
- package/src/runtime/taggedTemplateIndent.js +10 -5
- package/test/compiler/codeHelpers.js +1 -1
- package/test/compiler/parse.test.js +115 -43
- package/test/runtime/expressionObject.test.js +2 -2
- package/test/runtime/ops.test.js +23 -0
- package/test/runtime/taggedTemplateIndent.test.js +6 -6
- package/src/runtime/taggedTemplate.js +0 -9
- package/test/runtime/taggedTemplate.test.js +0 -10
package/main.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./src/runtime/internal.js";
|
|
2
2
|
|
|
3
3
|
export * as compile from "./src/compiler/compile.js";
|
|
4
|
+
export { default as isOrigamiFrontMatter } from "./src/compiler/isOrigamiFrontMatter.js";
|
|
4
5
|
export * from "./src/runtime/errors.js";
|
|
5
6
|
export { default as evaluate } from "./src/runtime/evaluate.js";
|
|
6
7
|
export { default as EventTargetMixin } from "./src/runtime/EventTargetMixin.js";
|
|
@@ -13,7 +14,6 @@ export { default as InvokeFunctionsTransform } from "./src/runtime/InvokeFunctio
|
|
|
13
14
|
export * as moduleCache from "./src/runtime/moduleCache.js";
|
|
14
15
|
export { default as OrigamiFiles } from "./src/runtime/OrigamiFiles.js";
|
|
15
16
|
export * as symbols from "./src/runtime/symbols.js";
|
|
16
|
-
export { default as taggedTemplate } from "./src/runtime/taggedTemplate.js";
|
|
17
17
|
export { default as taggedTemplateIndent } from "./src/runtime/taggedTemplateIndent.js";
|
|
18
18
|
export { default as TreeEvent } from "./src/runtime/TreeEvent.js";
|
|
19
19
|
export { default as WatchFilesMixin } from "./src/runtime/WatchFilesMixin.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "Web Origami expression language compiler and runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@types/node": "22.13.13",
|
|
10
10
|
"peggy": "4.2.0.",
|
|
11
|
-
"typescript": "5.8.2"
|
|
12
|
-
"yaml": "2.7.0"
|
|
11
|
+
"typescript": "5.8.2"
|
|
13
12
|
},
|
|
14
13
|
"dependencies": {
|
|
15
|
-
"@weborigami/async-tree": "0.2.
|
|
16
|
-
"@weborigami/types": "0.2.
|
|
17
|
-
"watcher": "2.3.1"
|
|
14
|
+
"@weborigami/async-tree": "0.2.12",
|
|
15
|
+
"@weborigami/types": "0.2.12",
|
|
16
|
+
"watcher": "2.3.1",
|
|
17
|
+
"yaml": "2.7.0"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "peggy --allowed-start-rules=\"*\" --format es src/compiler/origami.pegjs --output src/compiler/parse.js",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return true if the given text is Origami front matter
|
|
3
|
+
*
|
|
4
|
+
* Our heurstic is to see skip any initial alphanumeric or underscore
|
|
5
|
+
* characters, then see if the next character is a parenthesis, dot, slash,
|
|
6
|
+
* curly brace, or equals sign. If so, we assume this is an Origami expression.
|
|
7
|
+
*
|
|
8
|
+
* The goal is to identify Origami front matter like:
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* fn(x) function call
|
|
12
|
+
* index.ori() file extension
|
|
13
|
+
* src/data.json file path
|
|
14
|
+
* // Hello comment
|
|
15
|
+
* { a: 1 } object literal
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* These are generally invalid ways to start YAML. The last is valid YAML, but
|
|
19
|
+
* Origami supports the same syntax for basic object literals so interpreting as
|
|
20
|
+
* Origami should generally be acceptable.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} text
|
|
23
|
+
*/
|
|
24
|
+
export default function isOrigamiFrontMatter(text) {
|
|
25
|
+
return /^[ \t\r\n]*[A-Za-z0-9_]*[\(\.\/\{=]/.test(text);
|
|
26
|
+
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import * as ops from "../runtime/ops.js";
|
|
15
15
|
import {
|
|
16
16
|
annotate,
|
|
17
|
+
applyMacro,
|
|
17
18
|
downgradeReference,
|
|
18
19
|
makeArray,
|
|
19
20
|
makeBinaryOperation,
|
|
@@ -24,8 +25,10 @@ import {
|
|
|
24
25
|
makeProperty,
|
|
25
26
|
makeReference,
|
|
26
27
|
makeTemplate,
|
|
27
|
-
makeUnaryOperation
|
|
28
|
+
makeUnaryOperation,
|
|
29
|
+
makeYamlObject
|
|
28
30
|
} from "./parserHelpers.js";
|
|
31
|
+
import isOrigamiFrontMatter from "./isOrigamiFrontMatter.js";
|
|
29
32
|
|
|
30
33
|
}}
|
|
31
34
|
|
|
@@ -206,6 +209,18 @@ expectDoubleQuote
|
|
|
206
209
|
error("Expected closing quote");
|
|
207
210
|
}
|
|
208
211
|
|
|
212
|
+
expectExpression
|
|
213
|
+
= expression
|
|
214
|
+
/ .? {
|
|
215
|
+
error("Expected an Origami expression");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
expectFrontDelimiter
|
|
219
|
+
= frontDelimiter
|
|
220
|
+
/ .? {
|
|
221
|
+
error("Expected \"---\"");
|
|
222
|
+
}
|
|
223
|
+
|
|
209
224
|
expectGuillemet
|
|
210
225
|
= '»'
|
|
211
226
|
/ .? {
|
|
@@ -239,6 +254,27 @@ floatLiteral "floating-point number"
|
|
|
239
254
|
return annotate([ops.literal, parseFloat(text())], location());
|
|
240
255
|
}
|
|
241
256
|
|
|
257
|
+
// Marker for the beginning or end of front matter
|
|
258
|
+
frontDelimiter
|
|
259
|
+
= "---\n"
|
|
260
|
+
|
|
261
|
+
// Origami front matter
|
|
262
|
+
frontMatterExpression
|
|
263
|
+
// If we detect Origami front matter, we need to see an expression
|
|
264
|
+
= frontDelimiter &{
|
|
265
|
+
return isOrigamiFrontMatter(input.slice(location().end.offset))
|
|
266
|
+
} @expectExpression expectFrontDelimiter
|
|
267
|
+
|
|
268
|
+
frontMatterText
|
|
269
|
+
= chars:( !frontDelimiter @. )* {
|
|
270
|
+
return chars.join("");
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
frontMatterYaml "YAML front matter"
|
|
274
|
+
= frontDelimiter yaml:frontMatterText frontDelimiter {
|
|
275
|
+
return makeYamlObject(yaml, location());
|
|
276
|
+
}
|
|
277
|
+
|
|
242
278
|
// An expression in parentheses: `(foo)`
|
|
243
279
|
group "parenthetical group"
|
|
244
280
|
= "(" expression:expression expectClosingParenthesis {
|
|
@@ -619,10 +655,10 @@ stringLiteral "string"
|
|
|
619
655
|
/ singleQuoteString
|
|
620
656
|
/ guillemetString
|
|
621
657
|
|
|
622
|
-
//
|
|
623
|
-
//
|
|
624
|
-
|
|
625
|
-
= head:
|
|
658
|
+
// The body of a template document is a kind of template literal that can
|
|
659
|
+
// contain backticks at the top level.
|
|
660
|
+
templateBody "template"
|
|
661
|
+
= head:templateBodyText tail:(templateSubstitution templateBodyText)* {
|
|
626
662
|
const lambdaParameters = annotate(
|
|
627
663
|
[annotate([ops.literal, "_"], location())],
|
|
628
664
|
location()
|
|
@@ -633,15 +669,25 @@ templateDocument "template"
|
|
|
633
669
|
);
|
|
634
670
|
}
|
|
635
671
|
|
|
636
|
-
// Template
|
|
637
|
-
|
|
672
|
+
// Template document bodies can contain backticks at the top level
|
|
673
|
+
templateBodyChar
|
|
638
674
|
= !("${") @textChar
|
|
639
675
|
|
|
640
|
-
|
|
641
|
-
= chars:
|
|
676
|
+
templateBodyText "template text"
|
|
677
|
+
= chars:templateBodyChar* {
|
|
642
678
|
return annotate([ops.literal, chars.join("")], location());
|
|
643
679
|
}
|
|
644
680
|
|
|
681
|
+
templateDocument "template document"
|
|
682
|
+
= front:frontMatterExpression __ body:templateBody {
|
|
683
|
+
return annotate(applyMacro(front, "@template", body), location());
|
|
684
|
+
}
|
|
685
|
+
/ front:frontMatterYaml? body:templateBody {
|
|
686
|
+
return front
|
|
687
|
+
? annotate([ops.document, front, body], location())
|
|
688
|
+
: annotate(body, location());
|
|
689
|
+
}
|
|
690
|
+
|
|
645
691
|
// A backtick-quoted template literal
|
|
646
692
|
templateLiteral "template literal"
|
|
647
693
|
= "`" head:templateLiteralText tail:(templateSubstitution templateLiteralText)* expectBacktick {
|
|
@@ -659,7 +705,7 @@ templateLiteralText
|
|
|
659
705
|
|
|
660
706
|
// A substitution in a template literal: `${x}`
|
|
661
707
|
templateSubstitution "template substitution"
|
|
662
|
-
= "${" expression:
|
|
708
|
+
= "${" expression:expectExpression "}" {
|
|
663
709
|
return annotate(expression, location());
|
|
664
710
|
}
|
|
665
711
|
|