@antv/infographic 0.1.3 → 0.1.4
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/dist/infographic.min.js +110 -105
- package/dist/infographic.min.js.map +1 -1
- package/esm/constants/element.d.ts +1 -1
- package/esm/constants/index.d.ts +1 -0
- package/esm/constants/index.js +1 -0
- package/esm/constants/service.d.ts +1 -0
- package/esm/constants/service.js +1 -0
- package/esm/designs/components/Illus.js +1 -1
- package/esm/designs/structures/chart-wordcloud.d.ts +11 -0
- package/esm/designs/structures/chart-wordcloud.js +156 -0
- package/esm/designs/structures/hierarchy-tree.d.ts +2 -0
- package/esm/designs/structures/hierarchy-tree.js +179 -50
- package/esm/designs/structures/index.d.ts +2 -0
- package/esm/designs/structures/index.js +2 -0
- package/esm/designs/structures/sequence-stairs-front.d.ts +8 -0
- package/esm/designs/structures/sequence-stairs-front.js +116 -0
- package/esm/designs/types.d.ts +8 -0
- package/esm/editor/managers/state.js +1 -1
- package/esm/index.d.ts +2 -0
- package/esm/index.js +1 -0
- package/esm/options/parser.d.ts +1 -1
- package/esm/options/parser.js +33 -15
- package/esm/renderer/composites/icon.js +1 -1
- package/esm/renderer/composites/illus.js +1 -1
- package/esm/resource/loader.d.ts +2 -2
- package/esm/resource/loader.js +22 -11
- package/esm/resource/loaders/index.d.ts +1 -0
- package/esm/resource/loaders/index.js +1 -0
- package/esm/resource/loaders/remote.d.ts +1 -1
- package/esm/resource/loaders/remote.js +10 -2
- package/esm/resource/loaders/search.d.ts +1 -0
- package/esm/resource/loaders/search.js +51 -0
- package/esm/resource/types/index.d.ts +1 -0
- package/esm/resource/types/resource.d.ts +8 -1
- package/esm/resource/types/scene.d.ts +1 -0
- package/esm/resource/utils/data-uri.js +20 -11
- package/esm/resource/utils/parser.js +92 -1
- package/esm/resource/utils/ref.js +2 -2
- package/esm/runtime/Infographic.d.ts +7 -6
- package/esm/runtime/Infographic.js +48 -17
- package/esm/runtime/utils.d.ts +4 -2
- package/esm/runtime/utils.js +33 -13
- package/esm/syntax/index.d.ts +3 -0
- package/esm/syntax/index.js +101 -0
- package/esm/syntax/mapper.d.ts +3 -0
- package/esm/syntax/mapper.js +238 -0
- package/esm/syntax/parser.d.ts +14 -0
- package/esm/syntax/parser.js +142 -0
- package/esm/syntax/schema.d.ts +6 -0
- package/esm/syntax/schema.js +74 -0
- package/esm/syntax/types.d.ts +61 -0
- package/esm/syntax/types.js +1 -0
- package/esm/templates/built-in.js +4 -0
- package/esm/templates/hierarchy-tree.js +25 -11
- package/esm/templates/sequence-stairs.d.ts +2 -0
- package/esm/templates/sequence-stairs.js +42 -0
- package/esm/templates/word-cloud.d.ts +2 -0
- package/esm/templates/word-cloud.js +19 -0
- package/esm/themes/types.d.ts +1 -1
- package/esm/utils/design.d.ts +2 -0
- package/esm/utils/design.js +10 -0
- package/esm/utils/font.js +11 -1
- package/esm/utils/index.d.ts +1 -0
- package/esm/utils/index.js +1 -0
- package/lib/constants/element.d.ts +1 -1
- package/lib/constants/index.d.ts +1 -0
- package/lib/constants/index.js +1 -0
- package/lib/constants/service.d.ts +1 -0
- package/lib/constants/service.js +4 -0
- package/lib/designs/components/Illus.js +1 -1
- package/lib/designs/structures/chart-wordcloud.d.ts +11 -0
- package/lib/designs/structures/chart-wordcloud.js +160 -0
- package/lib/designs/structures/hierarchy-tree.d.ts +2 -0
- package/lib/designs/structures/hierarchy-tree.js +179 -50
- package/lib/designs/structures/index.d.ts +2 -0
- package/lib/designs/structures/index.js +2 -0
- package/lib/designs/structures/sequence-stairs-front.d.ts +8 -0
- package/lib/designs/structures/sequence-stairs-front.js +120 -0
- package/lib/designs/types.d.ts +8 -0
- package/lib/editor/managers/state.js +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +4 -1
- package/lib/options/parser.d.ts +1 -1
- package/lib/options/parser.js +32 -14
- package/lib/renderer/composites/icon.js +1 -1
- package/lib/renderer/composites/illus.js +1 -1
- package/lib/resource/loader.d.ts +2 -2
- package/lib/resource/loader.js +21 -10
- package/lib/resource/loaders/index.d.ts +1 -0
- package/lib/resource/loaders/index.js +1 -0
- package/lib/resource/loaders/remote.d.ts +1 -1
- package/lib/resource/loaders/remote.js +10 -2
- package/lib/resource/loaders/search.d.ts +1 -0
- package/lib/resource/loaders/search.js +54 -0
- package/lib/resource/types/index.d.ts +1 -0
- package/lib/resource/types/resource.d.ts +8 -1
- package/lib/resource/types/scene.d.ts +1 -0
- package/lib/resource/utils/data-uri.js +20 -11
- package/lib/resource/utils/parser.js +92 -1
- package/lib/resource/utils/ref.js +2 -2
- package/lib/runtime/Infographic.d.ts +7 -6
- package/lib/runtime/Infographic.js +47 -16
- package/lib/runtime/utils.d.ts +4 -2
- package/lib/runtime/utils.js +35 -13
- package/lib/syntax/index.d.ts +3 -0
- package/lib/syntax/index.js +104 -0
- package/lib/syntax/mapper.d.ts +3 -0
- package/lib/syntax/mapper.js +242 -0
- package/lib/syntax/parser.d.ts +14 -0
- package/lib/syntax/parser.js +146 -0
- package/lib/syntax/schema.d.ts +6 -0
- package/lib/syntax/schema.js +77 -0
- package/lib/syntax/types.d.ts +61 -0
- package/lib/syntax/types.js +2 -0
- package/lib/templates/built-in.js +4 -0
- package/lib/templates/hierarchy-tree.js +25 -11
- package/lib/templates/sequence-stairs.d.ts +2 -0
- package/lib/templates/sequence-stairs.js +45 -0
- package/lib/templates/word-cloud.d.ts +2 -0
- package/lib/templates/word-cloud.js +22 -0
- package/lib/themes/types.d.ts +1 -1
- package/lib/utils/design.d.ts +2 -0
- package/lib/utils/design.js +13 -0
- package/lib/utils/font.js +11 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/package.json +1 -1
- package/src/constants/element.ts +1 -1
- package/src/constants/index.ts +1 -0
- package/src/constants/service.ts +1 -0
- package/src/designs/components/Illus.tsx +1 -1
- package/src/designs/structures/chart-wordcloud.tsx +278 -0
- package/src/designs/structures/hierarchy-tree.tsx +212 -59
- package/src/designs/structures/index.ts +2 -0
- package/src/designs/structures/sequence-stairs-front.tsx +291 -0
- package/src/designs/types.ts +9 -0
- package/src/editor/managers/state.ts +1 -1
- package/src/index.ts +2 -0
- package/src/options/parser.ts +57 -28
- package/src/renderer/composites/icon.ts +1 -1
- package/src/renderer/composites/illus.ts +1 -1
- package/src/resource/loader.ts +22 -8
- package/src/resource/loaders/index.ts +1 -0
- package/src/resource/loaders/remote.ts +9 -2
- package/src/resource/loaders/search.ts +52 -0
- package/src/resource/types/index.ts +2 -1
- package/src/resource/types/resource.ts +12 -1
- package/src/resource/types/scene.ts +1 -0
- package/src/resource/utils/data-uri.ts +20 -11
- package/src/resource/utils/parser.ts +103 -2
- package/src/resource/utils/ref.ts +2 -2
- package/src/runtime/Infographic.tsx +74 -22
- package/src/runtime/utils.ts +38 -16
- package/src/syntax/index.ts +124 -0
- package/src/syntax/mapper.ts +362 -0
- package/src/syntax/parser.ts +171 -0
- package/src/syntax/schema.ts +98 -0
- package/src/syntax/types.ts +89 -0
- package/src/templates/built-in.ts +4 -0
- package/src/templates/hierarchy-tree.ts +34 -11
- package/src/templates/sequence-stairs.ts +44 -0
- package/src/templates/word-cloud.ts +21 -0
- package/src/themes/types.ts +1 -1
- package/src/utils/design.ts +14 -0
- package/src/utils/font.ts +11 -1
- package/src/utils/index.ts +1 -0
- package/esm/resource/types/font.d.ts +0 -12
- package/lib/resource/types/font.d.ts +0 -12
- package/src/resource/types/font.ts +0 -23
- /package/esm/resource/types/{font.js → scene.js} +0 -0
- /package/lib/resource/types/{font.js → scene.js} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSyntax = parseSyntax;
|
|
4
|
+
const mapper_1 = require("./mapper");
|
|
5
|
+
const parser_1 = require("./parser");
|
|
6
|
+
const schema_1 = require("./schema");
|
|
7
|
+
function resolveTemplate(node, errors) {
|
|
8
|
+
if (!node)
|
|
9
|
+
return undefined;
|
|
10
|
+
const mapped = (0, mapper_1.mapWithSchema)(node, schema_1.TemplateSchema, 'template', errors);
|
|
11
|
+
if (!mapped)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (typeof mapped === 'string')
|
|
14
|
+
return mapped;
|
|
15
|
+
if (typeof mapped === 'object' && typeof mapped.type === 'string') {
|
|
16
|
+
return mapped.type;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function parseSyntax(input) {
|
|
21
|
+
const { ast, errors } = (0, parser_1.parseSyntaxToAst)(input);
|
|
22
|
+
const warnings = [];
|
|
23
|
+
const options = {};
|
|
24
|
+
const mergedEntries = { ...ast.entries };
|
|
25
|
+
const infographicNode = ast.entries.infographic;
|
|
26
|
+
let templateFromInfographic;
|
|
27
|
+
if (infographicNode && infographicNode.kind === 'object') {
|
|
28
|
+
if (infographicNode.value)
|
|
29
|
+
templateFromInfographic = infographicNode.value;
|
|
30
|
+
Object.entries(infographicNode.entries).forEach(([key, value]) => {
|
|
31
|
+
if (!(key in mergedEntries))
|
|
32
|
+
mergedEntries[key] = value;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const allowedRootKeys = new Set([
|
|
36
|
+
'infographic',
|
|
37
|
+
'template',
|
|
38
|
+
'design',
|
|
39
|
+
'data',
|
|
40
|
+
'theme',
|
|
41
|
+
'width',
|
|
42
|
+
'height',
|
|
43
|
+
]);
|
|
44
|
+
Object.keys(mergedEntries).forEach((key) => {
|
|
45
|
+
if (!allowedRootKeys.has(key)) {
|
|
46
|
+
errors.push({
|
|
47
|
+
path: key,
|
|
48
|
+
line: mergedEntries[key].line,
|
|
49
|
+
code: 'unknown_key',
|
|
50
|
+
message: 'Unknown top-level key.',
|
|
51
|
+
raw: key,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const templateNode = mergedEntries.template;
|
|
56
|
+
const templateValue = resolveTemplate(templateNode, errors);
|
|
57
|
+
if (templateValue)
|
|
58
|
+
options.template = templateValue;
|
|
59
|
+
if (!options.template && templateFromInfographic) {
|
|
60
|
+
options.template = templateFromInfographic;
|
|
61
|
+
}
|
|
62
|
+
const designNode = mergedEntries.design;
|
|
63
|
+
if (designNode) {
|
|
64
|
+
const design = (0, mapper_1.mapWithSchema)(designNode, schema_1.DesignSchema, 'design', errors);
|
|
65
|
+
if (design)
|
|
66
|
+
options.design = design;
|
|
67
|
+
}
|
|
68
|
+
const dataNode = mergedEntries.data;
|
|
69
|
+
if (dataNode) {
|
|
70
|
+
const data = (0, mapper_1.mapWithSchema)(dataNode, schema_1.DataSchema, 'data', errors);
|
|
71
|
+
if (data)
|
|
72
|
+
options.data = data;
|
|
73
|
+
}
|
|
74
|
+
const themeNode = mergedEntries.theme;
|
|
75
|
+
if (themeNode) {
|
|
76
|
+
const theme = (0, mapper_1.mapWithSchema)(themeNode, schema_1.ThemeSchema, 'theme', errors);
|
|
77
|
+
if (theme && typeof theme === 'object') {
|
|
78
|
+
const { type, ...rest } = theme;
|
|
79
|
+
if (typeof type === 'string' && type)
|
|
80
|
+
options.theme = type;
|
|
81
|
+
if (Object.keys(rest).length > 0) {
|
|
82
|
+
options.themeConfig = rest;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const widthNode = mergedEntries.width;
|
|
87
|
+
if (widthNode) {
|
|
88
|
+
const width = (0, mapper_1.mapWithSchema)(widthNode, schema_1.RootSchema.fields.width, 'width', errors);
|
|
89
|
+
if (width !== undefined)
|
|
90
|
+
options.width = width;
|
|
91
|
+
}
|
|
92
|
+
const heightNode = mergedEntries.height;
|
|
93
|
+
if (heightNode) {
|
|
94
|
+
const height = (0, mapper_1.mapWithSchema)(heightNode, schema_1.RootSchema.fields.height, 'height', errors);
|
|
95
|
+
if (height !== undefined)
|
|
96
|
+
options.height = height;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
options,
|
|
100
|
+
errors,
|
|
101
|
+
warnings,
|
|
102
|
+
ast,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapWithSchema = mapWithSchema;
|
|
4
|
+
exports.mapUnknownToObject = mapUnknownToObject;
|
|
5
|
+
const parser_1 = require("./parser");
|
|
6
|
+
function createValueNode(value, line) {
|
|
7
|
+
return { kind: 'value', line, value };
|
|
8
|
+
}
|
|
9
|
+
function parseScalar(value) {
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
if (trimmed === 'true')
|
|
12
|
+
return true;
|
|
13
|
+
if (trimmed === 'false')
|
|
14
|
+
return false;
|
|
15
|
+
if (/^-?\d+(\.\d+)?$/.test(trimmed))
|
|
16
|
+
return parseFloat(trimmed);
|
|
17
|
+
return trimmed;
|
|
18
|
+
}
|
|
19
|
+
function readScalar(node) {
|
|
20
|
+
if (node.kind === 'value')
|
|
21
|
+
return node.value;
|
|
22
|
+
if (node.kind === 'object')
|
|
23
|
+
return node.value;
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function addError(errors, node, path, code, message, raw) {
|
|
27
|
+
errors.push({
|
|
28
|
+
path,
|
|
29
|
+
line: node.line,
|
|
30
|
+
code,
|
|
31
|
+
message,
|
|
32
|
+
raw,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function splitArrayValue(value, split = 'any') {
|
|
36
|
+
let text = value.trim();
|
|
37
|
+
if (text.startsWith('[') && text.endsWith(']')) {
|
|
38
|
+
text = text.slice(1, -1).trim();
|
|
39
|
+
}
|
|
40
|
+
if (!text)
|
|
41
|
+
return [];
|
|
42
|
+
let parts;
|
|
43
|
+
if (split === 'comma') {
|
|
44
|
+
parts = text.split(',');
|
|
45
|
+
}
|
|
46
|
+
else if (split === 'space') {
|
|
47
|
+
parts = text.split(/\s+/);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
parts = text.split(/[,\s]+/);
|
|
51
|
+
}
|
|
52
|
+
return parts.map((part) => part.trim()).filter(Boolean);
|
|
53
|
+
}
|
|
54
|
+
function mapUnknown(node) {
|
|
55
|
+
if (node.kind === 'array') {
|
|
56
|
+
return node.items.map((item) => mapUnknown(item));
|
|
57
|
+
}
|
|
58
|
+
if (node.kind === 'value')
|
|
59
|
+
return parseScalar(node.value);
|
|
60
|
+
const hasEntries = Object.keys(node.entries).length > 0;
|
|
61
|
+
if (!hasEntries && node.value !== undefined) {
|
|
62
|
+
return parseScalar(node.value);
|
|
63
|
+
}
|
|
64
|
+
const result = {};
|
|
65
|
+
if (node.value !== undefined) {
|
|
66
|
+
result.value = parseScalar(node.value);
|
|
67
|
+
}
|
|
68
|
+
Object.entries(node.entries).forEach(([key, child]) => {
|
|
69
|
+
result[key] = mapUnknown(child);
|
|
70
|
+
});
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
function mapUnion(node, schema, path, errors) {
|
|
74
|
+
let bestValue = undefined;
|
|
75
|
+
let bestErrors = null;
|
|
76
|
+
for (const variant of schema.variants) {
|
|
77
|
+
const variantErrors = [];
|
|
78
|
+
const value = mapWithSchema(node, variant, path, variantErrors);
|
|
79
|
+
if (bestErrors === null || variantErrors.length < bestErrors.length) {
|
|
80
|
+
bestErrors = variantErrors;
|
|
81
|
+
bestValue = value;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (bestErrors)
|
|
85
|
+
errors.push(...bestErrors);
|
|
86
|
+
return bestValue;
|
|
87
|
+
}
|
|
88
|
+
function mapWithSchema(node, schema, path, errors) {
|
|
89
|
+
switch (schema.kind) {
|
|
90
|
+
case 'union':
|
|
91
|
+
return mapUnion(node, schema, path, errors);
|
|
92
|
+
case 'string': {
|
|
93
|
+
const value = readScalar(node);
|
|
94
|
+
if (value === undefined) {
|
|
95
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected string value.');
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
case 'number': {
|
|
101
|
+
const value = readScalar(node);
|
|
102
|
+
if (value === undefined) {
|
|
103
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected number value.');
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const trimmed = value.trim();
|
|
107
|
+
const match = trimmed.match(/^(-?\d+(\.\d+)?)(?:\s*(#|\/\/).*)?$/);
|
|
108
|
+
if (!match) {
|
|
109
|
+
addError(errors, node, path, 'invalid_value', 'Invalid number value.', value);
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return parseFloat(match[1]);
|
|
113
|
+
}
|
|
114
|
+
case 'boolean': {
|
|
115
|
+
const value = readScalar(node);
|
|
116
|
+
if (value === undefined) {
|
|
117
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected boolean value.');
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
if (value !== 'true' && value !== 'false') {
|
|
121
|
+
addError(errors, node, path, 'invalid_value', 'Invalid boolean value.', value);
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return value === 'true';
|
|
125
|
+
}
|
|
126
|
+
case 'enum': {
|
|
127
|
+
const value = readScalar(node);
|
|
128
|
+
if (value === undefined) {
|
|
129
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected enum value.');
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
if (!schema.values.includes(value)) {
|
|
133
|
+
addError(errors, node, path, 'invalid_value', 'Invalid enum value.', value);
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
case 'array': {
|
|
139
|
+
if (node.kind === 'array') {
|
|
140
|
+
return node.items
|
|
141
|
+
.map((item, index) => mapWithSchema(item, schema.item, `${path}[${index}]`, errors))
|
|
142
|
+
.filter((value) => value !== undefined);
|
|
143
|
+
}
|
|
144
|
+
if (node.kind === 'object' && Object.keys(node.entries).length > 0) {
|
|
145
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected array value.');
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
const scalar = readScalar(node);
|
|
149
|
+
if (scalar === undefined) {
|
|
150
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected array value.');
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
const trimmed = scalar.trim();
|
|
154
|
+
if (trimmed.startsWith('[') && !trimmed.endsWith(']')) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
const parts = splitArrayValue(scalar, schema.split);
|
|
158
|
+
return parts
|
|
159
|
+
.map((part, index) => mapWithSchema(createValueNode(part, node.line), schema.item, `${path}[${index}]`, errors))
|
|
160
|
+
.filter((value) => value !== undefined);
|
|
161
|
+
}
|
|
162
|
+
case 'object': {
|
|
163
|
+
if (node.kind === 'array') {
|
|
164
|
+
addError(errors, node, path, 'schema_mismatch', 'Expected object value.');
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
const result = {};
|
|
168
|
+
if (node.kind === 'value') {
|
|
169
|
+
if (schema.shorthandKey) {
|
|
170
|
+
result[schema.shorthandKey] = node.value;
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
const inline = (0, parser_1.parseInlineKeyValue)(node.value);
|
|
174
|
+
if (inline?.value !== undefined) {
|
|
175
|
+
if (schema.fields[inline.key]) {
|
|
176
|
+
const value = mapWithSchema(createValueNode(inline.value, node.line), schema.fields[inline.key], `${path}.${inline.key}`, errors);
|
|
177
|
+
if (value !== undefined)
|
|
178
|
+
result[inline.key] = value;
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
if (schema.allowUnknown) {
|
|
182
|
+
result[inline.key] = parseScalar(inline.value);
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
addError(errors, node, `${path}.${inline.key}`, 'unknown_key', 'Unknown key in object.', inline.key);
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
if (schema.allowUnknown) {
|
|
189
|
+
result.value = parseScalar(node.value);
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
addError(errors, node, path, 'invalid_value', 'Expected object value.');
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
if (node.value !== undefined) {
|
|
196
|
+
if (schema.shorthandKey && result[schema.shorthandKey] === undefined) {
|
|
197
|
+
result[schema.shorthandKey] = node.value;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
const inline = (0, parser_1.parseInlineKeyValue)(node.value);
|
|
201
|
+
if (inline?.value !== undefined) {
|
|
202
|
+
if (schema.fields[inline.key]) {
|
|
203
|
+
const value = mapWithSchema(createValueNode(inline.value, node.line), schema.fields[inline.key], `${path}.${inline.key}`, errors);
|
|
204
|
+
if (value !== undefined && result[inline.key] === undefined) {
|
|
205
|
+
result[inline.key] = value;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else if (schema.allowUnknown) {
|
|
209
|
+
result[inline.key] = parseScalar(inline.value);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
addError(errors, node, `${path}.${inline.key}`, 'unknown_key', 'Unknown key in object.', inline.key);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else if (schema.allowUnknown) {
|
|
216
|
+
result.value = parseScalar(node.value);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
Object.entries(node.entries).forEach(([key, child]) => {
|
|
221
|
+
const fieldSchema = schema.fields[key];
|
|
222
|
+
if (!fieldSchema) {
|
|
223
|
+
if (schema.allowUnknown) {
|
|
224
|
+
result[key] = mapUnknown(child);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
addError(errors, child, `${path}.${key}`, 'unknown_key', 'Unknown key in object.', key);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const value = mapWithSchema(child, fieldSchema, `${path}.${key}`, errors);
|
|
231
|
+
if (value !== undefined)
|
|
232
|
+
result[key] = value;
|
|
233
|
+
});
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
default:
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function mapUnknownToObject(node) {
|
|
241
|
+
return mapUnknown(node);
|
|
242
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ObjectNode, SyntaxError } from './types';
|
|
2
|
+
interface ParseResult {
|
|
3
|
+
ast: ObjectNode;
|
|
4
|
+
errors: SyntaxError[];
|
|
5
|
+
}
|
|
6
|
+
export declare function parseSyntaxToAst(input: string): ParseResult;
|
|
7
|
+
export declare function parseInlineKeyValue(value: string): {
|
|
8
|
+
key: string;
|
|
9
|
+
value: string;
|
|
10
|
+
} | {
|
|
11
|
+
key: string;
|
|
12
|
+
value: undefined;
|
|
13
|
+
} | null;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSyntaxToAst = parseSyntaxToAst;
|
|
4
|
+
exports.parseInlineKeyValue = parseInlineKeyValue;
|
|
5
|
+
function isWhitespace(char) {
|
|
6
|
+
return char === ' ' || char === '\t';
|
|
7
|
+
}
|
|
8
|
+
function getIndentInfo(line) {
|
|
9
|
+
let indent = 0;
|
|
10
|
+
let index = 0;
|
|
11
|
+
while (index < line.length) {
|
|
12
|
+
const char = line[index];
|
|
13
|
+
if (char === ' ') {
|
|
14
|
+
indent += 1;
|
|
15
|
+
index += 1;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (char === '\t') {
|
|
19
|
+
indent += 2;
|
|
20
|
+
index += 1;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
return { indent, content: line.slice(index) };
|
|
26
|
+
}
|
|
27
|
+
function stripComments(content) {
|
|
28
|
+
return content.trimEnd();
|
|
29
|
+
}
|
|
30
|
+
function parseKeyValue(raw) {
|
|
31
|
+
const text = raw.trim();
|
|
32
|
+
if (!text)
|
|
33
|
+
return null;
|
|
34
|
+
const match = text.match(/^([^:\s=]+)\s*[:=]\s*(.*)$/);
|
|
35
|
+
if (match) {
|
|
36
|
+
return { key: match[1], value: match[2].trim() };
|
|
37
|
+
}
|
|
38
|
+
const matchSpace = text.match(/^([^\s]+)\s+(.*)$/);
|
|
39
|
+
if (matchSpace) {
|
|
40
|
+
return { key: matchSpace[1], value: matchSpace[2].trim() };
|
|
41
|
+
}
|
|
42
|
+
return { key: text, value: undefined };
|
|
43
|
+
}
|
|
44
|
+
function createObjectNode(line, value) {
|
|
45
|
+
return { kind: 'object', line, value, entries: {} };
|
|
46
|
+
}
|
|
47
|
+
function createArrayNode(line) {
|
|
48
|
+
return { kind: 'array', line, items: [] };
|
|
49
|
+
}
|
|
50
|
+
function parseSyntaxToAst(input) {
|
|
51
|
+
const errors = [];
|
|
52
|
+
const root = createObjectNode(0);
|
|
53
|
+
const stack = [
|
|
54
|
+
{ indent: -1, node: root, parent: null, key: null },
|
|
55
|
+
];
|
|
56
|
+
const lines = input.split(/\r?\n/);
|
|
57
|
+
lines.forEach((line, index) => {
|
|
58
|
+
const lineNumber = index + 1;
|
|
59
|
+
if (!line.trim())
|
|
60
|
+
return;
|
|
61
|
+
const { indent, content } = getIndentInfo(line);
|
|
62
|
+
const stripped = stripComments(content);
|
|
63
|
+
if (!stripped.trim())
|
|
64
|
+
return;
|
|
65
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
66
|
+
stack.pop();
|
|
67
|
+
}
|
|
68
|
+
const parentFrame = stack[stack.length - 1];
|
|
69
|
+
let parentNode = parentFrame.node;
|
|
70
|
+
const trimmed = stripped.trim();
|
|
71
|
+
if (trimmed.startsWith('-') &&
|
|
72
|
+
(trimmed.length === 1 || isWhitespace(trimmed[1]))) {
|
|
73
|
+
if (parentNode.kind !== 'array') {
|
|
74
|
+
if (parentNode.kind === 'object' &&
|
|
75
|
+
Object.keys(parentNode.entries).length === 0 &&
|
|
76
|
+
parentNode.value === undefined &&
|
|
77
|
+
parentFrame.parent &&
|
|
78
|
+
parentFrame.key) {
|
|
79
|
+
const arrayNode = createArrayNode(parentNode.line);
|
|
80
|
+
if (parentFrame.parent.kind === 'object') {
|
|
81
|
+
parentFrame.parent.entries[parentFrame.key] = arrayNode;
|
|
82
|
+
}
|
|
83
|
+
else if (parentFrame.parent.kind === 'array') {
|
|
84
|
+
const indexInParent = parentFrame.parent.items.indexOf(parentNode);
|
|
85
|
+
if (indexInParent >= 0)
|
|
86
|
+
parentFrame.parent.items[indexInParent] = arrayNode;
|
|
87
|
+
}
|
|
88
|
+
parentFrame.node = arrayNode;
|
|
89
|
+
parentNode = arrayNode;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
errors.push({
|
|
93
|
+
path: '',
|
|
94
|
+
line: lineNumber,
|
|
95
|
+
code: 'bad_list',
|
|
96
|
+
message: 'List item is not under an array container.',
|
|
97
|
+
raw: trimmed,
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const itemContent = trimmed.slice(1).trim();
|
|
103
|
+
const itemNode = createObjectNode(lineNumber, itemContent || undefined);
|
|
104
|
+
parentNode.items.push(itemNode);
|
|
105
|
+
stack.push({
|
|
106
|
+
indent,
|
|
107
|
+
node: itemNode,
|
|
108
|
+
parent: parentNode,
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const parsed = parseKeyValue(trimmed);
|
|
113
|
+
if (!parsed) {
|
|
114
|
+
errors.push({
|
|
115
|
+
path: '',
|
|
116
|
+
line: lineNumber,
|
|
117
|
+
code: 'bad_syntax',
|
|
118
|
+
message: 'Invalid syntax line.',
|
|
119
|
+
raw: trimmed,
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (parentNode.kind !== 'object') {
|
|
124
|
+
errors.push({
|
|
125
|
+
path: '',
|
|
126
|
+
line: lineNumber,
|
|
127
|
+
code: 'bad_syntax',
|
|
128
|
+
message: 'Key-value pair is not under an object container.',
|
|
129
|
+
raw: trimmed,
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const node = createObjectNode(lineNumber, parsed.value);
|
|
134
|
+
parentNode.entries[parsed.key] = node;
|
|
135
|
+
stack.push({
|
|
136
|
+
indent,
|
|
137
|
+
node,
|
|
138
|
+
parent: parentNode,
|
|
139
|
+
key: parsed.key,
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
return { ast: root, errors };
|
|
143
|
+
}
|
|
144
|
+
function parseInlineKeyValue(value) {
|
|
145
|
+
return parseKeyValue(value);
|
|
146
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ObjectSchema } from './types';
|
|
2
|
+
export declare const ThemeSchema: ObjectSchema;
|
|
3
|
+
export declare const DesignSchema: ObjectSchema;
|
|
4
|
+
export declare const DataSchema: ObjectSchema;
|
|
5
|
+
export declare const TemplateSchema: ObjectSchema;
|
|
6
|
+
export declare const RootSchema: ObjectSchema;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RootSchema = exports.TemplateSchema = exports.DataSchema = exports.DesignSchema = exports.ThemeSchema = void 0;
|
|
4
|
+
const string = () => ({ kind: 'string' });
|
|
5
|
+
const number = () => ({ kind: 'number' });
|
|
6
|
+
// const boolean = (): SchemaNode => ({ kind: 'boolean' });
|
|
7
|
+
const enumOf = (values) => ({ kind: 'enum', values });
|
|
8
|
+
const array = (item, split = 'any') => ({
|
|
9
|
+
kind: 'array',
|
|
10
|
+
item,
|
|
11
|
+
split,
|
|
12
|
+
});
|
|
13
|
+
const object = (fields, options = {}) => ({
|
|
14
|
+
kind: 'object',
|
|
15
|
+
fields,
|
|
16
|
+
allowUnknown: options.allowUnknown,
|
|
17
|
+
shorthandKey: options.shorthandKey,
|
|
18
|
+
});
|
|
19
|
+
const union = (...variants) => ({
|
|
20
|
+
kind: 'union',
|
|
21
|
+
variants,
|
|
22
|
+
});
|
|
23
|
+
const itemDatumSchema = object({});
|
|
24
|
+
itemDatumSchema.fields = {
|
|
25
|
+
label: string(),
|
|
26
|
+
value: union(number(), string()),
|
|
27
|
+
desc: string(),
|
|
28
|
+
icon: string(),
|
|
29
|
+
children: array(itemDatumSchema),
|
|
30
|
+
};
|
|
31
|
+
exports.ThemeSchema = object({
|
|
32
|
+
type: string(),
|
|
33
|
+
colorBg: string(),
|
|
34
|
+
colorPrimary: string(),
|
|
35
|
+
palette: array(string(), 'any'),
|
|
36
|
+
title: object({}, { allowUnknown: true }),
|
|
37
|
+
desc: object({}, { allowUnknown: true }),
|
|
38
|
+
base: object({
|
|
39
|
+
global: object({}, { allowUnknown: true }),
|
|
40
|
+
shape: object({}, { allowUnknown: true }),
|
|
41
|
+
text: object({}, { allowUnknown: true }),
|
|
42
|
+
}),
|
|
43
|
+
stylize: object({
|
|
44
|
+
type: enumOf(['rough', 'pattern']),
|
|
45
|
+
roughness: number(),
|
|
46
|
+
bowing: number(),
|
|
47
|
+
fillWeight: number(),
|
|
48
|
+
hachureGap: number(),
|
|
49
|
+
pattern: string(),
|
|
50
|
+
backgroundColor: string(),
|
|
51
|
+
foregroundColor: string(),
|
|
52
|
+
scale: number(),
|
|
53
|
+
}, { shorthandKey: 'type' }),
|
|
54
|
+
}, { shorthandKey: 'type' });
|
|
55
|
+
const designNodeSchema = object({}, { allowUnknown: true, shorthandKey: 'type' });
|
|
56
|
+
exports.DesignSchema = object({
|
|
57
|
+
structure: designNodeSchema,
|
|
58
|
+
item: designNodeSchema,
|
|
59
|
+
items: array(designNodeSchema),
|
|
60
|
+
title: designNodeSchema,
|
|
61
|
+
});
|
|
62
|
+
exports.DataSchema = object({
|
|
63
|
+
title: string(),
|
|
64
|
+
desc: string(),
|
|
65
|
+
items: array(itemDatumSchema),
|
|
66
|
+
});
|
|
67
|
+
exports.TemplateSchema = object({
|
|
68
|
+
type: string(),
|
|
69
|
+
}, { shorthandKey: 'type' });
|
|
70
|
+
exports.RootSchema = object({
|
|
71
|
+
template: exports.TemplateSchema,
|
|
72
|
+
design: exports.DesignSchema,
|
|
73
|
+
data: exports.DataSchema,
|
|
74
|
+
theme: exports.ThemeSchema,
|
|
75
|
+
width: union(number(), string()),
|
|
76
|
+
height: union(number(), string()),
|
|
77
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { InfographicOptions } from '../options';
|
|
2
|
+
export type SyntaxNode = ValueNode | ObjectNode | ArrayNode;
|
|
3
|
+
export interface ValueNode {
|
|
4
|
+
kind: 'value';
|
|
5
|
+
line: number;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ObjectNode {
|
|
9
|
+
kind: 'object';
|
|
10
|
+
line: number;
|
|
11
|
+
value?: string;
|
|
12
|
+
entries: Record<string, SyntaxNode>;
|
|
13
|
+
}
|
|
14
|
+
export interface ArrayNode {
|
|
15
|
+
kind: 'array';
|
|
16
|
+
line: number;
|
|
17
|
+
items: SyntaxNode[];
|
|
18
|
+
}
|
|
19
|
+
export type SyntaxErrorCode = 'unknown_key' | 'schema_mismatch' | 'invalid_value' | 'bad_indent' | 'bad_list' | 'bad_syntax';
|
|
20
|
+
export interface SyntaxError {
|
|
21
|
+
path: string;
|
|
22
|
+
line: number;
|
|
23
|
+
code: SyntaxErrorCode;
|
|
24
|
+
message: string;
|
|
25
|
+
raw?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SyntaxParseResult {
|
|
28
|
+
options: Partial<InfographicOptions>;
|
|
29
|
+
errors: SyntaxError[];
|
|
30
|
+
warnings: SyntaxError[];
|
|
31
|
+
ast?: ObjectNode;
|
|
32
|
+
}
|
|
33
|
+
export type SchemaNode = StringSchema | NumberSchema | BooleanSchema | EnumSchema | ArraySchema | ObjectSchema | UnionSchema;
|
|
34
|
+
export interface StringSchema {
|
|
35
|
+
kind: 'string';
|
|
36
|
+
}
|
|
37
|
+
export interface NumberSchema {
|
|
38
|
+
kind: 'number';
|
|
39
|
+
}
|
|
40
|
+
export interface BooleanSchema {
|
|
41
|
+
kind: 'boolean';
|
|
42
|
+
}
|
|
43
|
+
export interface EnumSchema {
|
|
44
|
+
kind: 'enum';
|
|
45
|
+
values: string[];
|
|
46
|
+
}
|
|
47
|
+
export interface ArraySchema {
|
|
48
|
+
kind: 'array';
|
|
49
|
+
item: SchemaNode;
|
|
50
|
+
split?: 'space' | 'comma' | 'any';
|
|
51
|
+
}
|
|
52
|
+
export interface ObjectSchema {
|
|
53
|
+
kind: 'object';
|
|
54
|
+
fields: Record<string, SchemaNode>;
|
|
55
|
+
allowUnknown?: boolean;
|
|
56
|
+
shorthandKey?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface UnionSchema {
|
|
59
|
+
kind: 'union';
|
|
60
|
+
variants: SchemaNode[];
|
|
61
|
+
}
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const hierarchy_mindmap_1 = require("./hierarchy-mindmap");
|
|
4
4
|
const hierarchy_tree_1 = require("./hierarchy-tree");
|
|
5
5
|
const registry_1 = require("./registry");
|
|
6
|
+
const sequence_stairs_1 = require("./sequence-stairs");
|
|
7
|
+
const word_cloud_1 = require("./word-cloud");
|
|
6
8
|
const BUILT_IN_TEMPLATES = {
|
|
7
9
|
'compare-hierarchy-left-right-circle-node-pill-badge': {
|
|
8
10
|
design: {
|
|
@@ -803,6 +805,8 @@ const BUILT_IN_TEMPLATES = {
|
|
|
803
805
|
},
|
|
804
806
|
...hierarchy_tree_1.hierarchyTreeTemplates,
|
|
805
807
|
...hierarchy_mindmap_1.hierarchyMindmapTemplates,
|
|
808
|
+
...sequence_stairs_1.sequenceStairsTemplates,
|
|
809
|
+
...word_cloud_1.wordCloudTemplate,
|
|
806
810
|
};
|
|
807
811
|
Object.entries(BUILT_IN_TEMPLATES).forEach(([name, options]) => {
|
|
808
812
|
(0, registry_1.registerTemplate)(name, options);
|