@stxt-lang/core 0.10.0 → 0.11.1
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/README.md +25 -9
- package/out/all.d.ts +14 -5
- package/out/all.js +19 -6
- package/out/core/Constants.d.ts +5 -4
- package/out/core/Constants.js +5 -4
- package/out/core/Line.d.ts +4 -4
- package/out/core/Line.js +3 -3
- package/out/core/LineParser.js +3 -1
- package/out/core/Node.d.ts +0 -6
- package/out/core/Node.js +0 -8
- package/out/discovery/DiscoveryResult.d.ts +1 -1
- package/out/discovery/DiscoveryResult.js +1 -1
- package/out/runtime/Formatter.d.ts +104 -0
- package/out/runtime/Formatter.js +184 -0
- package/out/schema/ChildDefinition.d.ts +2 -7
- package/out/schema/ChildDefinition.js +5 -12
- package/out/schema/NodeDefinition.d.ts +3 -8
- package/out/schema/NodeDefinition.js +3 -10
- package/out/schema/Schema.d.ts +4 -2
- package/out/schema/Schema.js +4 -0
- package/out/template/TemplateParser.d.ts +3 -0
- package/out/template/TemplateParser.js +5 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,7 +117,6 @@ import {
|
|
|
117
117
|
Parser,
|
|
118
118
|
UnifiedSchemaProvider,
|
|
119
119
|
SchemaValidator,
|
|
120
|
-
ConditionalValidator,
|
|
121
120
|
ValidationException,
|
|
122
121
|
} from '@stxt-lang/core';
|
|
123
122
|
|
|
@@ -138,8 +137,8 @@ const provider = new UnifiedSchemaProvider();
|
|
|
138
137
|
provider.addFile(schemaText);
|
|
139
138
|
|
|
140
139
|
const parser = new Parser();
|
|
141
|
-
//
|
|
142
|
-
parser.registerValidator(new
|
|
140
|
+
// Only nodes that carry a namespace are validated; free nodes pass through
|
|
141
|
+
parser.registerValidator(new SchemaValidator(provider));
|
|
143
142
|
|
|
144
143
|
const result = parser.parseResult(documentText);
|
|
145
144
|
|
|
@@ -223,7 +222,7 @@ class NodeEnvironment implements DiscoveryEnvironment {
|
|
|
223
222
|
With those in place, resolving a document and validating it is two steps — and note that `DiscoveryResult` implements `SchemaProvider`, so it goes straight into the validator:
|
|
224
223
|
|
|
225
224
|
```ts
|
|
226
|
-
import { Parser, SchemaValidator
|
|
225
|
+
import { Parser, SchemaValidator } from '@stxt-lang/core';
|
|
227
226
|
|
|
228
227
|
const resolver = new DiscoveryResolver(new NodeFileSystem(), new NodeEnvironment());
|
|
229
228
|
|
|
@@ -240,7 +239,7 @@ for (const error of result.getErrors()) {
|
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
const parser = new Parser();
|
|
243
|
-
parser.registerValidator(new
|
|
242
|
+
parser.registerValidator(new SchemaValidator(result));
|
|
244
243
|
|
|
245
244
|
const parsed = parser.parseResult(documentText);
|
|
246
245
|
```
|
|
@@ -292,15 +291,32 @@ const text = NodeWriter.toSTXT(node, IndentStyle.TABS);
|
|
|
292
291
|
const doc = NodeWriter.toSTXTDocs(result.getNodes(), IndentStyle.SPACES_4);
|
|
293
292
|
```
|
|
294
293
|
|
|
294
|
+
`NodeWriter` re-serializes the tree, so comments and blank lines are gone. To reformat a document
|
|
295
|
+
**keeping everything the author wrote**, use `Formatter`: it rewrites the original text line by
|
|
296
|
+
line — node lines in canonical form, block lines re-indented to their block, comments and blank
|
|
297
|
+
lines kept with their indentation units converted — and reports the syntax errors it met, so the
|
|
298
|
+
caller decides what to do with a document that does not parse. It is the formatter behind
|
|
299
|
+
`stxt format`, the VS Code extension and the playground.
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
import { Formatter, IndentStyle } from '@stxt-lang/core';
|
|
303
|
+
|
|
304
|
+
const { text, errors } = Formatter.format(source, IndentStyle.TABS);
|
|
305
|
+
if (errors.length === 0) {
|
|
306
|
+
fs.writeFileSync(file, text);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
295
310
|
## API surface
|
|
296
311
|
|
|
297
312
|
Everything importable from the package:
|
|
298
313
|
|
|
299
314
|
- **Parsing** — `Node`, `InlineNode`, `TextNode`, `Parser`, `ParseResult`, `Line`, `Constants`, `parseLine`, `StringUtils`
|
|
300
|
-
- **Exceptions** — `ParseException`, `ValidationException`
|
|
301
|
-
- **Extension points** — `Observer`
|
|
302
|
-
- **Schemas** — `Schema`, `SchemaValidator`, `SchemaProvider`, `NodeDefinition`, `ChildDefinition`, `
|
|
303
|
-
- **
|
|
315
|
+
- **Exceptions** — `ParseException`, `ValidationException`, `RuntimeException`
|
|
316
|
+
- **Extension points** — `Observer`, `Validator`
|
|
317
|
+
- **Schemas** — `Schema`, `SchemaValidator`, `SchemaProvider`, `SchemaProviderMemory`, `SchemaProviderMeta`, `NodeDefinition`, `ChildDefinition`, `TypeRegistry`, `Type`, `transformNodeToSchema`
|
|
318
|
+
- **Templates** — `transformTemplateNodeToSchema`, `TEMPLATE_NAMESPACE`, `TemplateSchemaProviderMemory`, `MetaTemplateSchemaProvider`
|
|
319
|
+
- **Runtime** — `UnifiedSchemaProvider`, `NodeWriter`, `IndentStyle`, `Formatter`, `FormatResult`, `toCanonicalTree`, `toCanonicalJson`
|
|
304
320
|
- **Discovery** — `DiscoveryResolver`, `DiscoveryOptions`, `DiscoveryResult`, `DiscoveryDefinition`, `DiscoveryLevel`, `DiscoveryError`, `DiscoveryFileSystem`, `DiscoveryEntry`, `DiscoveryEnvironment`
|
|
305
321
|
|
|
306
322
|
## License
|
package/out/all.d.ts
CHANGED
|
@@ -6,28 +6,37 @@ export { ParseResult } from "./core/ParseResult";
|
|
|
6
6
|
export { Line } from "./core/Line";
|
|
7
7
|
export { Constants } from "./core/Constants";
|
|
8
8
|
/**
|
|
9
|
-
* Version of the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Version of STXT-SPEC (the base syntax) this library implements, distinct from the version of
|
|
10
|
+
* the package; each specification is versioned independently (STXT-SPEC §1.1). Same value as
|
|
11
|
+
* `Constants.SPEC_VERSION`.
|
|
12
12
|
*/
|
|
13
13
|
export declare const SPEC_VERSION: string;
|
|
14
14
|
export { parseLine } from "./core/LineParser";
|
|
15
15
|
export { StringUtils } from "./core/StringUtils";
|
|
16
16
|
export { ParseException } from "./exceptions/ParseException";
|
|
17
17
|
export { ValidationException } from "./exceptions/ValidationException";
|
|
18
|
+
export { RuntimeException } from "./exceptions/RuntimeException";
|
|
18
19
|
export { Observer } from "./processors/Observer";
|
|
20
|
+
export { Validator } from "./processors/Validator";
|
|
19
21
|
export { Schema } from "./schema/Schema";
|
|
20
22
|
export { SchemaValidator } from "./schema/SchemaValidator";
|
|
21
23
|
export { SchemaProvider } from "./schema/SchemaProvider";
|
|
24
|
+
export { SchemaProviderMemory } from "./schema/SchemaProviderMemory";
|
|
25
|
+
export { SchemaProviderMeta } from "./schema/SchemaProviderMeta";
|
|
26
|
+
export { TypeRegistry } from "./schema/TypeRegistry";
|
|
27
|
+
export type { Type } from "./schema/Type";
|
|
22
28
|
export { NodeDefinition } from "./schema/NodeDefinition";
|
|
23
29
|
export { ChildDefinition } from "./schema/ChildDefinition";
|
|
24
30
|
export { transformNodeToSchema } from "./schema/SchemaParser";
|
|
25
31
|
export { UnifiedSchemaProvider } from "./runtime/UnifiedSchemaProvider";
|
|
26
|
-
export { ConditionalValidator } from "./runtime/ConditionalValidator";
|
|
27
32
|
export { NodeWriter, IndentStyle } from "./runtime/NodeWriter";
|
|
33
|
+
export { Formatter } from "./runtime/Formatter";
|
|
34
|
+
export type { FormatResult } from "./runtime/Formatter";
|
|
28
35
|
export { toCanonicalTree, toCanonicalJson } from "./runtime/TreeJson";
|
|
29
36
|
export type { CanonicalDocument, CanonicalNode, CanonicalInlineNode, CanonicalBlockNode } from "./runtime/TreeJson";
|
|
30
|
-
export { transformTemplateNodeToSchema } from "./template/TemplateParser";
|
|
37
|
+
export { transformTemplateNodeToSchema, TEMPLATE_NAMESPACE } from "./template/TemplateParser";
|
|
38
|
+
export { TemplateSchemaProviderMemory } from "./template/TemplateSchemaProviderMemory";
|
|
39
|
+
export { MetaTemplateSchemaProvider } from "./template/MetaTemplateSchemaProvider";
|
|
31
40
|
export { DiscoveryResolver, DiscoveryOptions } from "./discovery/DiscoveryResolver";
|
|
32
41
|
export { DiscoveryResult, DiscoveryDefinition, DiscoveryLevel } from "./discovery/DiscoveryResult";
|
|
33
42
|
export { DiscoveryError } from "./discovery/DiscoveryError";
|
package/out/all.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Anything that should be consumable by third parties (e.g. the VSCode extension)
|
|
4
4
|
// has to be re-exported from here.
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DiscoveryError = exports.DiscoveryResult = exports.DiscoveryResolver = exports.transformTemplateNodeToSchema = exports.toCanonicalJson = exports.toCanonicalTree = exports.
|
|
6
|
+
exports.DiscoveryError = exports.DiscoveryResult = exports.DiscoveryResolver = exports.MetaTemplateSchemaProvider = exports.TemplateSchemaProviderMemory = exports.TEMPLATE_NAMESPACE = exports.transformTemplateNodeToSchema = exports.toCanonicalJson = exports.toCanonicalTree = exports.Formatter = exports.IndentStyle = exports.NodeWriter = exports.UnifiedSchemaProvider = exports.transformNodeToSchema = exports.ChildDefinition = exports.NodeDefinition = exports.TypeRegistry = exports.SchemaProviderMeta = exports.SchemaProviderMemory = exports.SchemaValidator = exports.Schema = exports.RuntimeException = exports.ValidationException = exports.ParseException = exports.StringUtils = exports.parseLine = exports.SPEC_VERSION = exports.Constants = exports.Line = exports.ParseResult = exports.Parser = exports.TextNode = exports.InlineNode = exports.Node = void 0;
|
|
7
7
|
var Node_1 = require("./core/Node");
|
|
8
8
|
Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return Node_1.Node; } });
|
|
9
9
|
var InlineNode_1 = require("./core/InlineNode");
|
|
@@ -20,9 +20,9 @@ var Constants_1 = require("./core/Constants");
|
|
|
20
20
|
Object.defineProperty(exports, "Constants", { enumerable: true, get: function () { return Constants_1.Constants; } });
|
|
21
21
|
const Constants_2 = require("./core/Constants");
|
|
22
22
|
/**
|
|
23
|
-
* Version of the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Version of STXT-SPEC (the base syntax) this library implements, distinct from the version of
|
|
24
|
+
* the package; each specification is versioned independently (STXT-SPEC §1.1). Same value as
|
|
25
|
+
* `Constants.SPEC_VERSION`.
|
|
26
26
|
*/
|
|
27
27
|
exports.SPEC_VERSION = Constants_2.Constants.SPEC_VERSION;
|
|
28
28
|
var LineParser_1 = require("./core/LineParser");
|
|
@@ -33,10 +33,18 @@ var ParseException_1 = require("./exceptions/ParseException");
|
|
|
33
33
|
Object.defineProperty(exports, "ParseException", { enumerable: true, get: function () { return ParseException_1.ParseException; } });
|
|
34
34
|
var ValidationException_1 = require("./exceptions/ValidationException");
|
|
35
35
|
Object.defineProperty(exports, "ValidationException", { enumerable: true, get: function () { return ValidationException_1.ValidationException; } });
|
|
36
|
+
var RuntimeException_1 = require("./exceptions/RuntimeException");
|
|
37
|
+
Object.defineProperty(exports, "RuntimeException", { enumerable: true, get: function () { return RuntimeException_1.RuntimeException; } });
|
|
36
38
|
var Schema_1 = require("./schema/Schema");
|
|
37
39
|
Object.defineProperty(exports, "Schema", { enumerable: true, get: function () { return Schema_1.Schema; } });
|
|
38
40
|
var SchemaValidator_1 = require("./schema/SchemaValidator");
|
|
39
41
|
Object.defineProperty(exports, "SchemaValidator", { enumerable: true, get: function () { return SchemaValidator_1.SchemaValidator; } });
|
|
42
|
+
var SchemaProviderMemory_1 = require("./schema/SchemaProviderMemory");
|
|
43
|
+
Object.defineProperty(exports, "SchemaProviderMemory", { enumerable: true, get: function () { return SchemaProviderMemory_1.SchemaProviderMemory; } });
|
|
44
|
+
var SchemaProviderMeta_1 = require("./schema/SchemaProviderMeta");
|
|
45
|
+
Object.defineProperty(exports, "SchemaProviderMeta", { enumerable: true, get: function () { return SchemaProviderMeta_1.SchemaProviderMeta; } });
|
|
46
|
+
var TypeRegistry_1 = require("./schema/TypeRegistry");
|
|
47
|
+
Object.defineProperty(exports, "TypeRegistry", { enumerable: true, get: function () { return TypeRegistry_1.TypeRegistry; } });
|
|
40
48
|
var NodeDefinition_1 = require("./schema/NodeDefinition");
|
|
41
49
|
Object.defineProperty(exports, "NodeDefinition", { enumerable: true, get: function () { return NodeDefinition_1.NodeDefinition; } });
|
|
42
50
|
var ChildDefinition_1 = require("./schema/ChildDefinition");
|
|
@@ -45,16 +53,21 @@ var SchemaParser_1 = require("./schema/SchemaParser");
|
|
|
45
53
|
Object.defineProperty(exports, "transformNodeToSchema", { enumerable: true, get: function () { return SchemaParser_1.transformNodeToSchema; } });
|
|
46
54
|
var UnifiedSchemaProvider_1 = require("./runtime/UnifiedSchemaProvider");
|
|
47
55
|
Object.defineProperty(exports, "UnifiedSchemaProvider", { enumerable: true, get: function () { return UnifiedSchemaProvider_1.UnifiedSchemaProvider; } });
|
|
48
|
-
var ConditionalValidator_1 = require("./runtime/ConditionalValidator");
|
|
49
|
-
Object.defineProperty(exports, "ConditionalValidator", { enumerable: true, get: function () { return ConditionalValidator_1.ConditionalValidator; } });
|
|
50
56
|
var NodeWriter_1 = require("./runtime/NodeWriter");
|
|
51
57
|
Object.defineProperty(exports, "NodeWriter", { enumerable: true, get: function () { return NodeWriter_1.NodeWriter; } });
|
|
52
58
|
Object.defineProperty(exports, "IndentStyle", { enumerable: true, get: function () { return NodeWriter_1.IndentStyle; } });
|
|
59
|
+
var Formatter_1 = require("./runtime/Formatter");
|
|
60
|
+
Object.defineProperty(exports, "Formatter", { enumerable: true, get: function () { return Formatter_1.Formatter; } });
|
|
53
61
|
var TreeJson_1 = require("./runtime/TreeJson");
|
|
54
62
|
Object.defineProperty(exports, "toCanonicalTree", { enumerable: true, get: function () { return TreeJson_1.toCanonicalTree; } });
|
|
55
63
|
Object.defineProperty(exports, "toCanonicalJson", { enumerable: true, get: function () { return TreeJson_1.toCanonicalJson; } });
|
|
56
64
|
var TemplateParser_1 = require("./template/TemplateParser");
|
|
57
65
|
Object.defineProperty(exports, "transformTemplateNodeToSchema", { enumerable: true, get: function () { return TemplateParser_1.transformTemplateNodeToSchema; } });
|
|
66
|
+
Object.defineProperty(exports, "TEMPLATE_NAMESPACE", { enumerable: true, get: function () { return TemplateParser_1.TEMPLATE_NAMESPACE; } });
|
|
67
|
+
var TemplateSchemaProviderMemory_1 = require("./template/TemplateSchemaProviderMemory");
|
|
68
|
+
Object.defineProperty(exports, "TemplateSchemaProviderMemory", { enumerable: true, get: function () { return TemplateSchemaProviderMemory_1.TemplateSchemaProviderMemory; } });
|
|
69
|
+
var MetaTemplateSchemaProvider_1 = require("./template/MetaTemplateSchemaProvider");
|
|
70
|
+
Object.defineProperty(exports, "MetaTemplateSchemaProvider", { enumerable: true, get: function () { return MetaTemplateSchemaProvider_1.MetaTemplateSchemaProvider; } });
|
|
58
71
|
var DiscoveryResolver_1 = require("./discovery/DiscoveryResolver");
|
|
59
72
|
Object.defineProperty(exports, "DiscoveryResolver", { enumerable: true, get: function () { return DiscoveryResolver_1.DiscoveryResolver; } });
|
|
60
73
|
var DiscoveryResult_1 = require("./discovery/DiscoveryResult");
|
package/out/core/Constants.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/** Characters and sizes fixed by STXT-SPEC that the parser and the writer share. */
|
|
2
2
|
export declare class Constants {
|
|
3
3
|
/**
|
|
4
|
-
* Version of the
|
|
5
|
-
* STXT-
|
|
6
|
-
*
|
|
7
|
-
* specification
|
|
4
|
+
* Version of STXT-SPEC (the base syntax) this library implements; "STXT 1.0" on its own means
|
|
5
|
+
* this number (STXT-SPEC §1.1). Each specification is versioned independently, so the schema,
|
|
6
|
+
* template, tree and discovery specs may carry other numbers. It is distinct from the version
|
|
7
|
+
* of the package: the package may be released many times against the same specification
|
|
8
|
+
* version.
|
|
8
9
|
*/
|
|
9
10
|
static readonly SPEC_VERSION: string;
|
|
10
11
|
/** Character that opens a comment line. */
|
package/out/core/Constants.js
CHANGED
|
@@ -6,10 +6,11 @@ class Constants {
|
|
|
6
6
|
}
|
|
7
7
|
exports.Constants = Constants;
|
|
8
8
|
/**
|
|
9
|
-
* Version of the
|
|
10
|
-
* STXT-
|
|
11
|
-
*
|
|
12
|
-
* specification
|
|
9
|
+
* Version of STXT-SPEC (the base syntax) this library implements; "STXT 1.0" on its own means
|
|
10
|
+
* this number (STXT-SPEC §1.1). Each specification is versioned independently, so the schema,
|
|
11
|
+
* template, tree and discovery specs may carry other numbers. It is distinct from the version
|
|
12
|
+
* of the package: the package may be released many times against the same specification
|
|
13
|
+
* version.
|
|
13
14
|
*/
|
|
14
15
|
Constants.SPEC_VERSION = "1.0";
|
|
15
16
|
/** Character that opens a comment line. */
|
package/out/core/Line.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export declare class Line {
|
|
|
15
15
|
readonly isComment: boolean;
|
|
16
16
|
/** True if the line is a text line belonging to an open BLOCK node (`>>`). */
|
|
17
17
|
readonly isBlock: boolean;
|
|
18
|
-
/**
|
|
19
|
-
readonly
|
|
18
|
+
/** Index of the first character of the content (the number of characters the indentation took up). */
|
|
19
|
+
readonly contentStart: number;
|
|
20
20
|
/**
|
|
21
21
|
* Creates a line already split into indentation and content.
|
|
22
22
|
*
|
|
@@ -24,9 +24,9 @@ export declare class Line {
|
|
|
24
24
|
* @param content content of the line without its indentation.
|
|
25
25
|
* @param isComment true if the line is a comment.
|
|
26
26
|
* @param isBlock true if the line belongs to an open text block.
|
|
27
|
-
* @param
|
|
27
|
+
* @param contentStart index of the first character of the content, i.e. the number of characters the indentation took up.
|
|
28
28
|
*/
|
|
29
|
-
constructor(level: number, content: string, isComment: boolean, isBlock: boolean,
|
|
29
|
+
constructor(level: number, content: string, isComment: boolean, isBlock: boolean, contentStart: number);
|
|
30
30
|
/** @returns true if the line has no content beyond blanks (space/tab only, spec 4). */
|
|
31
31
|
isEmpty(): boolean;
|
|
32
32
|
}
|
package/out/core/Line.js
CHANGED
|
@@ -15,14 +15,14 @@ class Line {
|
|
|
15
15
|
* @param content content of the line without its indentation.
|
|
16
16
|
* @param isComment true if the line is a comment.
|
|
17
17
|
* @param isBlock true if the line belongs to an open text block.
|
|
18
|
-
* @param
|
|
18
|
+
* @param contentStart index of the first character of the content, i.e. the number of characters the indentation took up.
|
|
19
19
|
*/
|
|
20
|
-
constructor(level, content, isComment, isBlock,
|
|
20
|
+
constructor(level, content, isComment, isBlock, contentStart) {
|
|
21
21
|
this.level = level;
|
|
22
22
|
this.content = content;
|
|
23
23
|
this.isComment = isComment;
|
|
24
24
|
this.isBlock = isBlock;
|
|
25
|
-
this.
|
|
25
|
+
this.contentStart = contentStart;
|
|
26
26
|
}
|
|
27
27
|
/** @returns true if the line has no content beyond blanks (space/tab only, spec 4). */
|
|
28
28
|
isEmpty() {
|
package/out/core/LineParser.js
CHANGED
|
@@ -68,7 +68,9 @@ function parseLine(line, lastNodeBlock, lastLevel, numLine, validate = true) {
|
|
|
68
68
|
if (validate && sawSpace && sawTab && text.length > 0) {
|
|
69
69
|
throw new ParseException_1.ParseException(numLine, "INDENTATION_MIXED", `Mixed tabs and spaces in indentation`);
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
// pointer is the index of the indentation character that crossed the block level;
|
|
72
|
+
// the indentation took pointer + 1 characters
|
|
73
|
+
return new Line_1.Line(level, text, false, true, pointer + 1);
|
|
72
74
|
}
|
|
73
75
|
// Move the pointer forward
|
|
74
76
|
pointer++;
|
package/out/core/Node.d.ts
CHANGED
|
@@ -51,12 +51,6 @@ export declare abstract class Node {
|
|
|
51
51
|
setName(name: string): void;
|
|
52
52
|
/** @returns the canonical name of the node (STXT-SPEC §4.3), used to compare/look up by structural identity. */
|
|
53
53
|
getCanonicalName(): string;
|
|
54
|
-
/**
|
|
55
|
-
* @returns the canonical name of the node.
|
|
56
|
-
* @deprecated since 0.7.0, use {@link Node.getCanonicalName}; "canonical name" is the term of
|
|
57
|
-
* the specifications. To be removed in a later version.
|
|
58
|
-
*/
|
|
59
|
-
getNormalizedName(): string;
|
|
60
54
|
/** @returns the canonical name prefixed by the effective namespace (`namespace:name`), or just the canonical name when there is no namespace. */
|
|
61
55
|
getQualifiedName(): string;
|
|
62
56
|
/** @returns the namespace this node declares itself, lower-cased, or the empty string if it declares none (and so inherits the parent's). */
|
package/out/core/Node.js
CHANGED
|
@@ -68,14 +68,6 @@ class Node {
|
|
|
68
68
|
getCanonicalName() {
|
|
69
69
|
return this.canonicalName;
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
72
|
-
* @returns the canonical name of the node.
|
|
73
|
-
* @deprecated since 0.7.0, use {@link Node.getCanonicalName}; "canonical name" is the term of
|
|
74
|
-
* the specifications. To be removed in a later version.
|
|
75
|
-
*/
|
|
76
|
-
getNormalizedName() {
|
|
77
|
-
return this.canonicalName;
|
|
78
|
-
}
|
|
79
71
|
/** @returns the canonical name prefixed by the effective namespace (`namespace:name`), or just the canonical name when there is no namespace. */
|
|
80
72
|
getQualifiedName() {
|
|
81
73
|
const namespace = this.getNamespace();
|
|
@@ -35,7 +35,7 @@ export interface DiscoveryLevel {
|
|
|
35
35
|
* error found along the way.
|
|
36
36
|
*
|
|
37
37
|
* It implements {@link SchemaProvider}, so it can be handed directly to a
|
|
38
|
-
* `SchemaValidator
|
|
38
|
+
* `SchemaValidator` to validate the document it was resolved for.
|
|
39
39
|
* Like `UnifiedSchemaProvider`, it serves the meta-schemas of the two reserved namespaces
|
|
40
40
|
* itself, so schema and template documents also validate against it.
|
|
41
41
|
*/
|
|
@@ -8,7 +8,7 @@ const StringUtils_1 = require("../core/StringUtils");
|
|
|
8
8
|
* error found along the way.
|
|
9
9
|
*
|
|
10
10
|
* It implements {@link SchemaProvider}, so it can be handed directly to a
|
|
11
|
-
* `SchemaValidator
|
|
11
|
+
* `SchemaValidator` to validate the document it was resolved for.
|
|
12
12
|
* Like `UnifiedSchemaProvider`, it serves the meta-schemas of the two reserved namespaces
|
|
13
13
|
* itself, so schema and template documents also validate against it.
|
|
14
14
|
*/
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ParseException } from "../exceptions/ParseException";
|
|
2
|
+
import { IndentStyle } from "./NodeWriter";
|
|
3
|
+
/** The outcome of {@link Formatter.format}. */
|
|
4
|
+
export interface FormatResult {
|
|
5
|
+
/**
|
|
6
|
+
* The formatted document: the same lines as the source, in the same order, with the same
|
|
7
|
+
* line ending (CRLF is kept) and with a final newline only where the source had one.
|
|
8
|
+
*/
|
|
9
|
+
text: string;
|
|
10
|
+
/**
|
|
11
|
+
* Syntax errors found while parsing, in line order; empty when the document parses. A line
|
|
12
|
+
* the parse tree does not describe because of an error is only converted by indentation
|
|
13
|
+
* units and right-trimmed (see {@link Formatter}): formatting never repairs a document, and
|
|
14
|
+
* whether a document with errors should be reformatted at all is the caller's decision.
|
|
15
|
+
*/
|
|
16
|
+
errors: ParseException[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reformats an STXT document **line by line, over the original text**, so that nothing the
|
|
20
|
+
* parse tree does not hold — comments, blank lines, the exact content of text blocks — is lost.
|
|
21
|
+
* This is what distinguishes it from {@link NodeWriter}, which re-serializes the tree and
|
|
22
|
+
* therefore drops comments and blank lines.
|
|
23
|
+
*
|
|
24
|
+
* The rules, the same for every tool of the ecosystem (the CLI's `stxt format`, the VS Code
|
|
25
|
+
* extension's formatter and the playground's re-indentation all delegate here):
|
|
26
|
+
*
|
|
27
|
+
* - A line that **opens a node** is rendered in canonical form: the indentation of its level in
|
|
28
|
+
* the requested style, the name as parsed, the namespace only where the source wrote it (a
|
|
29
|
+
* child repeating its parent's namespace is redundant but legal, and dropping it would be an
|
|
30
|
+
* edit, not a reformat), `: value` with exactly one space — or a bare `:` when there is no
|
|
31
|
+
* value, so container nodes do not end in a stray space — or ` >>` for a block.
|
|
32
|
+
* - A **text line of a block** gets the indentation of the block (its level plus one) in the
|
|
33
|
+
* requested style, followed by its content; any indentation the line had beyond the block's
|
|
34
|
+
* is content (STXT-SPEC §10.2, relative indentation is preserved) and is kept exactly. A
|
|
35
|
+
* blank line of the block is `""` in the content whatever it looks like in the source
|
|
36
|
+
* (STXT-SPEC §10.3), so it is written with the indentation of the block too: the block reads
|
|
37
|
+
* as one piece and, at the end of the file, the line is not lost — an empty last line would
|
|
38
|
+
* be indistinguishable from the final line ending.
|
|
39
|
+
* - Every **other line** — a comment, a blank line outside a block, or a line the parse tree
|
|
40
|
+
* does not describe because of a syntax error — is kept as the author wrote it, except that
|
|
41
|
+
* its trailing blanks are removed and the whole indentation units at its start are converted
|
|
42
|
+
* one for one to the requested style (a tab or four spaces in either style count as a unit;
|
|
43
|
+
* whatever follows the last whole unit, including a remainder that is not a whole unit, is
|
|
44
|
+
* kept as it is). STXT-SPEC §9 validates the indentation of a comment like a node's, so in a
|
|
45
|
+
* document that parses every comment has a whole number of units and comes out fully in the
|
|
46
|
+
* new style; the remainder only survives in documents with errors, which this conversion
|
|
47
|
+
* neither repairs nor hides.
|
|
48
|
+
*
|
|
49
|
+
* The result is idempotent, round-trips between the two styles, and produces the same canonical
|
|
50
|
+
* tree (STXT-TREE-SPEC) as the source. The document is parsed without any schema: formatting
|
|
51
|
+
* has nothing to do with validation.
|
|
52
|
+
*/
|
|
53
|
+
export declare class Formatter {
|
|
54
|
+
private constructor();
|
|
55
|
+
/**
|
|
56
|
+
* Formats a document.
|
|
57
|
+
*
|
|
58
|
+
* @param text the document.
|
|
59
|
+
* @param style indentation style to format with; tabs by default.
|
|
60
|
+
* @returns the formatted text and the syntax errors found; see {@link FormatResult}.
|
|
61
|
+
*/
|
|
62
|
+
static format(text: string, style?: IndentStyle): FormatResult;
|
|
63
|
+
/**
|
|
64
|
+
* Formats one source line.
|
|
65
|
+
*
|
|
66
|
+
* @param line the line, without its line ending.
|
|
67
|
+
* @param lineNumber its line number, 1-indexed as the parser counts them.
|
|
68
|
+
* @param style indentation style to format with.
|
|
69
|
+
* @param sourceLines the parse of the document seen as source lines.
|
|
70
|
+
* @returns the formatted line.
|
|
71
|
+
*/
|
|
72
|
+
private static formatLine;
|
|
73
|
+
/**
|
|
74
|
+
* Renders the line that opens a node in its canonical form.
|
|
75
|
+
*
|
|
76
|
+
* @param node the node the line opens.
|
|
77
|
+
* @param line the source line, used only to tell whether it spelled the namespace out.
|
|
78
|
+
* @param style indentation style to format with.
|
|
79
|
+
* @returns the formatted line.
|
|
80
|
+
*/
|
|
81
|
+
private static renderNode;
|
|
82
|
+
/**
|
|
83
|
+
* Converts the whole indentation units at the start of a line to the requested style and
|
|
84
|
+
* keeps the rest of the line, remainder included.
|
|
85
|
+
*
|
|
86
|
+
* @param line the line, without trailing blanks.
|
|
87
|
+
* @param style indentation style to convert to.
|
|
88
|
+
* @returns the line with its indentation units converted.
|
|
89
|
+
*/
|
|
90
|
+
private static convertUnits;
|
|
91
|
+
/**
|
|
92
|
+
* @param line a line.
|
|
93
|
+
* @param position a position in it.
|
|
94
|
+
* @returns the length of the whole indentation unit — a tab or four spaces — that starts at
|
|
95
|
+
* `position`, or 0 if none does.
|
|
96
|
+
*/
|
|
97
|
+
private static unitAt;
|
|
98
|
+
/**
|
|
99
|
+
* @param level indentation level to produce.
|
|
100
|
+
* @param style indentation style to produce it in.
|
|
101
|
+
* @returns the indentation of that level.
|
|
102
|
+
*/
|
|
103
|
+
private static indent;
|
|
104
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Formatter = void 0;
|
|
4
|
+
const InlineNode_1 = require("../core/InlineNode");
|
|
5
|
+
const Parser_1 = require("../core/Parser");
|
|
6
|
+
const StringUtils_1 = require("../core/StringUtils");
|
|
7
|
+
const TextNode_1 = require("../core/TextNode");
|
|
8
|
+
const NodeWriter_1 = require("./NodeWriter");
|
|
9
|
+
/**
|
|
10
|
+
* Reformats an STXT document **line by line, over the original text**, so that nothing the
|
|
11
|
+
* parse tree does not hold — comments, blank lines, the exact content of text blocks — is lost.
|
|
12
|
+
* This is what distinguishes it from {@link NodeWriter}, which re-serializes the tree and
|
|
13
|
+
* therefore drops comments and blank lines.
|
|
14
|
+
*
|
|
15
|
+
* The rules, the same for every tool of the ecosystem (the CLI's `stxt format`, the VS Code
|
|
16
|
+
* extension's formatter and the playground's re-indentation all delegate here):
|
|
17
|
+
*
|
|
18
|
+
* - A line that **opens a node** is rendered in canonical form: the indentation of its level in
|
|
19
|
+
* the requested style, the name as parsed, the namespace only where the source wrote it (a
|
|
20
|
+
* child repeating its parent's namespace is redundant but legal, and dropping it would be an
|
|
21
|
+
* edit, not a reformat), `: value` with exactly one space — or a bare `:` when there is no
|
|
22
|
+
* value, so container nodes do not end in a stray space — or ` >>` for a block.
|
|
23
|
+
* - A **text line of a block** gets the indentation of the block (its level plus one) in the
|
|
24
|
+
* requested style, followed by its content; any indentation the line had beyond the block's
|
|
25
|
+
* is content (STXT-SPEC §10.2, relative indentation is preserved) and is kept exactly. A
|
|
26
|
+
* blank line of the block is `""` in the content whatever it looks like in the source
|
|
27
|
+
* (STXT-SPEC §10.3), so it is written with the indentation of the block too: the block reads
|
|
28
|
+
* as one piece and, at the end of the file, the line is not lost — an empty last line would
|
|
29
|
+
* be indistinguishable from the final line ending.
|
|
30
|
+
* - Every **other line** — a comment, a blank line outside a block, or a line the parse tree
|
|
31
|
+
* does not describe because of a syntax error — is kept as the author wrote it, except that
|
|
32
|
+
* its trailing blanks are removed and the whole indentation units at its start are converted
|
|
33
|
+
* one for one to the requested style (a tab or four spaces in either style count as a unit;
|
|
34
|
+
* whatever follows the last whole unit, including a remainder that is not a whole unit, is
|
|
35
|
+
* kept as it is). STXT-SPEC §9 validates the indentation of a comment like a node's, so in a
|
|
36
|
+
* document that parses every comment has a whole number of units and comes out fully in the
|
|
37
|
+
* new style; the remainder only survives in documents with errors, which this conversion
|
|
38
|
+
* neither repairs nor hides.
|
|
39
|
+
*
|
|
40
|
+
* The result is idempotent, round-trips between the two styles, and produces the same canonical
|
|
41
|
+
* tree (STXT-TREE-SPEC) as the source. The document is parsed without any schema: formatting
|
|
42
|
+
* has nothing to do with validation.
|
|
43
|
+
*/
|
|
44
|
+
class Formatter {
|
|
45
|
+
constructor() { }
|
|
46
|
+
/**
|
|
47
|
+
* Formats a document.
|
|
48
|
+
*
|
|
49
|
+
* @param text the document.
|
|
50
|
+
* @param style indentation style to format with; tabs by default.
|
|
51
|
+
* @returns the formatted text and the syntax errors found; see {@link FormatResult}.
|
|
52
|
+
*/
|
|
53
|
+
static format(text, style = NodeWriter_1.IndentStyle.TABS) {
|
|
54
|
+
const sourceLines = new SourceLines();
|
|
55
|
+
const parser = new Parser_1.Parser();
|
|
56
|
+
parser.registerObserver(sourceLines);
|
|
57
|
+
const result = parser.parseResult(text);
|
|
58
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
59
|
+
const formatted = text
|
|
60
|
+
.split(/\r?\n/)
|
|
61
|
+
.map((line, index) => Formatter.formatLine(line, index + 1, style, sourceLines))
|
|
62
|
+
.join(eol);
|
|
63
|
+
return { text: formatted, errors: result.getErrors() };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Formats one source line.
|
|
67
|
+
*
|
|
68
|
+
* @param line the line, without its line ending.
|
|
69
|
+
* @param lineNumber its line number, 1-indexed as the parser counts them.
|
|
70
|
+
* @param style indentation style to format with.
|
|
71
|
+
* @param sourceLines the parse of the document seen as source lines.
|
|
72
|
+
* @returns the formatted line.
|
|
73
|
+
*/
|
|
74
|
+
static formatLine(line, lineNumber, style, sourceLines) {
|
|
75
|
+
const node = sourceLines.nodeAt(lineNumber);
|
|
76
|
+
if (node) {
|
|
77
|
+
return Formatter.renderNode(node, line, style);
|
|
78
|
+
}
|
|
79
|
+
const text = sourceLines.textAt(lineNumber);
|
|
80
|
+
if (text) {
|
|
81
|
+
return Formatter.indent(text.node.getLevel() + 1, style) + text.line.content;
|
|
82
|
+
}
|
|
83
|
+
return Formatter.convertUnits(StringUtils_1.StringUtils.rightTrim(line), style);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Renders the line that opens a node in its canonical form.
|
|
87
|
+
*
|
|
88
|
+
* @param node the node the line opens.
|
|
89
|
+
* @param line the source line, used only to tell whether it spelled the namespace out.
|
|
90
|
+
* @param style indentation style to format with.
|
|
91
|
+
* @returns the formatted line.
|
|
92
|
+
*/
|
|
93
|
+
static renderNode(node, line, style) {
|
|
94
|
+
const indent = Formatter.indent(node.getLevel(), style);
|
|
95
|
+
const head = node instanceof InlineNode_1.InlineNode ? line.substring(0, line.indexOf(":")) : line;
|
|
96
|
+
const name = head.includes("(")
|
|
97
|
+
? `${node.getName()} (${node.getNamespace()})`
|
|
98
|
+
: node.getName();
|
|
99
|
+
if (node instanceof TextNode_1.TextNode) {
|
|
100
|
+
return `${indent}${name} >>`;
|
|
101
|
+
}
|
|
102
|
+
const value = node.getValue();
|
|
103
|
+
return value.length > 0 ? `${indent}${name}: ${value}` : `${indent}${name}:`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Converts the whole indentation units at the start of a line to the requested style and
|
|
107
|
+
* keeps the rest of the line, remainder included.
|
|
108
|
+
*
|
|
109
|
+
* @param line the line, without trailing blanks.
|
|
110
|
+
* @param style indentation style to convert to.
|
|
111
|
+
* @returns the line with its indentation units converted.
|
|
112
|
+
*/
|
|
113
|
+
static convertUnits(line, style) {
|
|
114
|
+
let consumed = 0;
|
|
115
|
+
let units = 0;
|
|
116
|
+
let unit = Formatter.unitAt(line, consumed);
|
|
117
|
+
while (unit > 0) {
|
|
118
|
+
consumed += unit;
|
|
119
|
+
units++;
|
|
120
|
+
unit = Formatter.unitAt(line, consumed);
|
|
121
|
+
}
|
|
122
|
+
return units === 0 ? line : Formatter.indent(units, style) + line.substring(consumed);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* @param line a line.
|
|
126
|
+
* @param position a position in it.
|
|
127
|
+
* @returns the length of the whole indentation unit — a tab or four spaces — that starts at
|
|
128
|
+
* `position`, or 0 if none does.
|
|
129
|
+
*/
|
|
130
|
+
static unitAt(line, position) {
|
|
131
|
+
if (line.startsWith("\t", position)) {
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
return line.startsWith(" ", position) ? 4 : 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* @param level indentation level to produce.
|
|
138
|
+
* @param style indentation style to produce it in.
|
|
139
|
+
* @returns the indentation of that level.
|
|
140
|
+
*/
|
|
141
|
+
static indent(level, style) {
|
|
142
|
+
return (style === NodeWriter_1.IndentStyle.SPACES_4 ? " " : "\t").repeat(level);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.Formatter = Formatter;
|
|
146
|
+
/**
|
|
147
|
+
* The parse of a document seen as source lines: which line opened which node, and which line is
|
|
148
|
+
* a text line of which block. It is what lets the formatter rewrite the lines the parse tree
|
|
149
|
+
* describes and leave every other line as the author wrote it.
|
|
150
|
+
*/
|
|
151
|
+
class SourceLines {
|
|
152
|
+
constructor() {
|
|
153
|
+
this.nodeByLine = new Map();
|
|
154
|
+
this.textByLine = new Map();
|
|
155
|
+
}
|
|
156
|
+
onCreate(node) {
|
|
157
|
+
this.nodeByLine.set(node.getLine(), node);
|
|
158
|
+
}
|
|
159
|
+
onFinish() {
|
|
160
|
+
// Formatting only needs to know where each node started.
|
|
161
|
+
}
|
|
162
|
+
onComment() {
|
|
163
|
+
// Comment lines need no bookkeeping: every line that opens no node is treated alike.
|
|
164
|
+
}
|
|
165
|
+
onTextLine(node, lineNumber, lineString, line) {
|
|
166
|
+
this.textByLine.set(lineNumber, { node, line });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* @param lineNumber line number, 1-indexed.
|
|
170
|
+
* @returns the node this line opened, or undefined if it opened none.
|
|
171
|
+
*/
|
|
172
|
+
nodeAt(lineNumber) {
|
|
173
|
+
return this.nodeByLine.get(lineNumber);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* @param lineNumber line number, 1-indexed.
|
|
177
|
+
* @returns the block node this line is text of and the line already split into indentation
|
|
178
|
+
* and content, or undefined if the line is not text of a block.
|
|
179
|
+
*/
|
|
180
|
+
textAt(lineNumber) {
|
|
181
|
+
return this.textByLine.get(lineNumber);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=Formatter.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Definition of an expected child inside a {@link NodeDefinition}: name, namespace and min/max cardinality. */
|
|
2
2
|
export declare class ChildDefinition {
|
|
3
|
-
private readonly
|
|
3
|
+
private readonly canonicalName;
|
|
4
4
|
private readonly name;
|
|
5
5
|
private readonly namespace;
|
|
6
6
|
private readonly min;
|
|
@@ -20,11 +20,6 @@ export declare class ChildDefinition {
|
|
|
20
20
|
getName(): string;
|
|
21
21
|
/** @returns the canonical name of the expected child. */
|
|
22
22
|
getCanonicalName(): string;
|
|
23
|
-
/**
|
|
24
|
-
* @returns the canonical name of the expected child.
|
|
25
|
-
* @deprecated since 0.7.0, use getCanonicalName().
|
|
26
|
-
*/
|
|
27
|
-
getNormalizedName(): string;
|
|
28
23
|
/** @returns the namespace of the expected child, or the empty string if it has none. */
|
|
29
24
|
getNamespace(): string;
|
|
30
25
|
/** @returns the minimum cardinality, or null if there is no minimum. */
|
|
@@ -36,7 +31,7 @@ export declare class ChildDefinition {
|
|
|
36
31
|
/** @returns a plain object with the definition, so that JSON.stringify serializes it. */
|
|
37
32
|
toJSON(): {
|
|
38
33
|
name: string;
|
|
39
|
-
|
|
34
|
+
canonicalName: string;
|
|
40
35
|
namespace: string;
|
|
41
36
|
min: number | null;
|
|
42
37
|
max: number | null;
|
|
@@ -18,7 +18,7 @@ class ChildDefinition {
|
|
|
18
18
|
*/
|
|
19
19
|
constructor(name, namespace, min, max, numLine) {
|
|
20
20
|
this.name = StringUtils_1.StringUtils.compactSpaces(name);
|
|
21
|
-
this.
|
|
21
|
+
this.canonicalName = StringUtils_1.StringUtils.normalize(name);
|
|
22
22
|
this.namespace = StringUtils_1.StringUtils.lowerCase(namespace);
|
|
23
23
|
this.min = min;
|
|
24
24
|
this.max = max;
|
|
@@ -33,14 +33,7 @@ class ChildDefinition {
|
|
|
33
33
|
}
|
|
34
34
|
/** @returns the canonical name of the expected child. */
|
|
35
35
|
getCanonicalName() {
|
|
36
|
-
return this.
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* @returns the canonical name of the expected child.
|
|
40
|
-
* @deprecated since 0.7.0, use getCanonicalName().
|
|
41
|
-
*/
|
|
42
|
-
getNormalizedName() {
|
|
43
|
-
return this.normalizedName;
|
|
36
|
+
return this.canonicalName;
|
|
44
37
|
}
|
|
45
38
|
/** @returns the namespace of the expected child, or the empty string if it has none. */
|
|
46
39
|
getNamespace() {
|
|
@@ -57,14 +50,14 @@ class ChildDefinition {
|
|
|
57
50
|
/** @returns the canonical name prefixed by its namespace, used as the key in {@link NodeDefinition.getChildren}. */
|
|
58
51
|
getQualifiedName() {
|
|
59
52
|
return this.namespace.length === 0
|
|
60
|
-
? this.
|
|
61
|
-
: `${this.namespace}:${this.
|
|
53
|
+
? this.canonicalName
|
|
54
|
+
: `${this.namespace}:${this.canonicalName}`;
|
|
62
55
|
}
|
|
63
56
|
/** @returns a plain object with the definition, so that JSON.stringify serializes it. */
|
|
64
57
|
toJSON() {
|
|
65
58
|
return {
|
|
66
59
|
name: this.getName(),
|
|
67
|
-
|
|
60
|
+
canonicalName: this.getCanonicalName(),
|
|
68
61
|
namespace: this.getNamespace(),
|
|
69
62
|
min: this.getMin(),
|
|
70
63
|
max: this.getMax(),
|
|
@@ -5,7 +5,7 @@ import { ChildDefinition } from "./ChildDefinition";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class NodeDefinition {
|
|
7
7
|
private readonly name;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly canonicalName;
|
|
9
9
|
private readonly type;
|
|
10
10
|
private description;
|
|
11
11
|
private readonly children;
|
|
@@ -24,11 +24,6 @@ export declare class NodeDefinition {
|
|
|
24
24
|
getName(): string;
|
|
25
25
|
/** @returns the canonical name of the node. */
|
|
26
26
|
getCanonicalName(): string;
|
|
27
|
-
/**
|
|
28
|
-
* @returns the canonical name of the node.
|
|
29
|
-
* @deprecated since 0.7.0, use getCanonicalName().
|
|
30
|
-
*/
|
|
31
|
-
getNormalizedName(): string;
|
|
32
27
|
/** @returns the name of the value type of this node (see {@link TypeRegistry}). */
|
|
33
28
|
getType(): string;
|
|
34
29
|
/** @returns the definitions of the expected children, indexed by their qualified canonical name. */
|
|
@@ -68,12 +63,12 @@ export declare class NodeDefinition {
|
|
|
68
63
|
/** @returns a plain object with the definition, so that JSON.stringify serializes it. */
|
|
69
64
|
toJSON(): {
|
|
70
65
|
name: string;
|
|
71
|
-
|
|
66
|
+
canonicalName: string;
|
|
72
67
|
type: string;
|
|
73
68
|
description: string | undefined;
|
|
74
69
|
children: {
|
|
75
70
|
name: string;
|
|
76
|
-
|
|
71
|
+
canonicalName: string;
|
|
77
72
|
namespace: string;
|
|
78
73
|
min: number | null;
|
|
79
74
|
max: number | null;
|
|
@@ -21,7 +21,7 @@ class NodeDefinition {
|
|
|
21
21
|
this.children = new Map();
|
|
22
22
|
this.values = new Set();
|
|
23
23
|
this.name = StringUtils_1.StringUtils.compactSpaces(name);
|
|
24
|
-
this.
|
|
24
|
+
this.canonicalName = StringUtils_1.StringUtils.normalize(name);
|
|
25
25
|
this.type = type;
|
|
26
26
|
this.description = description;
|
|
27
27
|
if (!StringUtils_1.StringUtils.isValidNodeName(this.name)) {
|
|
@@ -34,14 +34,7 @@ class NodeDefinition {
|
|
|
34
34
|
}
|
|
35
35
|
/** @returns the canonical name of the node. */
|
|
36
36
|
getCanonicalName() {
|
|
37
|
-
return this.
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* @returns the canonical name of the node.
|
|
41
|
-
* @deprecated since 0.7.0, use getCanonicalName().
|
|
42
|
-
*/
|
|
43
|
-
getNormalizedName() {
|
|
44
|
-
return this.normalizedName;
|
|
37
|
+
return this.canonicalName;
|
|
45
38
|
}
|
|
46
39
|
/** @returns the name of the value type of this node (see {@link TypeRegistry}). */
|
|
47
40
|
getType() {
|
|
@@ -113,7 +106,7 @@ class NodeDefinition {
|
|
|
113
106
|
toJSON() {
|
|
114
107
|
return {
|
|
115
108
|
name: this.getName(),
|
|
116
|
-
|
|
109
|
+
canonicalName: this.getCanonicalName(),
|
|
117
110
|
type: this.getType(),
|
|
118
111
|
description: this.description,
|
|
119
112
|
children: Array.from(this.getChildren().values()).map(c => c.toJSON()),
|
package/out/schema/Schema.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export declare class Schema {
|
|
|
15
15
|
* @throws ParseException if the namespace is not well formed.
|
|
16
16
|
*/
|
|
17
17
|
constructor(namespace: string | null | undefined, line: number, description: string | undefined);
|
|
18
|
+
/** @returns the description of the schema (STXT-SCHEMA-SPEC §6.1), or undefined if it has none. */
|
|
19
|
+
getDescription(): string | undefined;
|
|
18
20
|
/** @returns the node definitions, indexed by their canonical name. */
|
|
19
21
|
getNodes(): ReadonlyMap<string, NodeDefinition>;
|
|
20
22
|
/**
|
|
@@ -38,12 +40,12 @@ export declare class Schema {
|
|
|
38
40
|
namespace: string;
|
|
39
41
|
nodes: {
|
|
40
42
|
name: string;
|
|
41
|
-
|
|
43
|
+
canonicalName: string;
|
|
42
44
|
type: string;
|
|
43
45
|
description: string | undefined;
|
|
44
46
|
children: {
|
|
45
47
|
name: string;
|
|
46
|
-
|
|
48
|
+
canonicalName: string;
|
|
47
49
|
namespace: string;
|
|
48
50
|
min: number | null;
|
|
49
51
|
max: number | null;
|
package/out/schema/Schema.js
CHANGED
|
@@ -20,6 +20,10 @@ class Schema {
|
|
|
20
20
|
this.description = description;
|
|
21
21
|
NamespaceValidator_1.NamespaceValidator.validateNamespaceFormat(this.namespace, line);
|
|
22
22
|
}
|
|
23
|
+
/** @returns the description of the schema (STXT-SCHEMA-SPEC §6.1), or undefined if it has none. */
|
|
24
|
+
getDescription() {
|
|
25
|
+
return this.description;
|
|
26
|
+
}
|
|
23
27
|
/** @returns the node definitions, indexed by their canonical name. */
|
|
24
28
|
getNodes() {
|
|
25
29
|
return this.nodes;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Node } from "../core/Node";
|
|
2
2
|
import { Schema } from "../schema/Schema";
|
|
3
|
+
/** Namespace of the template language itself, `@stxt.template`. */
|
|
4
|
+
/** Namespace of the template language itself, `@stxt.template`. */
|
|
5
|
+
export declare const TEMPLATE_NAMESPACE = "@stxt.template";
|
|
3
6
|
/**
|
|
4
7
|
* Turns the tree of an already parsed `@stxt.template` document into an equivalent {@link Schema}.
|
|
5
8
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TEMPLATE_NAMESPACE = void 0;
|
|
3
4
|
exports.transformTemplateNodeToSchema = transformTemplateNodeToSchema;
|
|
4
5
|
const InlineNode_1 = require("../core/InlineNode");
|
|
5
6
|
const Parser_1 = require("../core/Parser");
|
|
@@ -13,7 +14,8 @@ const ParseException_1 = require("../exceptions/ParseException");
|
|
|
13
14
|
const TypeRegistry_1 = require("../schema/TypeRegistry");
|
|
14
15
|
const NamespaceValidator_1 = require("../core/NamespaceValidator");
|
|
15
16
|
/** Namespace of the template language itself, `@stxt.template`. */
|
|
16
|
-
|
|
17
|
+
/** Namespace of the template language itself, `@stxt.template`. */
|
|
18
|
+
exports.TEMPLATE_NAMESPACE = "@stxt.template";
|
|
17
19
|
/**
|
|
18
20
|
* Turns the tree of an already parsed `@stxt.template` document into an equivalent {@link Schema}.
|
|
19
21
|
*
|
|
@@ -25,8 +27,8 @@ const TEMPLATE_NAMESPACE = "@stxt.template";
|
|
|
25
27
|
*/
|
|
26
28
|
function transformTemplateNodeToSchema(node) {
|
|
27
29
|
// The root must be `Template (@stxt.template): ns`
|
|
28
|
-
if (node.getCanonicalName() !== "template" || node.getNamespace() !== TEMPLATE_NAMESPACE) {
|
|
29
|
-
throw new ValidationException_1.ValidationException(node.getLine(), "TEMPLATE_ROOT_NOT_VALID", `Expected template(${TEMPLATE_NAMESPACE}) but got ${node.getCanonicalName()}(${node.getNamespace()})`);
|
|
30
|
+
if (node.getCanonicalName() !== "template" || node.getNamespace() !== exports.TEMPLATE_NAMESPACE) {
|
|
31
|
+
throw new ValidationException_1.ValidationException(node.getLine(), "TEMPLATE_ROOT_NOT_VALID", `Expected template(${exports.TEMPLATE_NAMESPACE}) but got ${node.getCanonicalName()}(${node.getNamespace()})`);
|
|
30
32
|
}
|
|
31
33
|
// The target namespace: required, and with a valid format
|
|
32
34
|
const targetNamespace = StringUtils_1.StringUtils.lowerCase(node.getText());
|