@the_dissidents/libemmm 0.0.8 → 0.0.10
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 +204 -62
- package/dist/chunk-Bp6m_JJh.js +13 -0
- package/dist/index.cjs +3311 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +728 -0
- package/dist/index.d.ts +599 -506
- package/dist/index.js +3078 -3246
- package/dist/index.js.map +1 -1
- package/package.json +25 -17
- package/dist/index.d.mts +0 -634
- package/dist/index.mjs +0 -3366
- package/dist/index.mjs.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3311 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (all) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
18
|
+
key = keys[i];
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
20
|
+
get: ((k) => from[k]).bind(null, key),
|
|
21
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
27
|
+
value: mod,
|
|
28
|
+
enumerable: true
|
|
29
|
+
}) : target, mod));
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
let minimal_jsx_runtime_jsx_runtime = require("minimal-jsx-runtime/jsx-runtime");
|
|
33
|
+
minimal_jsx_runtime_jsx_runtime = __toESM(minimal_jsx_runtime_jsx_runtime);
|
|
34
|
+
|
|
35
|
+
//#region src/util.ts
|
|
36
|
+
var NameManager = class NameManager {
|
|
37
|
+
array = [];
|
|
38
|
+
data = /* @__PURE__ */ new Map();
|
|
39
|
+
constructor(from) {
|
|
40
|
+
if (from === void 0) return;
|
|
41
|
+
if (from instanceof NameManager) {
|
|
42
|
+
this.array = [...from.array];
|
|
43
|
+
this.data = new Map(from.data);
|
|
44
|
+
} else {
|
|
45
|
+
const array = [...from];
|
|
46
|
+
assert((from instanceof Set ? from : new Set(array)).size == array.length);
|
|
47
|
+
this.array = array.map((x) => ({
|
|
48
|
+
k: x.name,
|
|
49
|
+
v: x
|
|
50
|
+
}));
|
|
51
|
+
this.array.sort((a, b) => b.k.length - a.k.length);
|
|
52
|
+
this.data = new Map(array.map((x) => [x.name, x]));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
toArray() {
|
|
56
|
+
return this.array.map(({ v }) => v);
|
|
57
|
+
}
|
|
58
|
+
toSet() {
|
|
59
|
+
return new Set(this.toArray());
|
|
60
|
+
}
|
|
61
|
+
get(name) {
|
|
62
|
+
return this.data.get(name);
|
|
63
|
+
}
|
|
64
|
+
has(name) {
|
|
65
|
+
return this.data.has(name);
|
|
66
|
+
}
|
|
67
|
+
remove(name) {
|
|
68
|
+
assert(this.data.get(name) !== void 0);
|
|
69
|
+
this.data.delete(name);
|
|
70
|
+
this.array.splice(this.array.findIndex((x) => x.k == name), 1);
|
|
71
|
+
}
|
|
72
|
+
add(...elems) {
|
|
73
|
+
for (const elem of elems) {
|
|
74
|
+
assert(!this.has(elem.name));
|
|
75
|
+
this.data.set(elem.name, elem);
|
|
76
|
+
const len = elem.name.length;
|
|
77
|
+
let i = 0;
|
|
78
|
+
while (i < this.array.length && this.array[i].k.length > len) i++;
|
|
79
|
+
this.array.splice(i, 0, {
|
|
80
|
+
k: elem.name,
|
|
81
|
+
v: elem
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
find(predicate) {
|
|
86
|
+
const result = this.array.find((x) => predicate(x.v));
|
|
87
|
+
return result ? result.v : void 0;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
function assert(x) {
|
|
91
|
+
if (!!!x) {
|
|
92
|
+
let error = /* @__PURE__ */ new Error("assertion failed");
|
|
93
|
+
console.log(error.stack);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/debug.ts
|
|
100
|
+
let DebugLevel = /* @__PURE__ */ function(DebugLevel$1) {
|
|
101
|
+
DebugLevel$1[DebugLevel$1["Trace"] = 0] = "Trace";
|
|
102
|
+
DebugLevel$1[DebugLevel$1["Info"] = 1] = "Info";
|
|
103
|
+
DebugLevel$1[DebugLevel$1["Warning"] = 2] = "Warning";
|
|
104
|
+
DebugLevel$1[DebugLevel$1["Error"] = 3] = "Error";
|
|
105
|
+
DebugLevel$1[DebugLevel$1["None"] = 4] = "None";
|
|
106
|
+
return DebugLevel$1;
|
|
107
|
+
}({});
|
|
108
|
+
const debug = {
|
|
109
|
+
level: DebugLevel.Info,
|
|
110
|
+
trace(arg0, ...args) {
|
|
111
|
+
if (this.level > DebugLevel.Trace) return;
|
|
112
|
+
if (typeof arg0 == "function") arg0 = arg0();
|
|
113
|
+
console.info("TRACE", arg0, ...args);
|
|
114
|
+
},
|
|
115
|
+
info(arg0, ...args) {
|
|
116
|
+
if (this.level > DebugLevel.Info) return;
|
|
117
|
+
if (typeof arg0 == "function") arg0 = arg0();
|
|
118
|
+
console.info(" INFO", arg0, ...args);
|
|
119
|
+
},
|
|
120
|
+
warning(arg0, ...args) {
|
|
121
|
+
if (this.level > DebugLevel.Warning) return;
|
|
122
|
+
if (typeof arg0 == "function") arg0 = arg0();
|
|
123
|
+
console.warn(" WARN", arg0, ...args);
|
|
124
|
+
},
|
|
125
|
+
error(arg0, ...args) {
|
|
126
|
+
if (this.level > DebugLevel.Error) return;
|
|
127
|
+
if (typeof arg0 == "function") arg0 = arg0();
|
|
128
|
+
console.error("ERROR", arg0, ...args);
|
|
129
|
+
},
|
|
130
|
+
never(_) {
|
|
131
|
+
assert(false);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/source.ts
|
|
137
|
+
var StringSource = class {
|
|
138
|
+
name;
|
|
139
|
+
nLines;
|
|
140
|
+
lineMap;
|
|
141
|
+
constructor(d, src) {
|
|
142
|
+
this.src = src;
|
|
143
|
+
this.name = d.name;
|
|
144
|
+
this.lineMap = [0];
|
|
145
|
+
[...src].forEach((x, i) => {
|
|
146
|
+
if (x == "\n") this.lineMap.push(i + 1);
|
|
147
|
+
});
|
|
148
|
+
this.nLines = this.lineMap.length;
|
|
149
|
+
this.lineMap.push(Infinity);
|
|
150
|
+
}
|
|
151
|
+
getRowCol(pos) {
|
|
152
|
+
let line = -1, linepos = 0;
|
|
153
|
+
for (let i = 1; i < this.lineMap.length; i++) if (this.lineMap[i] > pos) {
|
|
154
|
+
line = i - 1;
|
|
155
|
+
linepos = this.lineMap[i - 1];
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
return [line, pos - linepos];
|
|
159
|
+
}
|
|
160
|
+
getRowStart(n) {
|
|
161
|
+
assert(n >= 0);
|
|
162
|
+
if (n >= this.lineMap.length) return Infinity;
|
|
163
|
+
return this.lineMap[n];
|
|
164
|
+
}
|
|
165
|
+
getRow(n) {
|
|
166
|
+
const start = this.getRowStart(n);
|
|
167
|
+
const end = this.getRowStart(n + 1);
|
|
168
|
+
if (start === Infinity) return void 0;
|
|
169
|
+
return this.src.substring(start, end - 1);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/interface.ts
|
|
175
|
+
let MessageSeverity = /* @__PURE__ */ function(MessageSeverity$1) {
|
|
176
|
+
MessageSeverity$1[MessageSeverity$1["Info"] = 0] = "Info";
|
|
177
|
+
MessageSeverity$1[MessageSeverity$1["Warning"] = 1] = "Warning";
|
|
178
|
+
MessageSeverity$1[MessageSeverity$1["Error"] = 2] = "Error";
|
|
179
|
+
return MessageSeverity$1;
|
|
180
|
+
}({});
|
|
181
|
+
let NodeType = /* @__PURE__ */ function(NodeType$1) {
|
|
182
|
+
NodeType$1[NodeType$1["Root"] = 0] = "Root";
|
|
183
|
+
NodeType$1[NodeType$1["Group"] = 1] = "Group";
|
|
184
|
+
NodeType$1[NodeType$1["Paragraph"] = 2] = "Paragraph";
|
|
185
|
+
NodeType$1[NodeType$1["Preformatted"] = 3] = "Preformatted";
|
|
186
|
+
NodeType$1[NodeType$1["Text"] = 4] = "Text";
|
|
187
|
+
NodeType$1[NodeType$1["Escaped"] = 5] = "Escaped";
|
|
188
|
+
NodeType$1[NodeType$1["SystemModifier"] = 6] = "SystemModifier";
|
|
189
|
+
NodeType$1[NodeType$1["InlineModifier"] = 7] = "InlineModifier";
|
|
190
|
+
NodeType$1[NodeType$1["BlockModifier"] = 8] = "BlockModifier";
|
|
191
|
+
NodeType$1[NodeType$1["Interpolation"] = 9] = "Interpolation";
|
|
192
|
+
return NodeType$1;
|
|
193
|
+
}({});
|
|
194
|
+
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/modifier.ts
|
|
197
|
+
let ModifierSlotType = /* @__PURE__ */ function(ModifierSlotType$1) {
|
|
198
|
+
ModifierSlotType$1[ModifierSlotType$1["Normal"] = 0] = "Normal";
|
|
199
|
+
/** Content is preformatted: no escaping, no inner tags */
|
|
200
|
+
ModifierSlotType$1[ModifierSlotType$1["Preformatted"] = 1] = "Preformatted";
|
|
201
|
+
/** No content slot */
|
|
202
|
+
ModifierSlotType$1[ModifierSlotType$1["None"] = 2] = "None";
|
|
203
|
+
return ModifierSlotType$1;
|
|
204
|
+
}({});
|
|
205
|
+
var ModifierBase = class {
|
|
206
|
+
constructor(name, slotType = ModifierSlotType.Normal, args) {
|
|
207
|
+
this.name = name;
|
|
208
|
+
this.slotType = slotType;
|
|
209
|
+
if (args) Object.assign(this, args);
|
|
210
|
+
}
|
|
211
|
+
metadata = {};
|
|
212
|
+
/**
|
|
213
|
+
* Common values: heading, emphasis, keyword, highlight, commentary, comment, link, quote, pre
|
|
214
|
+
*/
|
|
215
|
+
roleHint;
|
|
216
|
+
/**
|
|
217
|
+
* If true, any modifier encountered inside it will *not* be expanded *during parse-content*,
|
|
218
|
+
* *unless* that modifier is `alwaysTryExpand`. In the vast majority of cases, you shouldn't
|
|
219
|
+
* be using this.
|
|
220
|
+
*/
|
|
221
|
+
delayContentExpansion = false;
|
|
222
|
+
/**
|
|
223
|
+
* If true, such a modifier will always be expanded whenever it is encountered, *even if*
|
|
224
|
+
* it is contained in a modifier with `delayContentExpansion`. In the vast majority of cases,
|
|
225
|
+
* you shouldn't be using this.
|
|
226
|
+
*/
|
|
227
|
+
alwaysTryExpand = false;
|
|
228
|
+
/** Called before the modifier's content is parsed.
|
|
229
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
|
|
230
|
+
*/
|
|
231
|
+
beforeParseContent;
|
|
232
|
+
/** Called after the modifier's content is parsed.
|
|
233
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
|
|
234
|
+
*/
|
|
235
|
+
afterParseContent;
|
|
236
|
+
/** Called before reparsing of the expansion.
|
|
237
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.*/
|
|
238
|
+
beforeProcessExpansion;
|
|
239
|
+
/** Called before reparsing of the expansion.
|
|
240
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.*/
|
|
241
|
+
afterProcessExpansion;
|
|
242
|
+
/**
|
|
243
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
|
|
244
|
+
*/
|
|
245
|
+
prepareExpand;
|
|
246
|
+
/**
|
|
247
|
+
* @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
|
|
248
|
+
*/
|
|
249
|
+
expand;
|
|
250
|
+
};
|
|
251
|
+
var BlockModifierDefinition = class extends ModifierBase {};
|
|
252
|
+
var InlineModifierDefinition = class extends ModifierBase {};
|
|
253
|
+
var SystemModifierDefinition = class extends ModifierBase {};
|
|
254
|
+
var ArgumentInterpolatorDefinition = class {
|
|
255
|
+
constructor(name, postfix, args) {
|
|
256
|
+
this.name = name;
|
|
257
|
+
this.postfix = postfix;
|
|
258
|
+
if (args) Object.assign(this, args);
|
|
259
|
+
}
|
|
260
|
+
alwaysTryExpand = false;
|
|
261
|
+
expand;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/scanner.ts
|
|
266
|
+
var SimpleScanner = class {
|
|
267
|
+
source;
|
|
268
|
+
#pos = 0;
|
|
269
|
+
#inspectors;
|
|
270
|
+
constructor(src, sourceDesc = { name: "<input>" }, inspectors = []) {
|
|
271
|
+
this.src = src;
|
|
272
|
+
this.source = new StringSource(sourceDesc, src);
|
|
273
|
+
this.#inspectors = inspectors.toSorted((a, b) => a.position - b.position);
|
|
274
|
+
}
|
|
275
|
+
position() {
|
|
276
|
+
return this.#pos;
|
|
277
|
+
}
|
|
278
|
+
isEOF() {
|
|
279
|
+
return this.#pos >= this.src.length;
|
|
280
|
+
}
|
|
281
|
+
inspectors() {
|
|
282
|
+
let result = [];
|
|
283
|
+
while (this.#inspectors.length > 0 && this.#inspectors[0].position <= this.#pos) result.push(this.#inspectors.shift());
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
peek(str) {
|
|
287
|
+
assert(str !== "");
|
|
288
|
+
if (this.#pos + str.length > this.src.length) return false;
|
|
289
|
+
return this.src.slice(this.#pos, this.#pos + str.length) == str;
|
|
290
|
+
}
|
|
291
|
+
acceptChar() {
|
|
292
|
+
if (this.isEOF()) throw new RangeError("EOF");
|
|
293
|
+
let char = this.src[this.#pos];
|
|
294
|
+
this.#pos++;
|
|
295
|
+
return char;
|
|
296
|
+
}
|
|
297
|
+
accept(str) {
|
|
298
|
+
if (!this.peek(str)) return false;
|
|
299
|
+
this.#pos += str.length;
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
acceptWhitespaceChar() {
|
|
303
|
+
if (this.isEOF()) return null;
|
|
304
|
+
let char = this.src[this.#pos];
|
|
305
|
+
if (!" ".includes(char)) return null;
|
|
306
|
+
this.#pos++;
|
|
307
|
+
return char;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
//#endregion
|
|
312
|
+
//#region src/debug-print.ts
|
|
313
|
+
const debugPrint = {
|
|
314
|
+
blockModifier: (x) => `[.${x.name}] (${ModifierSlotType[x.slotType]})`,
|
|
315
|
+
inlineModifier: (x) => `[/${x.name}] (${ModifierSlotType[x.slotType]})`,
|
|
316
|
+
inlineShorthand: (x) => x.name + x.parts.map((x$1, i) => ` .. <arg${i}> .. ${x$1}`).join("") + (x.mod.slotType == ModifierSlotType.None ? "" : ` .. <slot> .. ${x.postfix ?? "<no postfix>"}`),
|
|
317
|
+
blockShorthand: (x) => x.name + x.parts.map((x$1, i) => ` .. <arg${i}> .. ${x$1}`).join("") + (x.mod.slotType == ModifierSlotType.None ? "" : ` .. <slot> .. ${x.postfix ?? "<no postfix>"}`),
|
|
318
|
+
argument: (arg) => arg.content.map(debugPrintArgEntity).join(""),
|
|
319
|
+
node: (...nodes) => nodes.map((x) => debugPrintNode(x)).join("\n"),
|
|
320
|
+
message: debugPrintMsg,
|
|
321
|
+
range: debugPrintRange,
|
|
322
|
+
document: debugDumpDocument
|
|
323
|
+
};
|
|
324
|
+
function debugPrintArgEntity(node) {
|
|
325
|
+
switch (node.type) {
|
|
326
|
+
case NodeType.Text: return node.content;
|
|
327
|
+
case NodeType.Escaped: return `<Escaped:${node.content}>`;
|
|
328
|
+
case NodeType.Interpolation: return `<Interp:${node.definition.name}-${node.definition.postfix}:${debugPrint.argument(node.argument)}${node.expansion ? `=${node.expansion}` : ""}>`;
|
|
329
|
+
default: return debug.never(node);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function debugPrintNode(node, prefix = "") {
|
|
333
|
+
function debugPrintNodes(content, prefix$1 = "") {
|
|
334
|
+
let dumps = content.map((x) => debugPrintNode(x, prefix$1 + " ")).filter((x) => x.length > 0);
|
|
335
|
+
if (dumps.length == 0) return "";
|
|
336
|
+
return dumps.map((x) => `${prefix$1} ${x}`).join("\n");
|
|
337
|
+
}
|
|
338
|
+
let result = `<${NodeType[node.type]}@${node.location.start}`;
|
|
339
|
+
switch (node.type) {
|
|
340
|
+
case NodeType.Group:
|
|
341
|
+
case NodeType.Paragraph:
|
|
342
|
+
const content = debugPrintNodes(node.content, prefix);
|
|
343
|
+
if (content.length > 0) result += `>\n${content}\n${prefix}</${NodeType[node.type]}@${node.location.end}>`;
|
|
344
|
+
else result += `-${node.location.end} />`;
|
|
345
|
+
break;
|
|
346
|
+
case NodeType.Escaped:
|
|
347
|
+
result += `>\n${prefix} ${node.content}\n${prefix}</${NodeType[node.type]}@${node.location.end}>`;
|
|
348
|
+
break;
|
|
349
|
+
case NodeType.Preformatted:
|
|
350
|
+
result += `>\n${prefix} ${node.content.text}\n${prefix}</${NodeType[node.type]}@${node.location.end}>`;
|
|
351
|
+
break;
|
|
352
|
+
case NodeType.InlineModifier:
|
|
353
|
+
case NodeType.BlockModifier:
|
|
354
|
+
case NodeType.SystemModifier:
|
|
355
|
+
const posargs = node.arguments.positional.map((x, i) => `\n${prefix} (${i})@${x.location.start}-${x.location.end}=${debugPrint.argument(x)}`).join("");
|
|
356
|
+
const namedargs = [...node.arguments.named].map(([name, x], i) => `\n${prefix} <${name}>@${x.location.start}-${x.location.end}=${debugPrint.argument(x)}`).join("");
|
|
357
|
+
if (node.content.length > 0) result += ` id=${node.mod.name}${posargs}${namedargs}>\n` + debugPrintNodes(node.content, prefix) + `\n${prefix}</${NodeType[node.type]}@${node.location.end}>`;
|
|
358
|
+
else result += `-${node.location.end} id=${node.mod.name}${posargs}${namedargs} />`;
|
|
359
|
+
if (node.expansion) {
|
|
360
|
+
const content$1 = debugPrintNodes(node.expansion, prefix);
|
|
361
|
+
if (content$1.length > 0) result += `\n${prefix}<expansion>\n${content$1}\n${prefix}</expansion>`;
|
|
362
|
+
else if (node.type != NodeType.SystemModifier) result += `\n${prefix}<expansion />`;
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
365
|
+
case NodeType.Text: return node.content;
|
|
366
|
+
default: return debug.never(node);
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
function debugPrintRange(loc, context = 1) {
|
|
371
|
+
const isSingleCharacter = loc.start == loc.end;
|
|
372
|
+
let [sr, sc] = loc.source.getRowCol(loc.start);
|
|
373
|
+
let [er, ec] = loc.source.getRowCol(loc.actualEnd ?? loc.end);
|
|
374
|
+
const rowWidth = Math.max((sr + 1).toString().length, (er + 1).toString().length);
|
|
375
|
+
const startLine = Math.max(0, sr - context);
|
|
376
|
+
const endLine = Math.min(loc.source.nLines - 1, er + context);
|
|
377
|
+
let lines = [];
|
|
378
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
379
|
+
const line = loc.source.getRow(i);
|
|
380
|
+
lines.push((i + 1).toString().padStart(rowWidth) + " | " + line);
|
|
381
|
+
if (i >= sr && i <= er) {
|
|
382
|
+
const startPos = i == sr ? sc : 0;
|
|
383
|
+
const endPos = i == er ? ec : line.length;
|
|
384
|
+
lines.push(" ".repeat(rowWidth) + " | " + " ".repeat(startPos) + (isSingleCharacter ? "^" : "~".repeat(endPos - startPos + 1)));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return lines.join("\n");
|
|
388
|
+
}
|
|
389
|
+
function debugPrintMsg(m) {
|
|
390
|
+
const poss = (loc$1) => {
|
|
391
|
+
const [r1, c1] = loc$1.source.getRowCol(loc$1.start);
|
|
392
|
+
if (loc$1.start == loc$1.end) return `l${r1 + 1}c${c1 + 1}`;
|
|
393
|
+
const [r2, c2] = loc$1.source.getRowCol(loc$1.end);
|
|
394
|
+
return `l${r1 + 1}c${c1 + 1}-l${r2 + 1}c${c2 + 1}`;
|
|
395
|
+
};
|
|
396
|
+
let loc = m.location;
|
|
397
|
+
let result = `at ${poss(loc)}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
|
|
398
|
+
while (loc = loc.original) {
|
|
399
|
+
let d = loc.source !== m.location.source ? `(in ${loc.source.name}) ` : "";
|
|
400
|
+
result += `\n---> original at: ${d}${poss(loc)}`;
|
|
401
|
+
}
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
function debugDumpDocument(doc) {
|
|
405
|
+
let root = debugPrint.node(...doc.root.content);
|
|
406
|
+
let msgs = doc.messages.map((x) => debugPrintRange(x.location) + "\n" + debugPrintMsg(x)).join("\n");
|
|
407
|
+
if (msgs.length > 0) msgs += "\n";
|
|
408
|
+
return `Document: ${doc.root.source.name}\n${msgs}${root}`;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/messages.ts
|
|
413
|
+
var messages_exports = /* @__PURE__ */ __export({
|
|
414
|
+
ArgumentCountMismatchMessage: () => ArgumentCountMismatchMessage,
|
|
415
|
+
CannotExpandArgumentMessage: () => CannotExpandArgumentMessage,
|
|
416
|
+
CannotUseModuleInSelfMessage: () => CannotUseModuleInSelfMessage,
|
|
417
|
+
ContentExpectedMessage: () => ContentExpectedMessage,
|
|
418
|
+
DuplicateNamedArgumentMessage: () => DuplicateNamedArgumentMessage,
|
|
419
|
+
EitherNormalOrPreMessage: () => EitherNormalOrPreMessage,
|
|
420
|
+
EntityNotAllowedMessage: () => EntityNotAllowedMessage,
|
|
421
|
+
ExpectedMessage: () => ExpectedMessage,
|
|
422
|
+
InternalErrorMessage: () => InternalErrorMessage,
|
|
423
|
+
InvalidArgumentMessage: () => InvalidArgumentMessage,
|
|
424
|
+
MultipleBlocksNotPermittedMessage: () => MultipleBlocksNotPermittedMessage,
|
|
425
|
+
NameAlreadyDefinedMessage: () => NameAlreadyDefinedMessage,
|
|
426
|
+
NewBlockShouldBeOnNewlineMessage: () => NewBlockShouldBeOnNewlineMessage,
|
|
427
|
+
NoNestedModuleMessage: () => NoNestedModuleMessage,
|
|
428
|
+
OnlySimpleParagraphsPermittedMessage: () => OnlySimpleParagraphsPermittedMessage,
|
|
429
|
+
OverwriteDefinitionsMessage: () => OverwriteDefinitionsMessage,
|
|
430
|
+
OverwriteSpecialVariableMessage: () => OverwriteSpecialVariableMessage,
|
|
431
|
+
ReachedRecursionLimitMessage: () => ReachedRecursionLimitMessage,
|
|
432
|
+
ShouldBeOnNewlineMessage: () => ShouldBeOnNewlineMessage,
|
|
433
|
+
SlotUsedOutsideDefinitionMessage: () => SlotUsedOutsideDefinitionMessage,
|
|
434
|
+
UnclosedInlineModifierMessage: () => UnclosedInlineModifierMessage,
|
|
435
|
+
UndefinedVariableMessage: () => UndefinedVariableMessage,
|
|
436
|
+
UnknownModifierMessage: () => UnknownModifierMessage,
|
|
437
|
+
UnnecessaryNewlineMessage: () => UnnecessaryNewlineMessage
|
|
438
|
+
});
|
|
439
|
+
var AddThingMessage = class {
|
|
440
|
+
constructor(code, severity, location, info) {
|
|
441
|
+
this.code = code;
|
|
442
|
+
this.severity = severity;
|
|
443
|
+
this.location = location;
|
|
444
|
+
this.info = info;
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
var RemoveThingMessage = class {
|
|
448
|
+
constructor(code, severity, location, info) {
|
|
449
|
+
this.code = code;
|
|
450
|
+
this.severity = severity;
|
|
451
|
+
this.location = location;
|
|
452
|
+
this.info = info;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
var ExpectedMessage = class {
|
|
456
|
+
constructor(location, what) {
|
|
457
|
+
this.location = location;
|
|
458
|
+
this.what = what;
|
|
459
|
+
assert(location.end == location.start);
|
|
460
|
+
}
|
|
461
|
+
code = 1;
|
|
462
|
+
severity = MessageSeverity.Error;
|
|
463
|
+
get info() {
|
|
464
|
+
return `expected '${this.what}'`;
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
var UnknownModifierMessage = class {
|
|
468
|
+
constructor(location, what) {
|
|
469
|
+
this.location = location;
|
|
470
|
+
this.what = what;
|
|
471
|
+
}
|
|
472
|
+
code = 2;
|
|
473
|
+
severity = MessageSeverity.Error;
|
|
474
|
+
get info() {
|
|
475
|
+
return `unknown modifier '${this.what}'`;
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
var UnclosedInlineModifierMessage = class {
|
|
479
|
+
constructor(location, what) {
|
|
480
|
+
this.location = location;
|
|
481
|
+
this.what = what;
|
|
482
|
+
assert(location.end == location.start);
|
|
483
|
+
}
|
|
484
|
+
code = 3;
|
|
485
|
+
severity = MessageSeverity.Error;
|
|
486
|
+
get info() {
|
|
487
|
+
return `unclosed inline modifier ${this.what}'`;
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
var ArgumentCountMismatchMessage = class {
|
|
491
|
+
constructor(location, min, max) {
|
|
492
|
+
this.location = location;
|
|
493
|
+
if (min !== void 0) if (max == min) this.msg = `: ${min} expected`;
|
|
494
|
+
else if (max !== void 0) this.msg = `: ${min} to ${max} expected`;
|
|
495
|
+
else this.msg = `: at least ${min} expected`;
|
|
496
|
+
else if (max !== void 0) this.msg = `: at most ${max} expected`;
|
|
497
|
+
}
|
|
498
|
+
msg = "";
|
|
499
|
+
code = 4;
|
|
500
|
+
severity = MessageSeverity.Error;
|
|
501
|
+
get info() {
|
|
502
|
+
return `argument count mismatch` + this.msg;
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var CannotExpandArgumentMessage = class {
|
|
506
|
+
constructor(location, what) {
|
|
507
|
+
this.location = location;
|
|
508
|
+
this.what = what;
|
|
509
|
+
}
|
|
510
|
+
code = 5;
|
|
511
|
+
severity = MessageSeverity.Error;
|
|
512
|
+
get info() {
|
|
513
|
+
return `failed to expand argument` + (this.what === void 0 ? "" : `: ${this.what}`);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
var InvalidArgumentMessage = class {
|
|
517
|
+
constructor(location, what) {
|
|
518
|
+
this.location = location;
|
|
519
|
+
this.what = what;
|
|
520
|
+
}
|
|
521
|
+
code = 6;
|
|
522
|
+
severity = MessageSeverity.Error;
|
|
523
|
+
get info() {
|
|
524
|
+
return `invalid argument` + (this.what === void 0 ? "" : `: ${this.what}`);
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var EntityNotAllowedMessage = class {
|
|
528
|
+
constructor(location, what) {
|
|
529
|
+
this.location = location;
|
|
530
|
+
this.what = what;
|
|
531
|
+
}
|
|
532
|
+
code = 7;
|
|
533
|
+
severity = MessageSeverity.Error;
|
|
534
|
+
get info() {
|
|
535
|
+
return "This entity is not allowed here" + (this.what ? `: ${this.what}` : "");
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
var ReachedRecursionLimitMessage = class {
|
|
539
|
+
constructor(location, limit, what) {
|
|
540
|
+
this.location = location;
|
|
541
|
+
this.limit = limit;
|
|
542
|
+
this.what = what;
|
|
543
|
+
}
|
|
544
|
+
code = 8;
|
|
545
|
+
severity = MessageSeverity.Error;
|
|
546
|
+
get info() {
|
|
547
|
+
return `Reached recursion limit ${this.limit} when expanding ${this.what}`;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
var SlotUsedOutsideDefinitionMessage = class {
|
|
551
|
+
constructor(location) {
|
|
552
|
+
this.location = location;
|
|
553
|
+
}
|
|
554
|
+
code = 9;
|
|
555
|
+
severity = MessageSeverity.Error;
|
|
556
|
+
get info() {
|
|
557
|
+
return `slot used outside a definition`;
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
var NoNestedModuleMessage = class {
|
|
561
|
+
constructor(location) {
|
|
562
|
+
this.location = location;
|
|
563
|
+
}
|
|
564
|
+
code = 10;
|
|
565
|
+
severity = MessageSeverity.Error;
|
|
566
|
+
get info() {
|
|
567
|
+
return `nested module definitions not allowed`;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
var CannotUseModuleInSelfMessage = class {
|
|
571
|
+
constructor(location) {
|
|
572
|
+
this.location = location;
|
|
573
|
+
}
|
|
574
|
+
code = 11;
|
|
575
|
+
severity = MessageSeverity.Error;
|
|
576
|
+
get info() {
|
|
577
|
+
return `cannot use the same module inside its definition`;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
var EitherNormalOrPreMessage = class {
|
|
581
|
+
constructor(location) {
|
|
582
|
+
this.location = location;
|
|
583
|
+
}
|
|
584
|
+
code = 12;
|
|
585
|
+
severity = MessageSeverity.Error;
|
|
586
|
+
get info() {
|
|
587
|
+
return `a definition cannot be at once normal and preformatted`;
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
var MultipleBlocksNotPermittedMessage = class {
|
|
591
|
+
constructor(location) {
|
|
592
|
+
this.location = location;
|
|
593
|
+
}
|
|
594
|
+
code = 13;
|
|
595
|
+
severity = MessageSeverity.Error;
|
|
596
|
+
get info() {
|
|
597
|
+
return `multiple blocks are not permitted here`;
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
var OnlySimpleParagraphsPermittedMessage = class {
|
|
601
|
+
constructor(location) {
|
|
602
|
+
this.location = location;
|
|
603
|
+
}
|
|
604
|
+
code = 14;
|
|
605
|
+
severity = MessageSeverity.Error;
|
|
606
|
+
get info() {
|
|
607
|
+
return `only simple paragraphs are permitted here`;
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
var ContentExpectedMessage = class {
|
|
611
|
+
constructor(location) {
|
|
612
|
+
this.location = location;
|
|
613
|
+
}
|
|
614
|
+
code = 15;
|
|
615
|
+
severity = MessageSeverity.Error;
|
|
616
|
+
get info() {
|
|
617
|
+
return `content expected`;
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
var InternalErrorMessage = class {
|
|
621
|
+
constructor(location, error) {
|
|
622
|
+
this.location = location;
|
|
623
|
+
this.error = error;
|
|
624
|
+
}
|
|
625
|
+
code = 16;
|
|
626
|
+
severity = MessageSeverity.Error;
|
|
627
|
+
get info() {
|
|
628
|
+
return `an internal error occurred when parsing: ${this.error}`;
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
var DuplicateNamedArgumentMessage = class {
|
|
632
|
+
constructor(location, name) {
|
|
633
|
+
this.location = location;
|
|
634
|
+
this.name = name;
|
|
635
|
+
}
|
|
636
|
+
code = 17;
|
|
637
|
+
severity = MessageSeverity.Error;
|
|
638
|
+
get info() {
|
|
639
|
+
return `an argument has already been defined with the same name "${this.name}"`;
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
var UnnecessaryNewlineMessage = class extends RemoveThingMessage {
|
|
643
|
+
constructor(location) {
|
|
644
|
+
super(1, MessageSeverity.Warning, location, "more than one newlines have the same effect as one");
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
var NewBlockShouldBeOnNewlineMessage = class extends AddThingMessage {
|
|
648
|
+
constructor(location) {
|
|
649
|
+
super(2, MessageSeverity.Warning, location, "a new block should begin in a new line to avoid confusion");
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
var ShouldBeOnNewlineMessage = class extends AddThingMessage {
|
|
653
|
+
constructor(location) {
|
|
654
|
+
super(3, MessageSeverity.Warning, location, "the following should begin in a new line to avoid confusion");
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var NameAlreadyDefinedMessage = class {
|
|
658
|
+
constructor(location, what) {
|
|
659
|
+
this.location = location;
|
|
660
|
+
this.what = what;
|
|
661
|
+
}
|
|
662
|
+
code = 4;
|
|
663
|
+
severity = MessageSeverity.Warning;
|
|
664
|
+
get info() {
|
|
665
|
+
return `name is already defined, will overwrite: ${this.what}`;
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
var UndefinedVariableMessage = class {
|
|
669
|
+
constructor(location, what) {
|
|
670
|
+
this.location = location;
|
|
671
|
+
this.what = what;
|
|
672
|
+
}
|
|
673
|
+
code = 5;
|
|
674
|
+
severity = MessageSeverity.Warning;
|
|
675
|
+
get info() {
|
|
676
|
+
return `variable is undefined, will expand to empty string: ${this.what}`;
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
var OverwriteDefinitionsMessage = class {
|
|
680
|
+
constructor(location, what) {
|
|
681
|
+
this.location = location;
|
|
682
|
+
this.what = what;
|
|
683
|
+
}
|
|
684
|
+
code = 6;
|
|
685
|
+
severity = MessageSeverity.Warning;
|
|
686
|
+
get info() {
|
|
687
|
+
return `using this module will overwrite: ${this.what}`;
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
var OverwriteSpecialVariableMessage = class {
|
|
691
|
+
constructor(location, varname, previous) {
|
|
692
|
+
this.location = location;
|
|
693
|
+
this.varname = varname;
|
|
694
|
+
this.previous = previous;
|
|
695
|
+
}
|
|
696
|
+
code = 6;
|
|
697
|
+
severity = MessageSeverity.Warning;
|
|
698
|
+
get info() {
|
|
699
|
+
return `${this.varname} is already defined (as "${this.previous}"), will be overwritten`;
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
//#endregion
|
|
704
|
+
//#region src/node-util.ts
|
|
705
|
+
const cloneArgument = (arg, options) => ({
|
|
706
|
+
location: cloneLocation(arg.location, options),
|
|
707
|
+
content: arg.content.map((ent) => {
|
|
708
|
+
switch (ent.type) {
|
|
709
|
+
case NodeType.Text:
|
|
710
|
+
case NodeType.Escaped: return cloneNode(ent, options);
|
|
711
|
+
case NodeType.Interpolation: return {
|
|
712
|
+
type: ent.type,
|
|
713
|
+
location: cloneLocation(arg.location, options),
|
|
714
|
+
definition: ent.definition,
|
|
715
|
+
argument: cloneArgument(ent.argument, options),
|
|
716
|
+
expansion: ent.expansion
|
|
717
|
+
};
|
|
718
|
+
default: return debug.never(ent);
|
|
719
|
+
}
|
|
720
|
+
})
|
|
721
|
+
});
|
|
722
|
+
function cloneLocation(pos, options) {
|
|
723
|
+
let base = options.newLocation ?? pos;
|
|
724
|
+
return {
|
|
725
|
+
start: base.start,
|
|
726
|
+
end: base.end,
|
|
727
|
+
actualEnd: base.actualEnd,
|
|
728
|
+
original: options.newLocation ? pos : pos.original,
|
|
729
|
+
source: base.source
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
function cloneNode(node, options = {}) {
|
|
733
|
+
switch (node.type) {
|
|
734
|
+
case NodeType.BlockModifier:
|
|
735
|
+
case NodeType.InlineModifier:
|
|
736
|
+
case NodeType.SystemModifier: return {
|
|
737
|
+
location: cloneLocation(node.location, options),
|
|
738
|
+
type: node.type,
|
|
739
|
+
mod: node.mod,
|
|
740
|
+
state: options.withState ? node.state : void 0,
|
|
741
|
+
head: cloneLocation(node.head, options),
|
|
742
|
+
arguments: {
|
|
743
|
+
positional: node.arguments.positional.map((x) => cloneArgument(x, options)),
|
|
744
|
+
named: new Map([...node.arguments.named].map(([x, y]) => [x, cloneArgument(y, options)]))
|
|
745
|
+
},
|
|
746
|
+
content: node.content.map((x) => cloneNode(x, options)),
|
|
747
|
+
expansion: node.expansion ? cloneNodes(node.expansion, options) : void 0
|
|
748
|
+
};
|
|
749
|
+
case NodeType.Root: return {
|
|
750
|
+
type: node.type,
|
|
751
|
+
source: node.source,
|
|
752
|
+
content: node.content.map((x) => cloneNode(x, options))
|
|
753
|
+
};
|
|
754
|
+
case NodeType.Group: return {
|
|
755
|
+
type: node.type,
|
|
756
|
+
location: cloneLocation(node.location, options),
|
|
757
|
+
content: node.content.map((x) => cloneNode(x, options))
|
|
758
|
+
};
|
|
759
|
+
case NodeType.Paragraph: return {
|
|
760
|
+
type: node.type,
|
|
761
|
+
location: cloneLocation(node.location, options),
|
|
762
|
+
content: node.content.map((x) => cloneNode(x, options))
|
|
763
|
+
};
|
|
764
|
+
case NodeType.Preformatted: return {
|
|
765
|
+
type: node.type,
|
|
766
|
+
location: cloneLocation(node.location, options),
|
|
767
|
+
content: { ...node.content }
|
|
768
|
+
};
|
|
769
|
+
case NodeType.Text:
|
|
770
|
+
case NodeType.Escaped: return {
|
|
771
|
+
type: node.type,
|
|
772
|
+
location: cloneLocation(node.location, options),
|
|
773
|
+
content: node.content
|
|
774
|
+
};
|
|
775
|
+
default: return debug.never(node);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function cloneNodes(nodes, options = {}) {
|
|
779
|
+
return nodes.map((x) => cloneNode(x, options));
|
|
780
|
+
}
|
|
781
|
+
/** Warning: modifies the original nodes */
|
|
782
|
+
function stripNode(...nodes) {
|
|
783
|
+
return nodes.flatMap((node) => {
|
|
784
|
+
switch (node.type) {
|
|
785
|
+
case NodeType.Preformatted:
|
|
786
|
+
case NodeType.Text:
|
|
787
|
+
case NodeType.Escaped: return [node];
|
|
788
|
+
case NodeType.BlockModifier:
|
|
789
|
+
case NodeType.InlineModifier: if (node.expansion !== void 0) return node.expansion.flatMap((x) => stripNode(x));
|
|
790
|
+
case NodeType.Root:
|
|
791
|
+
case NodeType.Group:
|
|
792
|
+
case NodeType.Paragraph:
|
|
793
|
+
node.content = node.content.flatMap((x) => stripNode(x));
|
|
794
|
+
return [node];
|
|
795
|
+
case NodeType.SystemModifier: return [];
|
|
796
|
+
default: return debug.never(node);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
//#endregion
|
|
802
|
+
//#region src/parser-config.ts
|
|
803
|
+
var ParseContext = class {
|
|
804
|
+
data = {};
|
|
805
|
+
usedModules = /* @__PURE__ */ new Set();
|
|
806
|
+
constructor(config$1, variables = /* @__PURE__ */ new Map()) {
|
|
807
|
+
this.config = config$1;
|
|
808
|
+
this.variables = variables;
|
|
809
|
+
config$1.initializers.forEach((x) => x(this));
|
|
810
|
+
}
|
|
811
|
+
init(key, obj) {
|
|
812
|
+
assert(!(key in this.data));
|
|
813
|
+
this.data[key] = obj;
|
|
814
|
+
}
|
|
815
|
+
set(key, obj) {
|
|
816
|
+
assert(key in this.data);
|
|
817
|
+
this.data[key] = obj;
|
|
818
|
+
}
|
|
819
|
+
get(key) {
|
|
820
|
+
assert(key in this.data);
|
|
821
|
+
return this.data[key];
|
|
822
|
+
}
|
|
823
|
+
parse(scanner) {
|
|
824
|
+
return new Parser(scanner, this).parse();
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
var Document = class Document {
|
|
828
|
+
constructor(root, context, messages) {
|
|
829
|
+
this.root = root;
|
|
830
|
+
this.context = context;
|
|
831
|
+
this.messages = messages;
|
|
832
|
+
}
|
|
833
|
+
toStripped() {
|
|
834
|
+
return new Document(stripNode(cloneNode(this.root, { withState: true }))[0], this.context, this.messages);
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Performs a depth-first walk of the node tree.
|
|
838
|
+
*/
|
|
839
|
+
walk(callback) {
|
|
840
|
+
let nodes = this.root.content;
|
|
841
|
+
let node;
|
|
842
|
+
while (node = nodes.shift()) {
|
|
843
|
+
const result = callback(node);
|
|
844
|
+
if (result == "break") break;
|
|
845
|
+
if (result == "skip") continue;
|
|
846
|
+
if ("arguments" in node) {
|
|
847
|
+
nodes.push(...node.arguments.positional.flatMap((x) => x.content));
|
|
848
|
+
nodes.push(...[...node.arguments.named].flatMap(([_name, x]) => x.content));
|
|
849
|
+
}
|
|
850
|
+
if ("content" in node && Array.isArray(node.content)) nodes.push(...node.content);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Gets all nodes that covers the given position, from outermost to innermost (essentially a path).
|
|
855
|
+
*/
|
|
856
|
+
resolvePosition(pos) {
|
|
857
|
+
const result = [];
|
|
858
|
+
this.walk((node) => {
|
|
859
|
+
if (node.location.start <= pos && (node.location.actualEnd ?? node.location.end) >= pos) {
|
|
860
|
+
result.push(node);
|
|
861
|
+
return "continue";
|
|
862
|
+
}
|
|
863
|
+
return "skip";
|
|
864
|
+
});
|
|
865
|
+
return result;
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
var Configuration = class Configuration {
|
|
869
|
+
initializers = [];
|
|
870
|
+
modules = /* @__PURE__ */ new Map();
|
|
871
|
+
blockModifiers = new NameManager();
|
|
872
|
+
inlineModifiers = new NameManager();
|
|
873
|
+
systemModifiers = new NameManager();
|
|
874
|
+
argumentInterpolators = new NameManager();
|
|
875
|
+
blockShorthands = new NameManager();
|
|
876
|
+
inlineShorthands = new NameManager();
|
|
877
|
+
kernel = {
|
|
878
|
+
collapseWhitespaces: false,
|
|
879
|
+
reparseDepthLimit: 10
|
|
880
|
+
};
|
|
881
|
+
static from(from) {
|
|
882
|
+
let config$1 = new Configuration();
|
|
883
|
+
config$1.initializers = [...from.initializers];
|
|
884
|
+
config$1.kernel = structuredClone(from.kernel);
|
|
885
|
+
config$1.blockModifiers = new NameManager(from.blockModifiers);
|
|
886
|
+
config$1.inlineModifiers = new NameManager(from.inlineModifiers);
|
|
887
|
+
config$1.systemModifiers = new NameManager(from.systemModifiers);
|
|
888
|
+
config$1.argumentInterpolators = new NameManager(from.argumentInterpolators);
|
|
889
|
+
config$1.blockShorthands = new NameManager(from.blockShorthands);
|
|
890
|
+
config$1.inlineShorthands = new NameManager(from.inlineShorthands);
|
|
891
|
+
return config$1;
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
//#endregion
|
|
896
|
+
//#region src/parser.ts
|
|
897
|
+
const ESCAPE_CHAR = "\\";
|
|
898
|
+
const GROUP_BEGIN = "<<<";
|
|
899
|
+
const GROUP_END = ">>>";
|
|
900
|
+
const MODIFIER_BLOCK_OPEN = "[.";
|
|
901
|
+
const MODIFIER_INLINE_OPEN = "[/";
|
|
902
|
+
const MODIFIER_SYSTEM_OPEN = "[-";
|
|
903
|
+
const MODIFIER_CLOSE_SIGN = "]";
|
|
904
|
+
const MODIFIER_END_SIGN = ";";
|
|
905
|
+
const MODIFIER_INLINE_END_TAG = "[;]";
|
|
906
|
+
const MODIFIER_ARGUMENT_SEPARATOR = "|";
|
|
907
|
+
const UnknownModifier = {
|
|
908
|
+
[NodeType.BlockModifier]: new BlockModifierDefinition("UNKNOWN", ModifierSlotType.Normal),
|
|
909
|
+
[NodeType.InlineModifier]: new InlineModifierDefinition("UNKNOWN", ModifierSlotType.Normal),
|
|
910
|
+
[NodeType.SystemModifier]: new SystemModifierDefinition("UNKNOWN", ModifierSlotType.Normal)
|
|
911
|
+
};
|
|
912
|
+
var EmitEnvironment = class {
|
|
913
|
+
root;
|
|
914
|
+
messages = [];
|
|
915
|
+
blockStack = [];
|
|
916
|
+
inlineStack = [];
|
|
917
|
+
constructor(scanner) {
|
|
918
|
+
this.scanner = scanner;
|
|
919
|
+
this.root = {
|
|
920
|
+
type: NodeType.Root,
|
|
921
|
+
source: scanner.source,
|
|
922
|
+
content: []
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
message(...m) {
|
|
926
|
+
for (let msg of m) {
|
|
927
|
+
this.messages.push(msg);
|
|
928
|
+
debug.trace("issued msg", msg.code, msg.info);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
addBlockNode(n) {
|
|
932
|
+
(this.blockStack.at(-1) ?? this.root).content.push(n);
|
|
933
|
+
return n;
|
|
934
|
+
}
|
|
935
|
+
addInlineNode(n) {
|
|
936
|
+
assert(this.inlineStack.length > 0);
|
|
937
|
+
this.inlineStack.at(-1).content.push(n);
|
|
938
|
+
return n;
|
|
939
|
+
}
|
|
940
|
+
addString(str) {
|
|
941
|
+
assert(this.inlineStack.length > 0);
|
|
942
|
+
const content = this.inlineStack.at(-1).content;
|
|
943
|
+
const last = content.at(-1);
|
|
944
|
+
if (last?.type == NodeType.Text) {
|
|
945
|
+
last.content += str;
|
|
946
|
+
last.location.end = this.scanner.position();
|
|
947
|
+
} else content.push({
|
|
948
|
+
type: NodeType.Text,
|
|
949
|
+
location: {
|
|
950
|
+
source: this.scanner.source,
|
|
951
|
+
start: this.scanner.position() - str.length,
|
|
952
|
+
end: this.scanner.position()
|
|
953
|
+
},
|
|
954
|
+
content: str
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
startBlock(block) {
|
|
958
|
+
this.addBlockNode(block);
|
|
959
|
+
this.blockStack.push(block);
|
|
960
|
+
}
|
|
961
|
+
endBlock() {
|
|
962
|
+
assert(this.blockStack.length > 0);
|
|
963
|
+
const node = this.blockStack.pop();
|
|
964
|
+
node.location.end = this.scanner.position();
|
|
965
|
+
}
|
|
966
|
+
startInline(n) {
|
|
967
|
+
if (n.type == NodeType.Paragraph) this.addBlockNode(n);
|
|
968
|
+
else this.addInlineNode(n);
|
|
969
|
+
this.inlineStack.push(n);
|
|
970
|
+
}
|
|
971
|
+
endInline() {
|
|
972
|
+
assert(this.inlineStack.length > 0);
|
|
973
|
+
const node = this.inlineStack.pop();
|
|
974
|
+
node.location.end = this.scanner.position();
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
var Parser = class {
|
|
978
|
+
emit;
|
|
979
|
+
delayDepth = 0;
|
|
980
|
+
constructor(scanner, cxt) {
|
|
981
|
+
this.scanner = scanner;
|
|
982
|
+
this.cxt = cxt;
|
|
983
|
+
this.emit = new EmitEnvironment(scanner);
|
|
984
|
+
}
|
|
985
|
+
#loc(to) {
|
|
986
|
+
return {
|
|
987
|
+
source: this.scanner.source,
|
|
988
|
+
start: this.scanner.position(),
|
|
989
|
+
end: to ?? this.scanner.position()
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
#locFrom(from, to) {
|
|
993
|
+
return {
|
|
994
|
+
source: this.scanner.source,
|
|
995
|
+
start: from,
|
|
996
|
+
end: to ?? this.scanner.position()
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
/* istanbul ignore next -- @preserve */
|
|
1000
|
+
#defs(type) {
|
|
1001
|
+
switch (type) {
|
|
1002
|
+
case NodeType.SystemModifier: return this.cxt.config.systemModifiers;
|
|
1003
|
+
case NodeType.InlineModifier: return this.cxt.config.inlineModifiers;
|
|
1004
|
+
case NodeType.BlockModifier: return this.cxt.config.blockModifiers;
|
|
1005
|
+
default: return debug.never(type);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
#reparse(nodes, depth) {
|
|
1009
|
+
if (depth > this.cxt.config.kernel.reparseDepthLimit) return false;
|
|
1010
|
+
let ok = true;
|
|
1011
|
+
for (const node of nodes) switch (node.type) {
|
|
1012
|
+
case NodeType.Preformatted:
|
|
1013
|
+
case NodeType.Text:
|
|
1014
|
+
case NodeType.Escaped: continue;
|
|
1015
|
+
case NodeType.Group:
|
|
1016
|
+
case NodeType.Paragraph:
|
|
1017
|
+
ok = this.#reparse(node.content, depth + 1) && ok;
|
|
1018
|
+
continue;
|
|
1019
|
+
case NodeType.BlockModifier:
|
|
1020
|
+
case NodeType.InlineModifier:
|
|
1021
|
+
case NodeType.SystemModifier:
|
|
1022
|
+
ok = this.#expand(node, depth + 1) && ok;
|
|
1023
|
+
continue;
|
|
1024
|
+
default: debug.never(node);
|
|
1025
|
+
}
|
|
1026
|
+
return ok;
|
|
1027
|
+
}
|
|
1028
|
+
#expandArgument(arg) {
|
|
1029
|
+
if (arg.expansion !== void 0) return arg.expansion;
|
|
1030
|
+
let result = "";
|
|
1031
|
+
const immediate = this.delayDepth == 0;
|
|
1032
|
+
for (const e of arg.content) switch (e.type) {
|
|
1033
|
+
case NodeType.Text:
|
|
1034
|
+
case NodeType.Escaped:
|
|
1035
|
+
result += e.content;
|
|
1036
|
+
break;
|
|
1037
|
+
case NodeType.Interpolation:
|
|
1038
|
+
if (e.expansion === void 0) {
|
|
1039
|
+
const inner = this.#expandArgument(e.argument);
|
|
1040
|
+
if (inner === void 0 || e.definition.expand === void 0 || !immediate && !e.definition.alwaysTryExpand) return void 0;
|
|
1041
|
+
e.expansion = e.definition.expand(inner, this.cxt, immediate);
|
|
1042
|
+
if (e.expansion === void 0) return void 0;
|
|
1043
|
+
}
|
|
1044
|
+
result += e.expansion;
|
|
1045
|
+
break;
|
|
1046
|
+
default: debug.never(e);
|
|
1047
|
+
}
|
|
1048
|
+
arg.expansion = result;
|
|
1049
|
+
return result;
|
|
1050
|
+
}
|
|
1051
|
+
#expandArguments(node) {
|
|
1052
|
+
for (const arg of node.arguments.positional) this.#expandArgument(arg);
|
|
1053
|
+
for (const [_name, arg] of node.arguments.named) this.#expandArgument(arg);
|
|
1054
|
+
}
|
|
1055
|
+
#tryAndMessage(node, fn, ...p) {
|
|
1056
|
+
if (!fn) return;
|
|
1057
|
+
try {
|
|
1058
|
+
this.emit.message(...fn.call(node.mod, ...p));
|
|
1059
|
+
} catch (e) {
|
|
1060
|
+
this.emit.message(new InternalErrorMessage(node.location, e));
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
#try(node, fn, ...p) {
|
|
1064
|
+
if (!fn) return;
|
|
1065
|
+
try {
|
|
1066
|
+
return fn.call(node.mod, ...p);
|
|
1067
|
+
} catch (e) {
|
|
1068
|
+
this.emit.message(new InternalErrorMessage(node.location, e));
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
#expand(node, depth = 0) {
|
|
1073
|
+
if (node.expansion !== void 0) {
|
|
1074
|
+
debug.trace("already expanded, skipping:", node.mod.name);
|
|
1075
|
+
return true;
|
|
1076
|
+
}
|
|
1077
|
+
if (depth > 0) this.#expandArguments(node);
|
|
1078
|
+
if (this.delayDepth > 0 && !node.mod.alwaysTryExpand) {
|
|
1079
|
+
debug.trace("delaying expansion of", node.mod.name);
|
|
1080
|
+
return true;
|
|
1081
|
+
}
|
|
1082
|
+
const immediate = this.delayDepth == 0;
|
|
1083
|
+
if (depth > 0) {
|
|
1084
|
+
this.#tryAndMessage(node, node.mod.beforeParseContent, node, this.cxt, immediate);
|
|
1085
|
+
if (node.content.length > 0) {
|
|
1086
|
+
if (node.mod.delayContentExpansion) this.delayDepth++;
|
|
1087
|
+
this.#reparse(node.content, depth);
|
|
1088
|
+
if (node.mod.delayContentExpansion) this.delayDepth--;
|
|
1089
|
+
}
|
|
1090
|
+
this.#tryAndMessage(node, node.mod.afterParseContent, node, this.cxt, immediate);
|
|
1091
|
+
}
|
|
1092
|
+
this.#tryAndMessage(node, node.mod.prepareExpand, node, this.cxt, immediate);
|
|
1093
|
+
if (node.mod.expand) {
|
|
1094
|
+
node.expansion = this.#try(node, node.mod.expand, node, this.cxt, immediate);
|
|
1095
|
+
if (!node.expansion) return true;
|
|
1096
|
+
debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
|
|
1097
|
+
if (node.expansion.length > 0) debug.trace(() => "-->\n" + debugPrint.node(...node.expansion));
|
|
1098
|
+
}
|
|
1099
|
+
this.#tryAndMessage(node, node.mod.beforeProcessExpansion, node, this.cxt, immediate);
|
|
1100
|
+
const expansion = node.expansion;
|
|
1101
|
+
if (!expansion || expansion.length == 0) return true;
|
|
1102
|
+
debug.trace("reparsing expansion of:", node.mod.name);
|
|
1103
|
+
let ok = this.#reparse(expansion, depth);
|
|
1104
|
+
debug.trace("done reparsing expansion of:", node.mod.name);
|
|
1105
|
+
this.#tryAndMessage(node, node.mod.afterProcessExpansion, node, this.cxt, immediate);
|
|
1106
|
+
if (!ok && depth == 0) {
|
|
1107
|
+
const limit = this.cxt.config.kernel.reparseDepthLimit;
|
|
1108
|
+
this.emit.message(new ReachedRecursionLimitMessage(node.location, limit, node.mod.name));
|
|
1109
|
+
}
|
|
1110
|
+
return ok;
|
|
1111
|
+
}
|
|
1112
|
+
parse() {
|
|
1113
|
+
this.DOCUMENT();
|
|
1114
|
+
return new Document(this.emit.root, this.cxt, this.emit.messages);
|
|
1115
|
+
}
|
|
1116
|
+
WHITESPACES() {
|
|
1117
|
+
while (this.scanner.acceptWhitespaceChar() !== null);
|
|
1118
|
+
}
|
|
1119
|
+
WHITESPACES_OR_NEWLINES() {
|
|
1120
|
+
while (this.scanner.acceptWhitespaceChar() !== null || this.scanner.accept("\n"));
|
|
1121
|
+
}
|
|
1122
|
+
SHOULD_BE_A_NEWLINE() {
|
|
1123
|
+
this.WHITESPACES();
|
|
1124
|
+
if (!this.scanner.accept("\n")) this.emit.message(new ShouldBeOnNewlineMessage(this.#loc()));
|
|
1125
|
+
}
|
|
1126
|
+
WARN_IF_MORE_NEWLINES_THAN(n) {
|
|
1127
|
+
let nlines = 0;
|
|
1128
|
+
const start = this.scanner.position();
|
|
1129
|
+
while (true) {
|
|
1130
|
+
if (this.scanner.accept("\n")) {
|
|
1131
|
+
nlines++;
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
if (this.scanner.acceptWhitespaceChar() == null) break;
|
|
1135
|
+
}
|
|
1136
|
+
const end = this.scanner.position();
|
|
1137
|
+
if (nlines > n) this.emit.message(new UnnecessaryNewlineMessage(this.#locFrom(start, end)));
|
|
1138
|
+
}
|
|
1139
|
+
DOCUMENT() {
|
|
1140
|
+
this.WHITESPACES_OR_NEWLINES();
|
|
1141
|
+
while (!this.scanner.isEOF()) {
|
|
1142
|
+
this.BLOCK_ENTITY();
|
|
1143
|
+
this.WHITESPACES_OR_NEWLINES();
|
|
1144
|
+
}
|
|
1145
|
+
this.scanner.inspectors().forEach((x) => x.callback(this.cxt, this.scanner.position()));
|
|
1146
|
+
}
|
|
1147
|
+
BLOCK_ENTITY() {
|
|
1148
|
+
assert(!this.scanner.isEOF());
|
|
1149
|
+
this.scanner.inspectors().forEach((x) => x.callback(this.cxt, this.scanner.position()));
|
|
1150
|
+
if (this.scanner.peek(MODIFIER_BLOCK_OPEN)) {
|
|
1151
|
+
this.MODIFIER(NodeType.BlockModifier);
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
if (this.scanner.peek(MODIFIER_SYSTEM_OPEN)) {
|
|
1155
|
+
this.MODIFIER(NodeType.SystemModifier);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
const short = this.cxt.config.blockShorthands.find((x) => this.scanner.accept(x.name));
|
|
1159
|
+
if (short) return this.SHORTHAND(NodeType.BlockModifier, short);
|
|
1160
|
+
this.MAYBE_GROUPED_PARAGRAPH();
|
|
1161
|
+
this.scanner.inspectors().forEach((x) => x.callback(this.cxt, this.scanner.position()));
|
|
1162
|
+
}
|
|
1163
|
+
MODIFIER(type) {
|
|
1164
|
+
const posStart = this.scanner.position();
|
|
1165
|
+
assert(this.scanner.accept({
|
|
1166
|
+
[NodeType.BlockModifier]: MODIFIER_BLOCK_OPEN,
|
|
1167
|
+
[NodeType.SystemModifier]: MODIFIER_SYSTEM_OPEN,
|
|
1168
|
+
[NodeType.InlineModifier]: MODIFIER_INLINE_OPEN
|
|
1169
|
+
}[type]));
|
|
1170
|
+
const result = this.#defs(type).find((x) => this.scanner.accept(x.name));
|
|
1171
|
+
const mod = result ?? UnknownModifier[type];
|
|
1172
|
+
if (result === void 0) {
|
|
1173
|
+
let name = "";
|
|
1174
|
+
while (!this.scanner.isEOF() && !this.scanner.acceptWhitespaceChar() && !this.scanner.peek(MODIFIER_CLOSE_SIGN) && !this.scanner.peek(MODIFIER_END_SIGN)) {
|
|
1175
|
+
if (this.scanner.accept(ESCAPE_CHAR)) {
|
|
1176
|
+
if (this.scanner.isEOF()) break;
|
|
1177
|
+
}
|
|
1178
|
+
name += this.scanner.acceptChar();
|
|
1179
|
+
}
|
|
1180
|
+
this.emit.message(new UnknownModifierMessage(this.#locFrom(posStart), name));
|
|
1181
|
+
}
|
|
1182
|
+
const args = this.ARGUMENTS();
|
|
1183
|
+
debug.trace(`PARSE ${NodeType[type]}:`, mod.name);
|
|
1184
|
+
const endsign = this.scanner.accept(MODIFIER_END_SIGN);
|
|
1185
|
+
const flagMarker = mod.slotType == ModifierSlotType.None;
|
|
1186
|
+
if (!this.scanner.accept(MODIFIER_CLOSE_SIGN)) this.emit.message(new ExpectedMessage(this.#loc(), MODIFIER_CLOSE_SIGN));
|
|
1187
|
+
const headEnd = this.scanner.position();
|
|
1188
|
+
const node = {
|
|
1189
|
+
type,
|
|
1190
|
+
mod,
|
|
1191
|
+
head: this.#locFrom(posStart, headEnd),
|
|
1192
|
+
location: this.#locFrom(posStart, headEnd),
|
|
1193
|
+
arguments: args,
|
|
1194
|
+
content: [],
|
|
1195
|
+
expansion: void 0
|
|
1196
|
+
};
|
|
1197
|
+
const isMarker = flagMarker || endsign;
|
|
1198
|
+
return this.MODIFIER_BODY(type, node, MODIFIER_INLINE_END_TAG, isMarker);
|
|
1199
|
+
}
|
|
1200
|
+
PRE_PARAGRAPH() {
|
|
1201
|
+
assert(!this.scanner.isEOF());
|
|
1202
|
+
const posStart = this.scanner.position();
|
|
1203
|
+
const grouped = this.scanner.accept(GROUP_BEGIN);
|
|
1204
|
+
if (grouped) this.SHOULD_BE_A_NEWLINE();
|
|
1205
|
+
const posContentStart = this.scanner.position();
|
|
1206
|
+
let posContentEnd = this.scanner.position();
|
|
1207
|
+
let paragraphEnd = void 0;
|
|
1208
|
+
let string = "";
|
|
1209
|
+
while (!this.scanner.isEOF()) {
|
|
1210
|
+
if (this.scanner.accept("\n")) {
|
|
1211
|
+
let white = "\n";
|
|
1212
|
+
let char;
|
|
1213
|
+
while ((char = this.scanner.acceptWhitespaceChar()) !== null) white += char;
|
|
1214
|
+
if (grouped && this.scanner.accept(GROUP_END)) {
|
|
1215
|
+
paragraphEnd = this.scanner.position();
|
|
1216
|
+
if (!this.scanner.isEOF()) {
|
|
1217
|
+
this.SHOULD_BE_A_NEWLINE();
|
|
1218
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1219
|
+
}
|
|
1220
|
+
break;
|
|
1221
|
+
}
|
|
1222
|
+
if (!grouped && this.scanner.accept("\n")) {
|
|
1223
|
+
paragraphEnd = this.scanner.position() - 1;
|
|
1224
|
+
if (!this.scanner.isEOF()) this.WARN_IF_MORE_NEWLINES_THAN(0);
|
|
1225
|
+
break;
|
|
1226
|
+
}
|
|
1227
|
+
if (this.scanner.isEOF()) {
|
|
1228
|
+
if (grouped) this.emit.message(new ExpectedMessage(this.#loc(), GROUP_END));
|
|
1229
|
+
break;
|
|
1230
|
+
}
|
|
1231
|
+
string += white;
|
|
1232
|
+
} else string += this.scanner.acceptChar();
|
|
1233
|
+
posContentEnd = this.scanner.position();
|
|
1234
|
+
}
|
|
1235
|
+
const node = {
|
|
1236
|
+
type: NodeType.Preformatted,
|
|
1237
|
+
location: this.#locFrom(posStart, paragraphEnd ?? posContentEnd),
|
|
1238
|
+
content: {
|
|
1239
|
+
start: posContentStart,
|
|
1240
|
+
end: posContentEnd,
|
|
1241
|
+
text: string
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
this.emit.addBlockNode(node);
|
|
1245
|
+
}
|
|
1246
|
+
MAYBE_GROUPED_PARAGRAPH() {
|
|
1247
|
+
assert(!this.scanner.isEOF());
|
|
1248
|
+
const posStart = this.scanner.position();
|
|
1249
|
+
if (this.scanner.accept(GROUP_BEGIN)) {
|
|
1250
|
+
this.SHOULD_BE_A_NEWLINE();
|
|
1251
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1252
|
+
const group = {
|
|
1253
|
+
location: this.#locFrom(posStart),
|
|
1254
|
+
type: NodeType.Group,
|
|
1255
|
+
content: []
|
|
1256
|
+
};
|
|
1257
|
+
this.emit.startBlock(group);
|
|
1258
|
+
while (!this.scanner.isEOF()) {
|
|
1259
|
+
if (this.scanner.accept(GROUP_END)) {
|
|
1260
|
+
this.emit.endBlock();
|
|
1261
|
+
if (!this.scanner.isEOF()) {
|
|
1262
|
+
this.SHOULD_BE_A_NEWLINE();
|
|
1263
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1264
|
+
}
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1267
|
+
this.BLOCK_ENTITY();
|
|
1268
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1269
|
+
}
|
|
1270
|
+
this.emit.message(new ExpectedMessage(this.#loc(), GROUP_END));
|
|
1271
|
+
} else this.PARAGRAPH();
|
|
1272
|
+
}
|
|
1273
|
+
#trimNode(node) {
|
|
1274
|
+
if (node.content.length == 0) return;
|
|
1275
|
+
let first = node.content[0];
|
|
1276
|
+
let last = node.content.at(-1);
|
|
1277
|
+
if (first.type == NodeType.Text) first.content = first.content.trimStart();
|
|
1278
|
+
if (last.type == NodeType.Text) last.content = last.content.trimEnd();
|
|
1279
|
+
}
|
|
1280
|
+
PARAGRAPH() {
|
|
1281
|
+
assert(!this.scanner.isEOF());
|
|
1282
|
+
const node = {
|
|
1283
|
+
type: NodeType.Paragraph,
|
|
1284
|
+
location: this.#loc(),
|
|
1285
|
+
content: []
|
|
1286
|
+
};
|
|
1287
|
+
this.emit.startInline(node);
|
|
1288
|
+
while (!this.scanner.isEOF() && this.INLINE_ENTITY());
|
|
1289
|
+
this.emit.endInline();
|
|
1290
|
+
const last = node.content.at(-1);
|
|
1291
|
+
node.location.actualEnd = last?.location.actualEnd ?? last?.location.end;
|
|
1292
|
+
this.#trimNode(node);
|
|
1293
|
+
}
|
|
1294
|
+
SHORTHAND(type, d) {
|
|
1295
|
+
const posStart = this.scanner.position();
|
|
1296
|
+
let args = [];
|
|
1297
|
+
for (const part of d.parts) {
|
|
1298
|
+
let [arg, ok] = this.ARGUMENT_CONTENT(part, ["\n\n"]);
|
|
1299
|
+
if (!ok) {
|
|
1300
|
+
this.emit.message(new ExpectedMessage(this.#loc(), part));
|
|
1301
|
+
return false;
|
|
1302
|
+
}
|
|
1303
|
+
args.push(arg);
|
|
1304
|
+
}
|
|
1305
|
+
const headEnd = this.scanner.position();
|
|
1306
|
+
const node = {
|
|
1307
|
+
type,
|
|
1308
|
+
mod: d.mod,
|
|
1309
|
+
head: this.#locFrom(posStart - d.name.length, headEnd),
|
|
1310
|
+
location: this.#locFrom(posStart - d.name.length, headEnd),
|
|
1311
|
+
arguments: {
|
|
1312
|
+
positional: args,
|
|
1313
|
+
named: /* @__PURE__ */ new Map(),
|
|
1314
|
+
location: this.#locFrom(posStart, headEnd)
|
|
1315
|
+
},
|
|
1316
|
+
content: [],
|
|
1317
|
+
expansion: void 0
|
|
1318
|
+
};
|
|
1319
|
+
const isMarker = node.mod.slotType == ModifierSlotType.None;
|
|
1320
|
+
return this.MODIFIER_BODY(type, node, d.postfix, isMarker);
|
|
1321
|
+
}
|
|
1322
|
+
MODIFIER_BODY(type, node, postfix, isMarker) {
|
|
1323
|
+
this.#expandArguments(node);
|
|
1324
|
+
const immediate = this.delayDepth == 0;
|
|
1325
|
+
if (node.mod.beforeParseContent) this.emit.message(...node.mod.beforeParseContent(node, this.cxt, immediate));
|
|
1326
|
+
if (node.mod.delayContentExpansion) this.delayDepth++;
|
|
1327
|
+
let ok = true;
|
|
1328
|
+
if (isMarker) {
|
|
1329
|
+
if (!this.scanner.isEOF() && type == NodeType.BlockModifier) {
|
|
1330
|
+
this.SHOULD_BE_A_NEWLINE();
|
|
1331
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1332
|
+
}
|
|
1333
|
+
if (type === NodeType.InlineModifier) this.emit.addInlineNode(node);
|
|
1334
|
+
else this.emit.addBlockNode(node);
|
|
1335
|
+
} else if (type == NodeType.InlineModifier) {
|
|
1336
|
+
node = node;
|
|
1337
|
+
this.emit.startInline(node);
|
|
1338
|
+
const pre = node.mod.slotType == ModifierSlotType.Preformatted;
|
|
1339
|
+
const entity = pre ? this.PREFORMATTED_INLINE_ENTITY.bind(this) : this.INLINE_ENTITY.bind(this);
|
|
1340
|
+
while (true) {
|
|
1341
|
+
if (postfix && this.scanner.accept(postfix)) break;
|
|
1342
|
+
if (this.scanner.isEOF() || !(ok = entity())) {
|
|
1343
|
+
if (postfix) this.emit.message(new ExpectedMessage(this.#loc(), postfix));
|
|
1344
|
+
break;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
this.emit.endInline();
|
|
1348
|
+
if (!pre && node.content.length > 0) this.#trimNode(node);
|
|
1349
|
+
} else {
|
|
1350
|
+
this.emit.startBlock(node);
|
|
1351
|
+
this.WARN_IF_MORE_NEWLINES_THAN(1);
|
|
1352
|
+
if (!this.scanner.isEOF()) if (node.mod.slotType == ModifierSlotType.Preformatted) this.PRE_PARAGRAPH();
|
|
1353
|
+
else this.BLOCK_ENTITY();
|
|
1354
|
+
this.emit.endBlock();
|
|
1355
|
+
}
|
|
1356
|
+
const last = node.content.at(-1);
|
|
1357
|
+
node.location.actualEnd = last?.location.actualEnd ?? last?.location.end;
|
|
1358
|
+
if (node.mod.delayContentExpansion) this.delayDepth--;
|
|
1359
|
+
if (node.mod.afterParseContent) this.emit.message(...node.mod.afterParseContent(node, this.cxt, immediate));
|
|
1360
|
+
this.#expand(node);
|
|
1361
|
+
return ok;
|
|
1362
|
+
}
|
|
1363
|
+
INLINE_ENTITY() {
|
|
1364
|
+
assert(!this.scanner.isEOF());
|
|
1365
|
+
if (this.scanner.peek(MODIFIER_INLINE_OPEN)) return this.MODIFIER(NodeType.InlineModifier);
|
|
1366
|
+
if (this.scanner.peek(MODIFIER_SYSTEM_OPEN)) return false;
|
|
1367
|
+
if (this.scanner.peek(MODIFIER_BLOCK_OPEN)) {
|
|
1368
|
+
this.SHOULD_BE_A_NEWLINE();
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
const short = this.cxt.config.inlineShorthands.find((x) => this.scanner.accept(x.name));
|
|
1372
|
+
if (short) return this.SHORTHAND(NodeType.InlineModifier, short);
|
|
1373
|
+
if (this.scanner.accept(ESCAPE_CHAR)) {
|
|
1374
|
+
if (this.scanner.isEOF()) {
|
|
1375
|
+
this.emit.addString(ESCAPE_CHAR);
|
|
1376
|
+
return true;
|
|
1377
|
+
}
|
|
1378
|
+
const start = this.scanner.position();
|
|
1379
|
+
const node = {
|
|
1380
|
+
type: NodeType.Escaped,
|
|
1381
|
+
content: this.scanner.acceptChar(),
|
|
1382
|
+
location: this.#locFrom(start - 1)
|
|
1383
|
+
};
|
|
1384
|
+
this.emit.addInlineNode(node);
|
|
1385
|
+
return true;
|
|
1386
|
+
}
|
|
1387
|
+
if (this.cxt.config.kernel.collapseWhitespaces && this.scanner.acceptWhitespaceChar() !== null) {
|
|
1388
|
+
this.WHITESPACES();
|
|
1389
|
+
this.emit.addString(" ");
|
|
1390
|
+
return true;
|
|
1391
|
+
}
|
|
1392
|
+
return this.PREFORMATTED_INLINE_ENTITY();
|
|
1393
|
+
}
|
|
1394
|
+
PREFORMATTED_INLINE_ENTITY() {
|
|
1395
|
+
assert(!this.scanner.isEOF());
|
|
1396
|
+
if (this.scanner.accept("\n")) {
|
|
1397
|
+
this.WHITESPACES();
|
|
1398
|
+
if (this.scanner.peek(MODIFIER_BLOCK_OPEN) || this.scanner.peek(MODIFIER_SYSTEM_OPEN) || this.cxt.config.blockShorthands.find((x) => this.scanner.peek(x.name)) || this.scanner.peek(GROUP_END) || this.scanner.isEOF()) return false;
|
|
1399
|
+
if (this.scanner.accept("\n")) {
|
|
1400
|
+
this.WARN_IF_MORE_NEWLINES_THAN(0);
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
this.emit.addString("\n");
|
|
1404
|
+
return true;
|
|
1405
|
+
}
|
|
1406
|
+
this.emit.addString(this.scanner.acceptChar());
|
|
1407
|
+
return true;
|
|
1408
|
+
}
|
|
1409
|
+
ARGUMENT_CONTENT(end = void 0, close = [MODIFIER_END_SIGN, MODIFIER_CLOSE_SIGN]) {
|
|
1410
|
+
let ok = true;
|
|
1411
|
+
const content = [];
|
|
1412
|
+
const posStart = this.scanner.position();
|
|
1413
|
+
let posEnd = this.scanner.position();
|
|
1414
|
+
const emitString = (s) => {
|
|
1415
|
+
const last = content.at(-1);
|
|
1416
|
+
if (last?.type == NodeType.Text) {
|
|
1417
|
+
last.content += s;
|
|
1418
|
+
last.location.end += s.length;
|
|
1419
|
+
} else {
|
|
1420
|
+
const end$1 = this.scanner.position();
|
|
1421
|
+
content.push({
|
|
1422
|
+
type: NodeType.Text,
|
|
1423
|
+
location: this.#locFrom(end$1 - s.length),
|
|
1424
|
+
content: s
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
while (true) {
|
|
1429
|
+
if (end && this.scanner.accept(end)) break;
|
|
1430
|
+
if (end === void 0 && this.scanner.accept(MODIFIER_ARGUMENT_SEPARATOR)) break;
|
|
1431
|
+
if (close.find((x) => this.scanner.peek(x)) || this.scanner.isEOF()) {
|
|
1432
|
+
ok = false;
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
if (this.scanner.accept(ESCAPE_CHAR)) {
|
|
1436
|
+
posEnd = this.scanner.position();
|
|
1437
|
+
if (this.scanner.isEOF()) {
|
|
1438
|
+
emitString(ESCAPE_CHAR);
|
|
1439
|
+
ok = false;
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
content.push({
|
|
1443
|
+
type: NodeType.Escaped,
|
|
1444
|
+
content: this.scanner.acceptChar(),
|
|
1445
|
+
location: this.#locFrom(posEnd - 1)
|
|
1446
|
+
});
|
|
1447
|
+
continue;
|
|
1448
|
+
}
|
|
1449
|
+
const beforeInterp = this.scanner.position();
|
|
1450
|
+
const result = this.cxt.config.argumentInterpolators.find((x) => this.scanner.accept(x.name));
|
|
1451
|
+
if (result !== void 0) {
|
|
1452
|
+
const [inner, ok2] = this.ARGUMENT_CONTENT(result.postfix);
|
|
1453
|
+
posEnd = this.scanner.position();
|
|
1454
|
+
content.push({
|
|
1455
|
+
type: NodeType.Interpolation,
|
|
1456
|
+
definition: result,
|
|
1457
|
+
argument: inner,
|
|
1458
|
+
location: this.#locFrom(beforeInterp)
|
|
1459
|
+
});
|
|
1460
|
+
if (!ok2) {
|
|
1461
|
+
this.emit.message(new ExpectedMessage(this.#loc(), result.postfix));
|
|
1462
|
+
ok = false;
|
|
1463
|
+
break;
|
|
1464
|
+
}
|
|
1465
|
+
} else {
|
|
1466
|
+
emitString(this.scanner.acceptChar());
|
|
1467
|
+
posEnd = this.scanner.position();
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
return [{
|
|
1471
|
+
location: this.#locFrom(posStart, posEnd),
|
|
1472
|
+
content
|
|
1473
|
+
}, ok];
|
|
1474
|
+
}
|
|
1475
|
+
POSSIBLY_NAMED_ARGUMENT(args) {
|
|
1476
|
+
let ok = true;
|
|
1477
|
+
const close = [MODIFIER_END_SIGN, MODIFIER_CLOSE_SIGN];
|
|
1478
|
+
let content = [];
|
|
1479
|
+
const posStart = this.scanner.position();
|
|
1480
|
+
let contentStart = posStart;
|
|
1481
|
+
let posEnd = this.scanner.position();
|
|
1482
|
+
let name = {
|
|
1483
|
+
type: "possible",
|
|
1484
|
+
value: ""
|
|
1485
|
+
};
|
|
1486
|
+
const emitString = (s) => {
|
|
1487
|
+
const last = content.at(-1);
|
|
1488
|
+
if (last?.type == NodeType.Text) {
|
|
1489
|
+
last.content += s;
|
|
1490
|
+
last.location.end += s.length;
|
|
1491
|
+
} else {
|
|
1492
|
+
const end = this.scanner.position();
|
|
1493
|
+
content.push({
|
|
1494
|
+
type: NodeType.Text,
|
|
1495
|
+
location: this.#locFrom(end - s.length),
|
|
1496
|
+
content: s
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
while (true) {
|
|
1501
|
+
if (this.scanner.accept(MODIFIER_ARGUMENT_SEPARATOR)) break;
|
|
1502
|
+
if (close.find((x) => this.scanner.peek(x)) || this.scanner.isEOF()) {
|
|
1503
|
+
ok = false;
|
|
1504
|
+
break;
|
|
1505
|
+
}
|
|
1506
|
+
if (this.scanner.accept(ESCAPE_CHAR)) {
|
|
1507
|
+
if (name?.type == "possible") name = void 0;
|
|
1508
|
+
posEnd = this.scanner.position();
|
|
1509
|
+
if (this.scanner.isEOF()) {
|
|
1510
|
+
emitString(ESCAPE_CHAR);
|
|
1511
|
+
ok = false;
|
|
1512
|
+
break;
|
|
1513
|
+
}
|
|
1514
|
+
content.push({
|
|
1515
|
+
type: NodeType.Escaped,
|
|
1516
|
+
content: this.scanner.acceptChar(),
|
|
1517
|
+
location: this.#locFrom(posEnd - 1)
|
|
1518
|
+
});
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
const beforeInterp = this.scanner.position();
|
|
1522
|
+
const result = this.cxt.config.argumentInterpolators.find((x) => this.scanner.accept(x.name));
|
|
1523
|
+
if (result !== void 0) {
|
|
1524
|
+
if (name?.type == "possible") name = void 0;
|
|
1525
|
+
const [inner, ok2] = this.ARGUMENT_CONTENT(result.postfix);
|
|
1526
|
+
posEnd = this.scanner.position();
|
|
1527
|
+
content.push({
|
|
1528
|
+
type: NodeType.Interpolation,
|
|
1529
|
+
definition: result,
|
|
1530
|
+
argument: inner,
|
|
1531
|
+
location: this.#locFrom(beforeInterp)
|
|
1532
|
+
});
|
|
1533
|
+
if (!ok2) {
|
|
1534
|
+
this.emit.message(new ExpectedMessage(this.#loc(), result.postfix));
|
|
1535
|
+
ok = false;
|
|
1536
|
+
break;
|
|
1537
|
+
}
|
|
1538
|
+
} else {
|
|
1539
|
+
const char = this.scanner.acceptChar();
|
|
1540
|
+
posEnd = this.scanner.position();
|
|
1541
|
+
if (name?.type == "possible") {
|
|
1542
|
+
if (char == "=") {
|
|
1543
|
+
name.type = "ok";
|
|
1544
|
+
content = [];
|
|
1545
|
+
contentStart = posEnd;
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1548
|
+
if (/[:/\[\s]/.test(char)) name = void 0;
|
|
1549
|
+
else name.value += char;
|
|
1550
|
+
}
|
|
1551
|
+
emitString(char);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
const arg = {
|
|
1555
|
+
location: this.#locFrom(contentStart, posEnd),
|
|
1556
|
+
content
|
|
1557
|
+
};
|
|
1558
|
+
let msgs;
|
|
1559
|
+
if (name?.type == "ok") {
|
|
1560
|
+
if (args.named.has(name.value)) msgs = [new DuplicateNamedArgumentMessage(this.#locFrom(posStart, contentStart - 1), name.value)];
|
|
1561
|
+
args.named.set(name.value, arg);
|
|
1562
|
+
} else args.positional.push(arg);
|
|
1563
|
+
return [msgs, ok];
|
|
1564
|
+
}
|
|
1565
|
+
ARGUMENTS() {
|
|
1566
|
+
if (!this.scanner.accept(MODIFIER_ARGUMENT_SEPARATOR)) this.WHITESPACES_OR_NEWLINES();
|
|
1567
|
+
const args = {
|
|
1568
|
+
positional: [],
|
|
1569
|
+
named: /* @__PURE__ */ new Map(),
|
|
1570
|
+
location: this.#loc()
|
|
1571
|
+
};
|
|
1572
|
+
if (this.scanner.peek(MODIFIER_CLOSE_SIGN) || this.scanner.peek(MODIFIER_END_SIGN)) return args;
|
|
1573
|
+
while (true) {
|
|
1574
|
+
const [msgs, ok] = this.POSSIBLY_NAMED_ARGUMENT(args);
|
|
1575
|
+
if (msgs) this.emit.message(...msgs);
|
|
1576
|
+
if (!ok) break;
|
|
1577
|
+
}
|
|
1578
|
+
args.location.end = this.scanner.position();
|
|
1579
|
+
return args;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1583
|
+
//#endregion
|
|
1584
|
+
//#region src/renderer.ts
|
|
1585
|
+
var RenderContext = class {
|
|
1586
|
+
renderEntity(node) {
|
|
1587
|
+
switch (node.type) {
|
|
1588
|
+
case NodeType.Group: return node.content.flatMap((x) => this.renderEntity(x));
|
|
1589
|
+
case NodeType.Paragraph:
|
|
1590
|
+
if (!this.config.paragraphRenderer) return [];
|
|
1591
|
+
return this.config.paragraphRenderer(node, this);
|
|
1592
|
+
case NodeType.Preformatted:
|
|
1593
|
+
case NodeType.Text:
|
|
1594
|
+
case NodeType.Escaped:
|
|
1595
|
+
if (!this.config.textRenderer) return [];
|
|
1596
|
+
return this.config.textRenderer(node, this);
|
|
1597
|
+
case NodeType.InlineModifier:
|
|
1598
|
+
let ir = this.config.inlineRenderers.get(node.mod);
|
|
1599
|
+
if (ir) return ir(node, this);
|
|
1600
|
+
if (!this.config.undefinedInlineRenderer) return [];
|
|
1601
|
+
return this.config.undefinedInlineRenderer(node, this);
|
|
1602
|
+
case NodeType.BlockModifier:
|
|
1603
|
+
let br = this.config.blockRenderers.get(node.mod);
|
|
1604
|
+
if (br) return br(node, this);
|
|
1605
|
+
if (!this.config.undefinedBlockRenderer) return [];
|
|
1606
|
+
return this.config.undefinedBlockRenderer(node, this);
|
|
1607
|
+
case NodeType.SystemModifier: return [];
|
|
1608
|
+
default: return debug.never(node);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
constructor(config$1, parsedDocument, state) {
|
|
1612
|
+
this.config = config$1;
|
|
1613
|
+
this.parsedDocument = parsedDocument;
|
|
1614
|
+
this.state = state;
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
var RenderConfiguration = class RenderConfiguration {
|
|
1618
|
+
paragraphRenderer;
|
|
1619
|
+
textRenderer;
|
|
1620
|
+
undefinedBlockRenderer;
|
|
1621
|
+
undefinedInlineRenderer;
|
|
1622
|
+
blockRenderers = /* @__PURE__ */ new Map();
|
|
1623
|
+
inlineRenderers = /* @__PURE__ */ new Map();
|
|
1624
|
+
constructor(options, postprocessor) {
|
|
1625
|
+
this.options = options;
|
|
1626
|
+
this.postprocessor = postprocessor;
|
|
1627
|
+
}
|
|
1628
|
+
render(doc, state) {
|
|
1629
|
+
let cxt = new RenderContext(this, doc, state);
|
|
1630
|
+
let results = doc.toStripped().root.content.flatMap((x) => cxt.renderEntity(x));
|
|
1631
|
+
return this.postprocessor(results, cxt);
|
|
1632
|
+
}
|
|
1633
|
+
addBlockRenderer(...rs) {
|
|
1634
|
+
rs.forEach(([x, y]) => this.blockRenderers.set(x, y));
|
|
1635
|
+
}
|
|
1636
|
+
addInlineRenderer(...rs) {
|
|
1637
|
+
rs.forEach(([x, y]) => this.inlineRenderers.set(x, y));
|
|
1638
|
+
}
|
|
1639
|
+
static from(from) {
|
|
1640
|
+
let config$1 = new RenderConfiguration(from.options, from.postprocessor);
|
|
1641
|
+
config$1.paragraphRenderer = from.paragraphRenderer;
|
|
1642
|
+
config$1.textRenderer = from.textRenderer;
|
|
1643
|
+
config$1.undefinedBlockRenderer = from.undefinedBlockRenderer;
|
|
1644
|
+
config$1.undefinedInlineRenderer = from.undefinedInlineRenderer;
|
|
1645
|
+
config$1.inlineRenderers = new Map(from.inlineRenderers);
|
|
1646
|
+
config$1.blockRenderers = new Map(from.blockRenderers);
|
|
1647
|
+
return config$1;
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
|
|
1651
|
+
//#endregion
|
|
1652
|
+
//#region src/modifier-helper.ts
|
|
1653
|
+
var modifier_helper_exports = /* @__PURE__ */ __export({
|
|
1654
|
+
bindArgs: () => bindArgs,
|
|
1655
|
+
createParagraphWrapper: () => createParagraphWrapper,
|
|
1656
|
+
createPlaintextWrapper: () => createPlaintextWrapper,
|
|
1657
|
+
onlyPermitPlaintextParagraph: () => onlyPermitPlaintextParagraph,
|
|
1658
|
+
onlyPermitSimpleParagraphs: () => onlyPermitSimpleParagraphs,
|
|
1659
|
+
onlyPermitSingleBlock: () => onlyPermitSingleBlock
|
|
1660
|
+
});
|
|
1661
|
+
function bindArgs(node, p, opts) {
|
|
1662
|
+
const badpos = node.arguments.positional.filter((x) => x.expansion === void 0);
|
|
1663
|
+
const badnamed = [...node.arguments.named].filter((x) => x[1].expansion === void 0);
|
|
1664
|
+
const bad = [...badpos, ...badnamed.map((x) => x[1])];
|
|
1665
|
+
if (bad.length > 0) return {
|
|
1666
|
+
msgs: bad.map((x) => new CannotExpandArgumentMessage(x.location)),
|
|
1667
|
+
args: void 0,
|
|
1668
|
+
nodes: void 0,
|
|
1669
|
+
rest: void 0,
|
|
1670
|
+
restNodes: void 0
|
|
1671
|
+
};
|
|
1672
|
+
const maxLength = opts?.rest ? Infinity : p.length + (opts?.optional?.length ?? 0);
|
|
1673
|
+
if (node.arguments.positional.length < p.length || node.arguments.positional.length > maxLength) return {
|
|
1674
|
+
msgs: [new ArgumentCountMismatchMessage({
|
|
1675
|
+
source: node.location.source,
|
|
1676
|
+
start: node.head.start,
|
|
1677
|
+
end: node.head.end
|
|
1678
|
+
}, p.length, maxLength)],
|
|
1679
|
+
args: void 0,
|
|
1680
|
+
nodes: void 0,
|
|
1681
|
+
rest: void 0,
|
|
1682
|
+
restNodes: void 0
|
|
1683
|
+
};
|
|
1684
|
+
const args = {};
|
|
1685
|
+
const nodes = {};
|
|
1686
|
+
const msgs = [];
|
|
1687
|
+
p.forEach((name, i) => {
|
|
1688
|
+
nodes[name] = node.arguments.positional[i];
|
|
1689
|
+
args[name] = nodes[name].expansion;
|
|
1690
|
+
if (opts?.trim) args[name] = args[name].trim();
|
|
1691
|
+
});
|
|
1692
|
+
if (opts?.optional) opts.optional.forEach((name, i) => {
|
|
1693
|
+
nodes[name] = node.arguments.positional[p.length + i];
|
|
1694
|
+
args[name] = nodes[name]?.expansion;
|
|
1695
|
+
if (opts?.trim && args[name]) args[name] = args[name].trim();
|
|
1696
|
+
});
|
|
1697
|
+
if (opts?.named) Object.entries(opts.named).forEach(([name, def]) => {
|
|
1698
|
+
nodes[name] = node.arguments.named.get(name);
|
|
1699
|
+
args[name] = node.arguments.named.get(name)?.expansion ?? def;
|
|
1700
|
+
if (opts?.trim && args[name]) args[name] = args[name].trim();
|
|
1701
|
+
});
|
|
1702
|
+
if (!opts?.restNamed) node.arguments.named.forEach((v, k) => {
|
|
1703
|
+
if (!opts?.named || !Object.hasOwn(opts.named, k)) msgs.push(new InvalidArgumentMessage(v.location, `no such named argument: "${k}"`));
|
|
1704
|
+
});
|
|
1705
|
+
if (msgs.length) return {
|
|
1706
|
+
msgs,
|
|
1707
|
+
args: void 0,
|
|
1708
|
+
nodes: void 0,
|
|
1709
|
+
rest: void 0,
|
|
1710
|
+
restNodes: void 0
|
|
1711
|
+
};
|
|
1712
|
+
const restNodes = node.arguments.positional.slice(p.length + (opts?.optional?.length ?? 0));
|
|
1713
|
+
return {
|
|
1714
|
+
msgs: null,
|
|
1715
|
+
args,
|
|
1716
|
+
nodes,
|
|
1717
|
+
rest: restNodes.map((x) => opts?.trim ? x.expansion.trim() : x.expansion),
|
|
1718
|
+
restNodes
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Helper function to ensure that a modifier only accepts plaintext paragraphs as content.
|
|
1723
|
+
* @returns The content as a string if OK, otherwise an array of error messages.
|
|
1724
|
+
*/
|
|
1725
|
+
function onlyPermitPlaintextParagraph(node) {
|
|
1726
|
+
function checkInline(ents) {
|
|
1727
|
+
let result = "";
|
|
1728
|
+
for (const ent of ents) switch (ent.type) {
|
|
1729
|
+
case NodeType.Text:
|
|
1730
|
+
case NodeType.Escaped:
|
|
1731
|
+
result += ent.content;
|
|
1732
|
+
break;
|
|
1733
|
+
case NodeType.SystemModifier: break;
|
|
1734
|
+
case NodeType.InlineModifier:
|
|
1735
|
+
if (!ent.expansion) return [new EntityNotAllowedMessage(ent.location, "it does not expand to plain text")];
|
|
1736
|
+
let checkInner = checkInline(ent.expansion);
|
|
1737
|
+
if (Array.isArray(checkInner)) return checkInner;
|
|
1738
|
+
result += checkInner;
|
|
1739
|
+
break;
|
|
1740
|
+
default: return debug.never(ent);
|
|
1741
|
+
}
|
|
1742
|
+
return result;
|
|
1743
|
+
}
|
|
1744
|
+
function checkContent(ents) {
|
|
1745
|
+
if (ents.length == 0) return "";
|
|
1746
|
+
else if (ents.length > 1) {
|
|
1747
|
+
let last = ents.at(-1).location;
|
|
1748
|
+
return [new MultipleBlocksNotPermittedMessage({
|
|
1749
|
+
source: last.source,
|
|
1750
|
+
start: ents[1].location.start,
|
|
1751
|
+
end: last.actualEnd ?? last.end
|
|
1752
|
+
})];
|
|
1753
|
+
}
|
|
1754
|
+
return check(ents[0]);
|
|
1755
|
+
}
|
|
1756
|
+
function check(ent) {
|
|
1757
|
+
if (ent.type == NodeType.BlockModifier) {
|
|
1758
|
+
if (!ent.expansion) return [new EntityNotAllowedMessage(ent.location, "it does not expand to plain text")];
|
|
1759
|
+
return checkContent(ent.expansion);
|
|
1760
|
+
} else if (ent.type == NodeType.Preformatted) return ent.content.text;
|
|
1761
|
+
else if (ent.type !== NodeType.Paragraph) return [new OnlySimpleParagraphsPermittedMessage(ent.location)];
|
|
1762
|
+
return checkInline(ent.content);
|
|
1763
|
+
}
|
|
1764
|
+
return checkContent(node.content);
|
|
1765
|
+
}
|
|
1766
|
+
/**
|
|
1767
|
+
* Helper function to ensure that a modifier does not accept any block modifiers inside its content.
|
|
1768
|
+
* @returns `null` if OK, otherwise an array of error messages.
|
|
1769
|
+
*/
|
|
1770
|
+
function onlyPermitSimpleParagraphs(node) {
|
|
1771
|
+
function check(nodes) {
|
|
1772
|
+
for (const ent of nodes) if (ent.type == NodeType.BlockModifier && ent.expansion !== void 0) {
|
|
1773
|
+
const cs = check(ent.expansion);
|
|
1774
|
+
if (cs) return cs;
|
|
1775
|
+
} else if (ent.type == NodeType.Group) {
|
|
1776
|
+
const cs = check(ent.content);
|
|
1777
|
+
if (cs) return cs;
|
|
1778
|
+
} else if (ent.type !== NodeType.Paragraph) return [new OnlySimpleParagraphsPermittedMessage(ent.location)];
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
return check(node.expansion ?? node.content);
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Helper function to ensure that a modifier only accepts one block as its content.
|
|
1785
|
+
* @returns `null` if OK, otherwise an array of error messages.
|
|
1786
|
+
*/
|
|
1787
|
+
function onlyPermitSingleBlock(node, opt) {
|
|
1788
|
+
function check(nodes) {
|
|
1789
|
+
if (nodes.length > 1) {
|
|
1790
|
+
const last = nodes.at(-1).location;
|
|
1791
|
+
return [new MultipleBlocksNotPermittedMessage({
|
|
1792
|
+
source: last.source,
|
|
1793
|
+
start: nodes[1].location.start,
|
|
1794
|
+
end: last.actualEnd ?? last.end
|
|
1795
|
+
})];
|
|
1796
|
+
} else if (nodes.length == 1 && nodes[0].type === NodeType.BlockModifier && nodes[0].expansion !== void 0) return check(nodes[0].expansion);
|
|
1797
|
+
else if (nodes.length == 0 && !opt?.optional) return [new ContentExpectedMessage(node.location)];
|
|
1798
|
+
return null;
|
|
1799
|
+
}
|
|
1800
|
+
return check(node.expansion ?? node.content);
|
|
1801
|
+
}
|
|
1802
|
+
function createPlaintextWrapper(name, get, set, slotType = ModifierSlotType.Normal) {
|
|
1803
|
+
return new SystemModifierDefinition(name, slotType, {
|
|
1804
|
+
delayContentExpansion: true,
|
|
1805
|
+
beforeProcessExpansion(node, cxt) {
|
|
1806
|
+
let { msgs } = bindArgs(node, []);
|
|
1807
|
+
if (msgs) return msgs;
|
|
1808
|
+
const result = onlyPermitPlaintextParagraph(node);
|
|
1809
|
+
if (typeof result !== "string") return result;
|
|
1810
|
+
const previous = get(cxt);
|
|
1811
|
+
if (previous !== void 0) msgs = [new OverwriteSpecialVariableMessage(node.head, name, previous)];
|
|
1812
|
+
set(cxt, result);
|
|
1813
|
+
return msgs ?? [];
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
function createParagraphWrapper(name, get, set, slotType = ModifierSlotType.Normal) {
|
|
1818
|
+
return new SystemModifierDefinition(name, slotType, { beforeProcessExpansion(node, cxt) {
|
|
1819
|
+
let { msgs } = bindArgs(node, []);
|
|
1820
|
+
if (msgs) return msgs;
|
|
1821
|
+
msgs = onlyPermitSingleBlock(node);
|
|
1822
|
+
if (msgs) return msgs;
|
|
1823
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
1824
|
+
if (msgs) return msgs;
|
|
1825
|
+
if (get(cxt) !== void 0) msgs = [new OverwriteSpecialVariableMessage(node.head, name, "<block>")];
|
|
1826
|
+
const stripped = stripNode(cloneNode(node.content[0]))[0];
|
|
1827
|
+
set(cxt, stripped);
|
|
1828
|
+
debug.info(name, "->", debugPrint.node(stripped));
|
|
1829
|
+
return msgs ?? [];
|
|
1830
|
+
} });
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
//#endregion
|
|
1834
|
+
//#region src/builtin/internal.ts
|
|
1835
|
+
const builtins = Symbol();
|
|
1836
|
+
function initParseContext(cxt) {
|
|
1837
|
+
cxt.init(builtins, {
|
|
1838
|
+
blockSlotDelayedStack: [],
|
|
1839
|
+
inlineSlotDelayedStack: [],
|
|
1840
|
+
blockInstantiationData: [],
|
|
1841
|
+
inlineInstantiationData: [],
|
|
1842
|
+
insideModule: void 0
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
function customModifier(type, name, signature, content) {
|
|
1846
|
+
debug.info(`created custom ${NodeType[type]}:`, name);
|
|
1847
|
+
debug.info("args:", signature.args, "named:", signature.namedArgs, `with ${signature.slotName === void 0 ? "no slot" : signature.slotName == "" ? "empty slot name" : "slot name: " + signature.slotName}`);
|
|
1848
|
+
debug.trace(() => "content is\n" + debugPrint.node(...content));
|
|
1849
|
+
const flag = signature.slotName === void 0 ? ModifierSlotType.None : signature.preformatted ? ModifierSlotType.Preformatted : ModifierSlotType.Normal;
|
|
1850
|
+
const mod = type == NodeType.BlockModifier ? new BlockModifierDefinition(name, flag) : new InlineModifierDefinition(name, flag);
|
|
1851
|
+
const isInline = type == NodeType.InlineModifier;
|
|
1852
|
+
if (content.length == 1 && (content[0].type == NodeType.BlockModifier || content[0].type == NodeType.InlineModifier)) mod.roleHint = content[0].mod.roleHint;
|
|
1853
|
+
mod.delayContentExpansion = true;
|
|
1854
|
+
mod.prepareExpand = (node) => {
|
|
1855
|
+
let { msgs, args } = bindArgs(node, signature.args, { named: signature.namedArgs });
|
|
1856
|
+
if (msgs) return msgs;
|
|
1857
|
+
node.state = {
|
|
1858
|
+
ok: true,
|
|
1859
|
+
args: new Map(Object.entries(args))
|
|
1860
|
+
};
|
|
1861
|
+
return [];
|
|
1862
|
+
};
|
|
1863
|
+
mod.expand = (node) => {
|
|
1864
|
+
if (!node.state?.ok) return [];
|
|
1865
|
+
return cloneNodes(content, { newLocation: node.location });
|
|
1866
|
+
};
|
|
1867
|
+
mod.beforeProcessExpansion = (node, cxt) => {
|
|
1868
|
+
if (!node.state?.ok) return [];
|
|
1869
|
+
const store = cxt.get(builtins);
|
|
1870
|
+
(isInline ? store.inlineInstantiationData : store.blockInstantiationData).push({
|
|
1871
|
+
slotName: signature.slotName,
|
|
1872
|
+
mod,
|
|
1873
|
+
args: node.state.args,
|
|
1874
|
+
slotContent: node.content
|
|
1875
|
+
});
|
|
1876
|
+
debug.trace(`pushed ${NodeType[type]} slot data for`, name);
|
|
1877
|
+
debug.trace(`... slotName:`, signature.slotName === "" ? "<unnamed>" : signature.slotName === void 0 ? "<no slot>" : `'${signature.slotName}'`);
|
|
1878
|
+
debug.trace(`... args:`, "{" + [...node.state.args].map(([a, b]) => `${a} => ${b}`).join(", ") + "}");
|
|
1879
|
+
return [];
|
|
1880
|
+
};
|
|
1881
|
+
mod.afterProcessExpansion = (node, cxt) => {
|
|
1882
|
+
if (!node.state?.ok) return [];
|
|
1883
|
+
const store = cxt.get(builtins);
|
|
1884
|
+
(isInline ? store.inlineInstantiationData : store.blockInstantiationData).pop();
|
|
1885
|
+
debug.trace(`popped ${NodeType[type]} slot data for`, name);
|
|
1886
|
+
return [];
|
|
1887
|
+
};
|
|
1888
|
+
return mod;
|
|
1889
|
+
}
|
|
1890
|
+
function makeInlineDefinition(content, msgs) {
|
|
1891
|
+
let lastIsParagraph = false;
|
|
1892
|
+
let concat = [];
|
|
1893
|
+
for (const n of content) switch (n.type) {
|
|
1894
|
+
case NodeType.Group:
|
|
1895
|
+
concat.push(...makeInlineDefinition(n.content, msgs));
|
|
1896
|
+
break;
|
|
1897
|
+
case NodeType.Paragraph: if (!lastIsParagraph) {
|
|
1898
|
+
lastIsParagraph = true;
|
|
1899
|
+
concat.push(...n.content);
|
|
1900
|
+
continue;
|
|
1901
|
+
}
|
|
1902
|
+
case NodeType.Preformatted:
|
|
1903
|
+
case NodeType.BlockModifier:
|
|
1904
|
+
msgs.push(new EntityNotAllowedMessage(n.location));
|
|
1905
|
+
break;
|
|
1906
|
+
case NodeType.SystemModifier:
|
|
1907
|
+
lastIsParagraph = false;
|
|
1908
|
+
concat.push(n);
|
|
1909
|
+
break;
|
|
1910
|
+
default: debug.never(n);
|
|
1911
|
+
}
|
|
1912
|
+
return concat;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
//#endregion
|
|
1916
|
+
//#region src/builtin/define-modifier.ts
|
|
1917
|
+
function parseDefineArguments$1(node, stack) {
|
|
1918
|
+
let { msgs, args, nodes, rest } = bindArgs(node, ["name"], {
|
|
1919
|
+
rest: true,
|
|
1920
|
+
restNamed: true
|
|
1921
|
+
});
|
|
1922
|
+
if (msgs) return msgs;
|
|
1923
|
+
msgs = [];
|
|
1924
|
+
const nameNode = nodes.name;
|
|
1925
|
+
const name = args.name;
|
|
1926
|
+
if (name === "" || name?.includes("\n")) return [new InvalidArgumentMessage(nameNode.location, name)];
|
|
1927
|
+
let slotName = "";
|
|
1928
|
+
if (rest.length > 0) {
|
|
1929
|
+
const last = rest.at(-1);
|
|
1930
|
+
const match = /^\((.*)\)$/.exec(last);
|
|
1931
|
+
if (match) {
|
|
1932
|
+
slotName = match[1];
|
|
1933
|
+
rest.pop();
|
|
1934
|
+
} else slotName = "";
|
|
1935
|
+
}
|
|
1936
|
+
let namedArgs = Object.fromEntries([...node.arguments.named].map((x) => [x[0], x[1].expansion]));
|
|
1937
|
+
let signature = {
|
|
1938
|
+
slotName,
|
|
1939
|
+
args: rest,
|
|
1940
|
+
namedArgs,
|
|
1941
|
+
preformatted: void 0
|
|
1942
|
+
};
|
|
1943
|
+
node.state = {
|
|
1944
|
+
name,
|
|
1945
|
+
nameNode,
|
|
1946
|
+
signature,
|
|
1947
|
+
msgs
|
|
1948
|
+
};
|
|
1949
|
+
stack.push(signature);
|
|
1950
|
+
}
|
|
1951
|
+
const DefineBlockMod = new SystemModifierDefinition("define-block", ModifierSlotType.Normal, {
|
|
1952
|
+
delayContentExpansion: true,
|
|
1953
|
+
alwaysTryExpand: true,
|
|
1954
|
+
beforeParseContent(node, cxt, immediate) {
|
|
1955
|
+
const check = parseDefineArguments$1(node, cxt.get(builtins).blockSlotDelayedStack);
|
|
1956
|
+
if (check) if (immediate) return check;
|
|
1957
|
+
else {
|
|
1958
|
+
debug.trace("skipping incomplete definition");
|
|
1959
|
+
return [];
|
|
1960
|
+
}
|
|
1961
|
+
debug.trace("entering block definition:", node.state.name);
|
|
1962
|
+
return [];
|
|
1963
|
+
},
|
|
1964
|
+
afterParseContent(node, cxt) {
|
|
1965
|
+
if (!node.state) return [];
|
|
1966
|
+
assert(cxt.get(builtins).blockSlotDelayedStack.pop() === node.state.signature);
|
|
1967
|
+
debug.trace("leaving block definition", node.state.name);
|
|
1968
|
+
return [];
|
|
1969
|
+
},
|
|
1970
|
+
prepareExpand(node, cxt, immediate) {
|
|
1971
|
+
if (!immediate || !node.state) return [];
|
|
1972
|
+
const msgs = node.state.msgs;
|
|
1973
|
+
if (!node.state.name) msgs.push(new InvalidArgumentMessage(node.state.nameNode.location));
|
|
1974
|
+
else if (cxt.config.blockModifiers.has(node.state.name)) msgs.push(new NameAlreadyDefinedMessage(node.state.nameNode.location, node.state.name));
|
|
1975
|
+
return msgs;
|
|
1976
|
+
},
|
|
1977
|
+
expand(node, cxt, immediate) {
|
|
1978
|
+
if (!immediate) return void 0;
|
|
1979
|
+
if (node.state?.name) {
|
|
1980
|
+
if (cxt.config.blockModifiers.has(node.state.name)) cxt.config.blockModifiers.remove(node.state.name);
|
|
1981
|
+
cxt.config.blockModifiers.add(customModifier(NodeType.BlockModifier, node.state.name, node.state.signature, node.content));
|
|
1982
|
+
}
|
|
1983
|
+
return [];
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
const DefineInlineMod = new SystemModifierDefinition("define-inline", ModifierSlotType.Normal, {
|
|
1987
|
+
delayContentExpansion: true,
|
|
1988
|
+
alwaysTryExpand: true,
|
|
1989
|
+
beforeParseContent(node, cxt, immediate) {
|
|
1990
|
+
const check = parseDefineArguments$1(node, cxt.get(builtins).inlineSlotDelayedStack);
|
|
1991
|
+
if (check) if (immediate) return check;
|
|
1992
|
+
else {
|
|
1993
|
+
debug.trace("skipping incomplete definition");
|
|
1994
|
+
return [];
|
|
1995
|
+
}
|
|
1996
|
+
debug.trace("entering inline definition:", node.state.name);
|
|
1997
|
+
return [];
|
|
1998
|
+
},
|
|
1999
|
+
afterParseContent(node, cxt) {
|
|
2000
|
+
if (!node.state) return [];
|
|
2001
|
+
assert(cxt.get(builtins).inlineSlotDelayedStack.pop() === node.state.signature);
|
|
2002
|
+
debug.trace("leaving inline definition", node.state.name);
|
|
2003
|
+
return [];
|
|
2004
|
+
},
|
|
2005
|
+
prepareExpand(node, cxt, immediate) {
|
|
2006
|
+
if (!immediate || !node.state) return [];
|
|
2007
|
+
if (!node.state.name) return [new InvalidArgumentMessage(node.state.nameNode.location)];
|
|
2008
|
+
const msgs = node.state.msgs;
|
|
2009
|
+
if (cxt.config.inlineModifiers.has(node.state.name)) msgs.push(new NameAlreadyDefinedMessage(node.state.nameNode.location, node.state.name));
|
|
2010
|
+
node.state.definition = makeInlineDefinition(node.content, msgs);
|
|
2011
|
+
return msgs;
|
|
2012
|
+
},
|
|
2013
|
+
expand(node, cxt, immediate) {
|
|
2014
|
+
if (!immediate) return void 0;
|
|
2015
|
+
if (node.state?.name) {
|
|
2016
|
+
if (cxt.config.inlineModifiers.has(node.state.name)) cxt.config.inlineModifiers.remove(node.state.name);
|
|
2017
|
+
cxt.config.inlineModifiers.add(customModifier(NodeType.InlineModifier, node.state.name, node.state.signature, node.state.definition));
|
|
2018
|
+
}
|
|
2019
|
+
return [];
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
|
|
2023
|
+
//#endregion
|
|
2024
|
+
//#region src/builtin/define-shorthand.ts
|
|
2025
|
+
function parseDefineArguments(type, node, stack) {
|
|
2026
|
+
let { msgs, args, nodes, rest, restNodes } = bindArgs(node, ["name"], { rest: true });
|
|
2027
|
+
if (msgs) return msgs;
|
|
2028
|
+
msgs = [];
|
|
2029
|
+
const nameNode = nodes.name;
|
|
2030
|
+
const name = args.name;
|
|
2031
|
+
if (name === "" || name?.includes("\n")) return [new InvalidArgumentMessage(nameNode.location, name)];
|
|
2032
|
+
let slotName = void 0;
|
|
2033
|
+
let parts = [];
|
|
2034
|
+
let postfix = void 0;
|
|
2035
|
+
let i = 0;
|
|
2036
|
+
while (i < rest.length) {
|
|
2037
|
+
const arg = restNodes[i];
|
|
2038
|
+
const match = /^\((.*)\)$/.exec(arg.expansion);
|
|
2039
|
+
if (match) {
|
|
2040
|
+
slotName = match[1];
|
|
2041
|
+
i++;
|
|
2042
|
+
if (type == NodeType.InlineModifier) if (i < rest.length) if (rest[i] === "") msgs.push(new InvalidArgumentMessage(restNodes[i].location, "postfix"));
|
|
2043
|
+
else {
|
|
2044
|
+
postfix = rest[i];
|
|
2045
|
+
i++;
|
|
2046
|
+
}
|
|
2047
|
+
else msgs.push(new ArgumentCountMismatchMessage(node.head));
|
|
2048
|
+
break;
|
|
2049
|
+
}
|
|
2050
|
+
i++;
|
|
2051
|
+
if (i < rest.length) {
|
|
2052
|
+
const id = arg.expansion;
|
|
2053
|
+
if (id === "") return [new InvalidArgumentMessage(arg.location, "id")];
|
|
2054
|
+
const part = rest[i];
|
|
2055
|
+
if (part === "") return [new InvalidArgumentMessage(restNodes[i].location, "part")];
|
|
2056
|
+
parts.push([id, part]);
|
|
2057
|
+
i++;
|
|
2058
|
+
} else {
|
|
2059
|
+
msgs.push(new ArgumentCountMismatchMessage(node.head));
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
if (i == rest.length - 1) {
|
|
2064
|
+
if (rest[i] !== "") msgs.push(new InvalidArgumentMessage(restNodes[i].location, "(must be empty)"));
|
|
2065
|
+
} else if (i < rest.length - 1) msgs.push(new ArgumentCountMismatchMessage(node.head));
|
|
2066
|
+
let signature = {
|
|
2067
|
+
slotName,
|
|
2068
|
+
args: parts.map((x) => x[0]),
|
|
2069
|
+
namedArgs: {},
|
|
2070
|
+
preformatted: void 0
|
|
2071
|
+
};
|
|
2072
|
+
node.state = {
|
|
2073
|
+
name,
|
|
2074
|
+
nameNode,
|
|
2075
|
+
signature,
|
|
2076
|
+
parts,
|
|
2077
|
+
postfix,
|
|
2078
|
+
msgs
|
|
2079
|
+
};
|
|
2080
|
+
stack.push(signature);
|
|
2081
|
+
return [];
|
|
2082
|
+
}
|
|
2083
|
+
const DefineBlockShorthandMod = new SystemModifierDefinition("block-shorthand", ModifierSlotType.Normal, {
|
|
2084
|
+
delayContentExpansion: true,
|
|
2085
|
+
alwaysTryExpand: true,
|
|
2086
|
+
beforeParseContent(node, cxt, immediate) {
|
|
2087
|
+
if (!immediate) return [];
|
|
2088
|
+
const store = cxt.get(builtins);
|
|
2089
|
+
const check = parseDefineArguments(NodeType.BlockModifier, node, store.blockSlotDelayedStack);
|
|
2090
|
+
if (check) return check;
|
|
2091
|
+
debug.trace("entering block shorthand definition", node.state.name);
|
|
2092
|
+
return [];
|
|
2093
|
+
},
|
|
2094
|
+
afterParseContent(node, cxt) {
|
|
2095
|
+
if (!node.state) return [];
|
|
2096
|
+
assert(cxt.get(builtins).blockSlotDelayedStack.pop() === node.state.signature);
|
|
2097
|
+
debug.trace("leaving inline shorthand definition", node.state.name);
|
|
2098
|
+
return [];
|
|
2099
|
+
},
|
|
2100
|
+
prepareExpand(node, cxt, immediate) {
|
|
2101
|
+
if (!immediate || !node.state) return [];
|
|
2102
|
+
if (!node.state.name) return [new InvalidArgumentMessage(node.state.nameNode.location)];
|
|
2103
|
+
const msgs = node.state.msgs;
|
|
2104
|
+
if (cxt.config.blockShorthands.has(node.state.name)) msgs.push(new NameAlreadyDefinedMessage(node.state.nameNode.location, node.state.name));
|
|
2105
|
+
return msgs;
|
|
2106
|
+
},
|
|
2107
|
+
expand(node, cxt, immediate) {
|
|
2108
|
+
if (!immediate || !node.state) return void 0;
|
|
2109
|
+
const name = "<block shorthand>";
|
|
2110
|
+
const parts = node.state.parts.map((x) => x[1]);
|
|
2111
|
+
const mod = customModifier(NodeType.BlockModifier, name, node.state.signature, node.content);
|
|
2112
|
+
const shorthand = {
|
|
2113
|
+
name: node.state.name,
|
|
2114
|
+
postfix: node.state.postfix,
|
|
2115
|
+
mod,
|
|
2116
|
+
parts
|
|
2117
|
+
};
|
|
2118
|
+
if (cxt.config.blockShorthands.has(node.state.name)) cxt.config.blockShorthands.remove(node.state.name);
|
|
2119
|
+
cxt.config.blockShorthands.add(shorthand);
|
|
2120
|
+
debug.info(() => "created block shorthand: " + debugPrint.blockShorthand(shorthand));
|
|
2121
|
+
return [];
|
|
2122
|
+
}
|
|
2123
|
+
});
|
|
2124
|
+
const DefineInlineShorthandMod = new SystemModifierDefinition("inline-shorthand", ModifierSlotType.Normal, {
|
|
2125
|
+
delayContentExpansion: true,
|
|
2126
|
+
alwaysTryExpand: true,
|
|
2127
|
+
beforeParseContent(node, cxt, immediate) {
|
|
2128
|
+
if (!immediate) return [];
|
|
2129
|
+
const store = cxt.get(builtins);
|
|
2130
|
+
const check = parseDefineArguments(NodeType.InlineModifier, node, store.inlineSlotDelayedStack);
|
|
2131
|
+
if (check) return check;
|
|
2132
|
+
debug.trace("entering inline shorthand definition", node.state.name);
|
|
2133
|
+
return [];
|
|
2134
|
+
},
|
|
2135
|
+
afterParseContent(node, cxt) {
|
|
2136
|
+
if (!node.state) return [];
|
|
2137
|
+
assert(cxt.get(builtins).inlineSlotDelayedStack.pop() === node.state.signature);
|
|
2138
|
+
debug.trace("leaving inline shorthand definition", node.state.name);
|
|
2139
|
+
return [];
|
|
2140
|
+
},
|
|
2141
|
+
prepareExpand(node, cxt, immediate) {
|
|
2142
|
+
if (!immediate || !node.state) return [];
|
|
2143
|
+
if (!node.state.name) return [new InvalidArgumentMessage(node.state.nameNode.location)];
|
|
2144
|
+
const msgs = node.state.msgs;
|
|
2145
|
+
if (cxt.config.inlineShorthands.has(node.state.name)) msgs.push(new NameAlreadyDefinedMessage(node.state.nameNode.location, node.state.name));
|
|
2146
|
+
node.state.definition = makeInlineDefinition(node.content, msgs);
|
|
2147
|
+
return msgs;
|
|
2148
|
+
},
|
|
2149
|
+
expand(node, cxt, immediate) {
|
|
2150
|
+
if (!immediate || !node.state) return void 0;
|
|
2151
|
+
const name = "<inline shorthand>";
|
|
2152
|
+
const parts = node.state.parts.map((x) => x[1]);
|
|
2153
|
+
const mod = customModifier(NodeType.InlineModifier, name, node.state.signature, node.state.definition);
|
|
2154
|
+
const shorthand = {
|
|
2155
|
+
name: node.state.name,
|
|
2156
|
+
postfix: node.state.postfix,
|
|
2157
|
+
mod,
|
|
2158
|
+
parts
|
|
2159
|
+
};
|
|
2160
|
+
if (cxt.config.inlineShorthands.has(node.state.name)) cxt.config.inlineShorthands.remove(node.state.name);
|
|
2161
|
+
cxt.config.inlineShorthands.add(shorthand);
|
|
2162
|
+
debug.info(() => "created inline shorthand: " + debugPrint.inlineShorthand(shorthand));
|
|
2163
|
+
return [];
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
|
|
2167
|
+
//#endregion
|
|
2168
|
+
//#region src/builtin/misc.ts
|
|
2169
|
+
const RawBlockMod = new BlockModifierDefinition("raw", ModifierSlotType.Preformatted, { expand(node) {
|
|
2170
|
+
return node.content;
|
|
2171
|
+
} });
|
|
2172
|
+
const ConcatBlockMod = new BlockModifierDefinition("concat", ModifierSlotType.Normal, {
|
|
2173
|
+
prepareExpand(node) {
|
|
2174
|
+
let { msgs, nodes } = bindArgs(node, [], { named: { sep: "" } });
|
|
2175
|
+
if (msgs) return msgs;
|
|
2176
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
2177
|
+
if (msgs) return msgs;
|
|
2178
|
+
node.state = nodes?.sep;
|
|
2179
|
+
return [];
|
|
2180
|
+
},
|
|
2181
|
+
expand(node) {
|
|
2182
|
+
const result = {
|
|
2183
|
+
location: node.location,
|
|
2184
|
+
type: NodeType.Paragraph,
|
|
2185
|
+
content: []
|
|
2186
|
+
};
|
|
2187
|
+
function separator() {
|
|
2188
|
+
if (node.state?.expansion) result.content.push({
|
|
2189
|
+
type: NodeType.Text,
|
|
2190
|
+
location: node.state.location,
|
|
2191
|
+
content: node.state.expansion
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
function work(nodes) {
|
|
2195
|
+
for (const n of nodes) switch (n.type) {
|
|
2196
|
+
case NodeType.Paragraph:
|
|
2197
|
+
result.content.push(...n.content);
|
|
2198
|
+
separator();
|
|
2199
|
+
break;
|
|
2200
|
+
case NodeType.Group:
|
|
2201
|
+
work(n.content);
|
|
2202
|
+
break;
|
|
2203
|
+
case NodeType.BlockModifier:
|
|
2204
|
+
if (n.expansion) work(n.expansion);
|
|
2205
|
+
break;
|
|
2206
|
+
case NodeType.Preformatted:
|
|
2207
|
+
case NodeType.SystemModifier: break;
|
|
2208
|
+
default: debug.never(n);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
work(node.content);
|
|
2212
|
+
if (node.state?.expansion && result.content.length > 0) result.content.pop();
|
|
2213
|
+
return [result];
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
|
|
2217
|
+
//#endregion
|
|
2218
|
+
//#region src/module.ts
|
|
2219
|
+
let ModuleDefinition;
|
|
2220
|
+
(function(_ModuleDefinition) {
|
|
2221
|
+
function from(cxt) {
|
|
2222
|
+
return {
|
|
2223
|
+
usedModules: new Set(cxt.usedModules),
|
|
2224
|
+
blocks: cxt.config.blockModifiers.toSet(),
|
|
2225
|
+
inlines: cxt.config.inlineModifiers.toSet(),
|
|
2226
|
+
inlineShorthands: cxt.config.inlineShorthands.toSet(),
|
|
2227
|
+
blockShorthands: cxt.config.blockShorthands.toSet()
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
_ModuleDefinition.from = from;
|
|
2231
|
+
function apply(defs, cxt) {
|
|
2232
|
+
cxt.usedModules = new Set(defs.usedModules);
|
|
2233
|
+
cxt.config.blockModifiers = new NameManager(defs.blocks);
|
|
2234
|
+
cxt.config.inlineModifiers = new NameManager(defs.inlines);
|
|
2235
|
+
cxt.config.inlineShorthands = new NameManager(defs.inlineShorthands);
|
|
2236
|
+
cxt.config.blockShorthands = new NameManager(defs.blockShorthands);
|
|
2237
|
+
}
|
|
2238
|
+
_ModuleDefinition.apply = apply;
|
|
2239
|
+
function diff(cnew, cold) {
|
|
2240
|
+
return {
|
|
2241
|
+
usedModules: cnew.usedModules.difference(cold.usedModules),
|
|
2242
|
+
blocks: cnew.blocks.difference(cold.blocks),
|
|
2243
|
+
inlines: cnew.inlines.difference(cold.inlines),
|
|
2244
|
+
inlineShorthands: cnew.inlineShorthands.difference(cold.inlineShorthands),
|
|
2245
|
+
blockShorthands: cnew.blockShorthands.difference(cold.blockShorthands)
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
_ModuleDefinition.diff = diff;
|
|
2249
|
+
function add(snew, sold, transform) {
|
|
2250
|
+
let newNames = new Set([...snew].map((x) => x.name));
|
|
2251
|
+
let out = new Set(snew);
|
|
2252
|
+
let overlap = [];
|
|
2253
|
+
for (const x of sold) if (newNames.has(x.name)) overlap.push(x);
|
|
2254
|
+
else out.add(x);
|
|
2255
|
+
return [out, overlap.map(transform).join(", ")];
|
|
2256
|
+
}
|
|
2257
|
+
function combine(cnew, cold) {
|
|
2258
|
+
let [blocks, s1] = add(cnew.blocks, cold.blocks, debugPrint.blockModifier);
|
|
2259
|
+
let [inlines, s2] = add(cnew.inlines, cold.inlines, debugPrint.inlineModifier);
|
|
2260
|
+
let [inlineShorthands, s3] = add(cnew.inlineShorthands, cold.inlineShorthands, debugPrint.inlineShorthand);
|
|
2261
|
+
let [blockShorthands, s4] = add(cnew.blockShorthands, cold.blockShorthands, debugPrint.blockShorthand);
|
|
2262
|
+
return [{
|
|
2263
|
+
usedModules: cnew.usedModules.union(cold.usedModules),
|
|
2264
|
+
blocks,
|
|
2265
|
+
inlines,
|
|
2266
|
+
inlineShorthands,
|
|
2267
|
+
blockShorthands
|
|
2268
|
+
}, (s1 ? s1 + "; " : "") + (s2 ? s2 + "; " : "") + (s3 ? "inline shorthand " + s3 + "; " : "") + (s4 ? "block shorthand " + s4 : "")];
|
|
2269
|
+
}
|
|
2270
|
+
_ModuleDefinition.combine = combine;
|
|
2271
|
+
})(ModuleDefinition || (ModuleDefinition = {}));
|
|
2272
|
+
|
|
2273
|
+
//#endregion
|
|
2274
|
+
//#region src/builtin/module.ts
|
|
2275
|
+
const ModuleMod = new BlockModifierDefinition("module", ModifierSlotType.Normal, {
|
|
2276
|
+
expand() {
|
|
2277
|
+
return [];
|
|
2278
|
+
},
|
|
2279
|
+
beforeParseContent(node, cxt) {
|
|
2280
|
+
let { msgs, args } = bindArgs(node, ["name"]);
|
|
2281
|
+
if (msgs) return msgs;
|
|
2282
|
+
const data = cxt.get(builtins);
|
|
2283
|
+
const name = args.name;
|
|
2284
|
+
const defs = ModuleDefinition.from(cxt);
|
|
2285
|
+
if (data.insideModule !== void 0) return [new NoNestedModuleMessage(node.head)];
|
|
2286
|
+
msgs = [];
|
|
2287
|
+
node.state = {
|
|
2288
|
+
name,
|
|
2289
|
+
defs
|
|
2290
|
+
};
|
|
2291
|
+
data.insideModule = name;
|
|
2292
|
+
if (cxt.config.modules.has(name)) {
|
|
2293
|
+
const [combined, msg] = ModuleDefinition.combine(defs, cxt.config.modules.get(name));
|
|
2294
|
+
if (msg) msgs.push(new OverwriteDefinitionsMessage(node.head, msg));
|
|
2295
|
+
ModuleDefinition.apply(combined, cxt);
|
|
2296
|
+
debug.trace("entering defs for module", name, "(earlier data loaded)");
|
|
2297
|
+
} else debug.trace("entering defs for module", name);
|
|
2298
|
+
return msgs;
|
|
2299
|
+
},
|
|
2300
|
+
afterParseContent(node, cxt) {
|
|
2301
|
+
if (!node.state) return [];
|
|
2302
|
+
const data = cxt.get(builtins);
|
|
2303
|
+
data.insideModule = void 0;
|
|
2304
|
+
const old = ModuleDefinition.from(cxt);
|
|
2305
|
+
cxt.config.modules.set(node.state.name, ModuleDefinition.diff(old, node.state.defs));
|
|
2306
|
+
ModuleDefinition.apply(node.state.defs, cxt);
|
|
2307
|
+
debug.trace("exiting defs for module", node.state.name);
|
|
2308
|
+
return [];
|
|
2309
|
+
}
|
|
2310
|
+
});
|
|
2311
|
+
function use(node, cxt) {
|
|
2312
|
+
let { msgs, args, nodes } = bindArgs(node, ["name"]);
|
|
2313
|
+
if (msgs) return msgs;
|
|
2314
|
+
const data = cxt.get(builtins);
|
|
2315
|
+
if (!cxt.config.modules.has(args.name)) return [new InvalidArgumentMessage(nodes.name.location)];
|
|
2316
|
+
if (data.insideModule === args.name) return [new CannotUseModuleInSelfMessage(nodes.name.location)];
|
|
2317
|
+
const old = ModuleDefinition.from(cxt);
|
|
2318
|
+
const [combined, msg] = ModuleDefinition.combine(cxt.config.modules.get(args.name), old);
|
|
2319
|
+
ModuleDefinition.apply(combined, cxt);
|
|
2320
|
+
node.state = old;
|
|
2321
|
+
if (msg) return [new OverwriteDefinitionsMessage(node.head, msg)];
|
|
2322
|
+
return [];
|
|
2323
|
+
}
|
|
2324
|
+
const UseSystemMod = new SystemModifierDefinition("use", ModifierSlotType.None, { prepareExpand(node, cxt) {
|
|
2325
|
+
return use(node, cxt);
|
|
2326
|
+
} });
|
|
2327
|
+
const UseBlockMod = new BlockModifierDefinition("use", ModifierSlotType.Normal, {
|
|
2328
|
+
beforeParseContent(node, cxt) {
|
|
2329
|
+
return use(node, cxt);
|
|
2330
|
+
},
|
|
2331
|
+
afterParseContent(node, cxt) {
|
|
2332
|
+
if (node.state) ModuleDefinition.apply(node.state, cxt);
|
|
2333
|
+
return [];
|
|
2334
|
+
},
|
|
2335
|
+
expand(node) {
|
|
2336
|
+
return node.content;
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2339
|
+
|
|
2340
|
+
//#endregion
|
|
2341
|
+
//#region src/builtin/slot.ts
|
|
2342
|
+
function slotModifier(name, type, preformatted, inject) {
|
|
2343
|
+
const mod = type == NodeType.BlockModifier ? new BlockModifierDefinition(name, ModifierSlotType.None) : new InlineModifierDefinition(name, ModifierSlotType.None);
|
|
2344
|
+
const isInline = type == NodeType.InlineModifier;
|
|
2345
|
+
mod.alwaysTryExpand = true;
|
|
2346
|
+
mod.prepareExpand = (node, cxt, immediate) => {
|
|
2347
|
+
if (node.state) return [];
|
|
2348
|
+
function processSignature(s) {
|
|
2349
|
+
if (s.preformatted === void 0) {
|
|
2350
|
+
s.preformatted = preformatted;
|
|
2351
|
+
debug.trace("set preformatted to ", preformatted);
|
|
2352
|
+
} else if (s.preformatted !== preformatted) return [new EitherNormalOrPreMessage(node.location)];
|
|
2353
|
+
return [];
|
|
2354
|
+
}
|
|
2355
|
+
const check = inject ? bindArgs(node, ["modname"], { optional: ["id"] }) : bindArgs(node, [], { optional: ["id"] });
|
|
2356
|
+
if (check.msgs) {
|
|
2357
|
+
node.state = { ok: false };
|
|
2358
|
+
return check.msgs;
|
|
2359
|
+
}
|
|
2360
|
+
const store = cxt.get(builtins);
|
|
2361
|
+
const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
|
|
2362
|
+
const stack = isInline ? store.inlineSlotDelayedStack : store.blockSlotDelayedStack;
|
|
2363
|
+
let msgs = (() => {
|
|
2364
|
+
if (data.length == 0 && stack.length == 0) {
|
|
2365
|
+
node.state = { ok: false };
|
|
2366
|
+
return [new SlotUsedOutsideDefinitionMessage(node.location)];
|
|
2367
|
+
}
|
|
2368
|
+
const id = check.args.id;
|
|
2369
|
+
if (!id) {
|
|
2370
|
+
let signature$1 = stack.at(-1);
|
|
2371
|
+
if (signature$1) return processSignature(signature$1);
|
|
2372
|
+
node.state = {
|
|
2373
|
+
ok: true,
|
|
2374
|
+
data: data.at(-1),
|
|
2375
|
+
index: data.length - 1
|
|
2376
|
+
};
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
let signature = stack.find((x) => x.slotName == id);
|
|
2380
|
+
if (signature) return processSignature(signature);
|
|
2381
|
+
for (let i = data.length - 1; i >= 0; i--) if (data[i].slotName === id) {
|
|
2382
|
+
node.state = {
|
|
2383
|
+
ok: true,
|
|
2384
|
+
data: data[i],
|
|
2385
|
+
index: i
|
|
2386
|
+
};
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
if (immediate) {
|
|
2390
|
+
node.state = { ok: false };
|
|
2391
|
+
return [new InvalidArgumentMessage(check.nodes.id.location, id)];
|
|
2392
|
+
}
|
|
2393
|
+
return [];
|
|
2394
|
+
})();
|
|
2395
|
+
if (inject) {
|
|
2396
|
+
const modname = check.args.modname;
|
|
2397
|
+
const modnameNode = check.nodes.modname;
|
|
2398
|
+
const mod$1 = (isInline ? cxt.config.inlineModifiers : cxt.config.blockModifiers).get(modname);
|
|
2399
|
+
if (!mod$1) {
|
|
2400
|
+
node.state = { ok: false };
|
|
2401
|
+
return [new UnknownModifierMessage(modnameNode.location, modname)];
|
|
2402
|
+
}
|
|
2403
|
+
if (node.state?.ok) node.state.injectMod = mod$1;
|
|
2404
|
+
}
|
|
2405
|
+
if (msgs !== void 0) return msgs;
|
|
2406
|
+
return [];
|
|
2407
|
+
};
|
|
2408
|
+
mod.expand = (node, cxt) => {
|
|
2409
|
+
if (!node.state) return void 0;
|
|
2410
|
+
if (!node.state.ok) return [];
|
|
2411
|
+
let cloned = cloneNodes(node.state.data.slotContent);
|
|
2412
|
+
if (inject) {
|
|
2413
|
+
assert(node.state.injectMod !== void 0);
|
|
2414
|
+
return [{
|
|
2415
|
+
type,
|
|
2416
|
+
mod: node.state.injectMod,
|
|
2417
|
+
location: node.location,
|
|
2418
|
+
head: node.head,
|
|
2419
|
+
arguments: {
|
|
2420
|
+
positional: [],
|
|
2421
|
+
named: /* @__PURE__ */ new Map(),
|
|
2422
|
+
location: node.location
|
|
2423
|
+
},
|
|
2424
|
+
content: cloned
|
|
2425
|
+
}];
|
|
2426
|
+
} else return cloned;
|
|
2427
|
+
};
|
|
2428
|
+
mod.beforeProcessExpansion = (node, cxt) => {
|
|
2429
|
+
if (!node.state?.ok) return [];
|
|
2430
|
+
const store = cxt.get(builtins);
|
|
2431
|
+
debug.trace("temporarily removed slot data for", node.state.data.mod.name);
|
|
2432
|
+
(isInline ? store.inlineInstantiationData : store.blockInstantiationData).splice(node.state.index, 1);
|
|
2433
|
+
return [];
|
|
2434
|
+
};
|
|
2435
|
+
mod.afterProcessExpansion = (node, cxt) => {
|
|
2436
|
+
if (!node.state?.ok) return [];
|
|
2437
|
+
const store = cxt.get(builtins);
|
|
2438
|
+
debug.trace("reinstated slot data for", node.state.data.mod.name);
|
|
2439
|
+
(isInline ? store.inlineInstantiationData : store.blockInstantiationData).splice(node.state.index, 0, node.state.data);
|
|
2440
|
+
return [];
|
|
2441
|
+
};
|
|
2442
|
+
return mod;
|
|
2443
|
+
}
|
|
2444
|
+
const SlotBlockMod = slotModifier("slot", NodeType.BlockModifier, false, false);
|
|
2445
|
+
const SlotInlineMod = slotModifier("slot", NodeType.InlineModifier, false, false);
|
|
2446
|
+
const PreSlotBlockMod = slotModifier("pre-slot", NodeType.BlockModifier, true, false);
|
|
2447
|
+
const PreSlotInlineMod = slotModifier("pre-slot", NodeType.InlineModifier, true, false);
|
|
2448
|
+
const InjectPreSlotBlockMod = slotModifier("inject-pre-slot", NodeType.BlockModifier, true, true);
|
|
2449
|
+
const InjectPreSlotInlineMod = slotModifier("inject-pre-slot", NodeType.InlineModifier, true, true);
|
|
2450
|
+
|
|
2451
|
+
//#endregion
|
|
2452
|
+
//#region src/builtin/var.ts
|
|
2453
|
+
function resolveId(id, cxt) {
|
|
2454
|
+
const store = cxt.get(builtins);
|
|
2455
|
+
if (store.inlineSlotDelayedStack.find((x) => x.args.includes(id)) || store.blockSlotDelayedStack.find((x) => x.args.includes(id))) {
|
|
2456
|
+
debug.trace("delaying the yet unknown argument", id);
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
let value = void 0;
|
|
2460
|
+
for (let i = store.inlineInstantiationData.length - 1; i >= 0; i--) if ((value = store.inlineInstantiationData[i].args.get(id)) !== void 0) break;
|
|
2461
|
+
for (let i = store.blockInstantiationData.length - 1; i >= 0; i--) if ((value = store.blockInstantiationData[i].args.get(id)) !== void 0) break;
|
|
2462
|
+
if (value === void 0) value = cxt.variables.get(id);
|
|
2463
|
+
return value;
|
|
2464
|
+
}
|
|
2465
|
+
let ifdefBody = (x) => ({
|
|
2466
|
+
prepareExpand(node, cxt) {
|
|
2467
|
+
let { msgs, args, nodes } = bindArgs(node, ["id"]);
|
|
2468
|
+
if (msgs) return msgs;
|
|
2469
|
+
if (args.id == "") return [new InvalidArgumentMessage(nodes.id.location)];
|
|
2470
|
+
node.state = resolveId(args.id, cxt) !== void 0;
|
|
2471
|
+
return [];
|
|
2472
|
+
},
|
|
2473
|
+
expand(node) {
|
|
2474
|
+
return node.state == x ? node.content : [];
|
|
2475
|
+
}
|
|
2476
|
+
});
|
|
2477
|
+
let ifdefBlock = (name, x) => new BlockModifierDefinition(name, ModifierSlotType.Normal, ifdefBody(x));
|
|
2478
|
+
let ifdefInline = (name, x) => new InlineModifierDefinition(name, ModifierSlotType.Normal, ifdefBody(x));
|
|
2479
|
+
const IfdefBlockMod = ifdefBlock("ifdef", true);
|
|
2480
|
+
const IfndefBlockMod = ifdefBlock("ifndef", false);
|
|
2481
|
+
const IfdefInlineMod = ifdefInline("ifdef", true);
|
|
2482
|
+
const IfndefInlineMod = ifdefInline("ifndef", false);
|
|
2483
|
+
const GetVarInlineMod = new InlineModifierDefinition("$", ModifierSlotType.None, {
|
|
2484
|
+
alwaysTryExpand: true,
|
|
2485
|
+
prepareExpand(node, cxt, immediate) {
|
|
2486
|
+
let { msgs, args, nodes } = bindArgs(node, ["id"]);
|
|
2487
|
+
if (msgs) return immediate ? msgs : [];
|
|
2488
|
+
const id = args.id;
|
|
2489
|
+
if (id == "") return immediate ? [new InvalidArgumentMessage(nodes.id.location)] : [];
|
|
2490
|
+
const value = resolveId(id, cxt);
|
|
2491
|
+
if (value === void 0) return immediate ? [new UndefinedVariableMessage(nodes.id.location, id)] : [];
|
|
2492
|
+
node.state = { value };
|
|
2493
|
+
return [];
|
|
2494
|
+
},
|
|
2495
|
+
expand(node, _, immediate) {
|
|
2496
|
+
if (!node.state) return immediate ? [] : void 0;
|
|
2497
|
+
return [{
|
|
2498
|
+
type: NodeType.Text,
|
|
2499
|
+
content: node.state.value,
|
|
2500
|
+
location: node.location
|
|
2501
|
+
}];
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
const PrintInlineMod = new InlineModifierDefinition("print", ModifierSlotType.None, {
|
|
2505
|
+
prepareExpand(node) {
|
|
2506
|
+
let { msgs, rest } = bindArgs(node, [], { rest: true });
|
|
2507
|
+
if (msgs) return msgs;
|
|
2508
|
+
node.state = { value: rest.join("") };
|
|
2509
|
+
return [];
|
|
2510
|
+
},
|
|
2511
|
+
expand(node) {
|
|
2512
|
+
if (!node.state) return [];
|
|
2513
|
+
return [{
|
|
2514
|
+
type: NodeType.Text,
|
|
2515
|
+
content: node.state.value,
|
|
2516
|
+
location: node.location
|
|
2517
|
+
}];
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
2520
|
+
const GetVarInterpolator = new ArgumentInterpolatorDefinition("$(", ")", {
|
|
2521
|
+
alwaysTryExpand: true,
|
|
2522
|
+
expand(content, cxt) {
|
|
2523
|
+
const result = resolveId(content, cxt);
|
|
2524
|
+
if (result !== void 0) debug.trace(`$(${content}) --> ${result}`);
|
|
2525
|
+
return result;
|
|
2526
|
+
}
|
|
2527
|
+
});
|
|
2528
|
+
const VarMod = new SystemModifierDefinition("var", ModifierSlotType.None, {
|
|
2529
|
+
prepareExpand(node) {
|
|
2530
|
+
if (node.arguments.named.size == 1 && node.arguments.positional.length == 0) {
|
|
2531
|
+
const [id, arg] = [...node.arguments.named][0];
|
|
2532
|
+
if (arg.expansion === void 0) return [new CannotExpandArgumentMessage(arg.location)];
|
|
2533
|
+
node.state = {
|
|
2534
|
+
id,
|
|
2535
|
+
value: arg.expansion
|
|
2536
|
+
};
|
|
2537
|
+
return [];
|
|
2538
|
+
}
|
|
2539
|
+
let { msgs, args, nodes } = bindArgs(node, ["id", "value"]);
|
|
2540
|
+
if (msgs) return msgs;
|
|
2541
|
+
if (!args.id) return [new InvalidArgumentMessage(nodes.id.location)];
|
|
2542
|
+
node.state = {
|
|
2543
|
+
id: args.id,
|
|
2544
|
+
value: args.value
|
|
2545
|
+
};
|
|
2546
|
+
return [];
|
|
2547
|
+
},
|
|
2548
|
+
expand(node, cxt) {
|
|
2549
|
+
if (node.state) {
|
|
2550
|
+
cxt.variables.set(node.state.id, node.state.value);
|
|
2551
|
+
debug.trace("set variable", node.state.id, "=", node.state.value);
|
|
2552
|
+
}
|
|
2553
|
+
return [];
|
|
2554
|
+
}
|
|
2555
|
+
});
|
|
2556
|
+
|
|
2557
|
+
//#endregion
|
|
2558
|
+
//#region src/builtin/builtin.ts
|
|
2559
|
+
let builtin = new Configuration();
|
|
2560
|
+
builtin.initializers = [initParseContext];
|
|
2561
|
+
builtin.systemModifiers.add(DefineBlockMod, DefineInlineMod, DefineBlockShorthandMod, DefineInlineShorthandMod, VarMod, UseSystemMod);
|
|
2562
|
+
builtin.blockModifiers.add(SlotBlockMod, PreSlotBlockMod, InjectPreSlotBlockMod, ModuleMod, UseBlockMod, IfdefBlockMod, IfndefBlockMod, RawBlockMod, ConcatBlockMod);
|
|
2563
|
+
builtin.inlineModifiers.add(SlotInlineMod, PreSlotInlineMod, InjectPreSlotInlineMod, GetVarInlineMod, PrintInlineMod, IfdefInlineMod, IfndefInlineMod);
|
|
2564
|
+
builtin.argumentInterpolators.add(GetVarInterpolator);
|
|
2565
|
+
const BuiltinConfiguration = Object.freeze(builtin);
|
|
2566
|
+
|
|
2567
|
+
//#endregion
|
|
2568
|
+
//#region src/default/bullets.tsx
|
|
2569
|
+
const bulletItemBlock = new BlockModifierDefinition("bullet-item", ModifierSlotType.Normal, { roleHint: void 0 });
|
|
2570
|
+
const orderedListItemBlock = new BlockModifierDefinition("ordered-item", ModifierSlotType.Normal, {
|
|
2571
|
+
roleHint: void 0,
|
|
2572
|
+
prepareExpand(node) {
|
|
2573
|
+
let { msgs, args, nodes } = bindArgs(node, ["number"]);
|
|
2574
|
+
if (msgs) return msgs;
|
|
2575
|
+
let num = Number.parseInt(args.number);
|
|
2576
|
+
if (isNaN(num)) return [new InvalidArgumentMessage(nodes.number.location, "should be a number")];
|
|
2577
|
+
node.state = num;
|
|
2578
|
+
return [];
|
|
2579
|
+
}
|
|
2580
|
+
});
|
|
2581
|
+
const subItemBlock = new BlockModifierDefinition("subitem", ModifierSlotType.Normal, { roleHint: void 0 });
|
|
2582
|
+
const BulletBlocks = [
|
|
2583
|
+
bulletItemBlock,
|
|
2584
|
+
orderedListItemBlock,
|
|
2585
|
+
subItemBlock
|
|
2586
|
+
];
|
|
2587
|
+
const BulletBlockRenderersHTML = [
|
|
2588
|
+
[bulletItemBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("li", {
|
|
2589
|
+
class: "bullet",
|
|
2590
|
+
children: cxt.state.render(node.content, cxt)
|
|
2591
|
+
})],
|
|
2592
|
+
[subItemBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("div", {
|
|
2593
|
+
class: "subitem",
|
|
2594
|
+
children: cxt.state.render(node.content, cxt)
|
|
2595
|
+
})],
|
|
2596
|
+
[orderedListItemBlock, (node, cxt) => node.state === void 0 ? cxt.state.invalidBlock(node, "bad format") : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("li", {
|
|
2597
|
+
class: "ordered",
|
|
2598
|
+
value: node.state,
|
|
2599
|
+
children: cxt.state.render(node.content, cxt)
|
|
2600
|
+
})]
|
|
2601
|
+
];
|
|
2602
|
+
|
|
2603
|
+
//#endregion
|
|
2604
|
+
//#region src/default/headings.tsx
|
|
2605
|
+
const headings = Symbol();
|
|
2606
|
+
function initHeadings(cxt) {
|
|
2607
|
+
cxt.init(headings, { path: [] });
|
|
2608
|
+
}
|
|
2609
|
+
function setHeading(cxt, data) {
|
|
2610
|
+
const path = cxt.get(headings).path;
|
|
2611
|
+
while (path.length > 0 && path.at(-1).level >= data.level) path.pop();
|
|
2612
|
+
path.push(data);
|
|
2613
|
+
return [];
|
|
2614
|
+
}
|
|
2615
|
+
function currentHeadingLevel(cxt) {
|
|
2616
|
+
return cxt.get(headings).path.at(-1)?.level;
|
|
2617
|
+
}
|
|
2618
|
+
function currentExplicitHeadingLevel(cxt) {
|
|
2619
|
+
return cxt.get(headings).path.findLast((x) => !x.implicit)?.level;
|
|
2620
|
+
}
|
|
2621
|
+
const headingBlock = new BlockModifierDefinition("heading", ModifierSlotType.Normal, {
|
|
2622
|
+
roleHint: "heading",
|
|
2623
|
+
prepareExpand(node, cxt) {
|
|
2624
|
+
let { msgs, args, nodes } = bindArgs(node, [], { optional: ["n"] });
|
|
2625
|
+
if (msgs) return msgs;
|
|
2626
|
+
msgs = onlyPermitSingleBlock(node);
|
|
2627
|
+
if (msgs) return msgs;
|
|
2628
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
2629
|
+
if (msgs) return msgs;
|
|
2630
|
+
node.state = {
|
|
2631
|
+
name: void 0,
|
|
2632
|
+
level: currentHeadingLevel(cxt) ?? 1
|
|
2633
|
+
};
|
|
2634
|
+
if (args.n !== void 0) {
|
|
2635
|
+
const level = Number.parseInt(args.n);
|
|
2636
|
+
if (isNaN(level) || level < 1 || level > 6) msgs = [new InvalidArgumentMessage(nodes.n.location, "should be a number between 1 and 6")];
|
|
2637
|
+
else node.state.level = level;
|
|
2638
|
+
}
|
|
2639
|
+
setHeading(cxt, node.state);
|
|
2640
|
+
return msgs ?? [];
|
|
2641
|
+
}
|
|
2642
|
+
});
|
|
2643
|
+
const implicitHeadingBlock = new BlockModifierDefinition("implicit-heading", ModifierSlotType.None, {
|
|
2644
|
+
roleHint: "heading",
|
|
2645
|
+
prepareExpand(node, cxt) {
|
|
2646
|
+
let { msgs, args, nodes } = bindArgs(node, [], { optional: ["n"] });
|
|
2647
|
+
if (msgs) return msgs;
|
|
2648
|
+
node.state = {
|
|
2649
|
+
name: void 0,
|
|
2650
|
+
implicit: true,
|
|
2651
|
+
level: (currentExplicitHeadingLevel(cxt) ?? 0) + 1
|
|
2652
|
+
};
|
|
2653
|
+
if (args.n !== void 0) {
|
|
2654
|
+
const level = Number.parseInt(args.n);
|
|
2655
|
+
if (isNaN(level) || level < 1 || level > 6) msgs = [new InvalidArgumentMessage(nodes.n.location, "should be a number between 1 and 6")];
|
|
2656
|
+
else node.state.level = level;
|
|
2657
|
+
}
|
|
2658
|
+
setHeading(cxt, node.state);
|
|
2659
|
+
return msgs ?? [];
|
|
2660
|
+
}
|
|
2661
|
+
});
|
|
2662
|
+
const numberedHeadingBlock = new BlockModifierDefinition("numbered-heading", ModifierSlotType.Normal, {
|
|
2663
|
+
roleHint: "heading",
|
|
2664
|
+
prepareExpand(node, cxt) {
|
|
2665
|
+
let { msgs, args, nodes } = bindArgs(node, ["number"]);
|
|
2666
|
+
if (msgs) return msgs;
|
|
2667
|
+
msgs = onlyPermitSingleBlock(node, { optional: true });
|
|
2668
|
+
if (msgs) return msgs;
|
|
2669
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
2670
|
+
if (msgs) return msgs;
|
|
2671
|
+
node.state = {
|
|
2672
|
+
name: void 0,
|
|
2673
|
+
level: currentHeadingLevel(cxt) ?? 1
|
|
2674
|
+
};
|
|
2675
|
+
const split = args.number.trim().split(".").filter((x) => x.length > 0);
|
|
2676
|
+
if (split.length == 0 || split.length > 6) msgs = [new InvalidArgumentMessage(nodes.number.location, "heading level should be between 1 and 6")];
|
|
2677
|
+
else node.state = {
|
|
2678
|
+
name: split.join("."),
|
|
2679
|
+
level: split.length
|
|
2680
|
+
};
|
|
2681
|
+
setHeading(cxt, node.state);
|
|
2682
|
+
return msgs ?? [];
|
|
2683
|
+
}
|
|
2684
|
+
});
|
|
2685
|
+
const HeadingBlocks = [
|
|
2686
|
+
headingBlock,
|
|
2687
|
+
implicitHeadingBlock,
|
|
2688
|
+
numberedHeadingBlock
|
|
2689
|
+
];
|
|
2690
|
+
const HeadingBlockRenderersHTML = [
|
|
2691
|
+
[headingBlock, (node, cxt) => {
|
|
2692
|
+
if (node.state !== void 0) {
|
|
2693
|
+
const tag = "h" + node.state.level;
|
|
2694
|
+
const para = node.content[0];
|
|
2695
|
+
const element = document.createElement(tag);
|
|
2696
|
+
element.appendChild(cxt.state.render(para.content, cxt));
|
|
2697
|
+
return element;
|
|
2698
|
+
}
|
|
2699
|
+
return cxt.state.invalidBlock(node, "Bad format");
|
|
2700
|
+
}],
|
|
2701
|
+
[implicitHeadingBlock, (node, cxt) => {
|
|
2702
|
+
if (node.state !== void 0) {
|
|
2703
|
+
const tag = "h" + node.state.level;
|
|
2704
|
+
const element = document.createElement(tag);
|
|
2705
|
+
element.className = "implicit";
|
|
2706
|
+
return element;
|
|
2707
|
+
}
|
|
2708
|
+
return cxt.state.invalidBlock(node, "Bad format");
|
|
2709
|
+
}],
|
|
2710
|
+
[numberedHeadingBlock, (node, cxt) => {
|
|
2711
|
+
if (node.state !== void 0) {
|
|
2712
|
+
const tag = "h" + node.state.level;
|
|
2713
|
+
const element = document.createElement(tag);
|
|
2714
|
+
element.className = "numbered-heading";
|
|
2715
|
+
element.appendChild(/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("span", {
|
|
2716
|
+
class: "heading-number",
|
|
2717
|
+
children: node.state.name
|
|
2718
|
+
}));
|
|
2719
|
+
if (node.content.length > 0) {
|
|
2720
|
+
const para = node.content[0];
|
|
2721
|
+
element.appendChild(/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("span", {
|
|
2722
|
+
class: "heading-content",
|
|
2723
|
+
children: cxt.state.render(para.content, cxt)
|
|
2724
|
+
}));
|
|
2725
|
+
}
|
|
2726
|
+
return element;
|
|
2727
|
+
}
|
|
2728
|
+
return cxt.state.invalidBlock(node, "Bad format");
|
|
2729
|
+
}]
|
|
2730
|
+
];
|
|
2731
|
+
|
|
2732
|
+
//#endregion
|
|
2733
|
+
//#region src/default/notes.tsx
|
|
2734
|
+
const notes = Symbol();
|
|
2735
|
+
function initNotes(cxt) {
|
|
2736
|
+
cxt.init(notes, {
|
|
2737
|
+
systems: /* @__PURE__ */ new Map(),
|
|
2738
|
+
defaultSystem: {
|
|
2739
|
+
position: "preserve",
|
|
2740
|
+
autonumber: false
|
|
2741
|
+
},
|
|
2742
|
+
definitions: [],
|
|
2743
|
+
currentId: 0
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
function getSystem(cxt, name) {
|
|
2747
|
+
const defs = cxt.get(notes);
|
|
2748
|
+
let system;
|
|
2749
|
+
if (name) if (!defs.systems.has(name)) {
|
|
2750
|
+
system = { ...defs.defaultSystem };
|
|
2751
|
+
defs.systems.set(name, system);
|
|
2752
|
+
} else system = defs.systems.get(name);
|
|
2753
|
+
else system = defs.defaultSystem;
|
|
2754
|
+
return system;
|
|
2755
|
+
}
|
|
2756
|
+
const notePositionSystem = new SystemModifierDefinition("note-position", ModifierSlotType.None, { prepareExpand(node, cxt) {
|
|
2757
|
+
let { msgs, args, nodes } = bindArgs(node, ["type"], {
|
|
2758
|
+
optional: ["name"],
|
|
2759
|
+
trim: true
|
|
2760
|
+
});
|
|
2761
|
+
if (msgs) return msgs;
|
|
2762
|
+
if (args.type != "global" && args.type != "preserve") return [new InvalidArgumentMessage(nodes.type.location, "should be `preserve` or `global`")];
|
|
2763
|
+
getSystem(cxt, args.name).position = args.type;
|
|
2764
|
+
return [];
|
|
2765
|
+
} });
|
|
2766
|
+
const noteRenumberingSystem = new SystemModifierDefinition("note-renumbering", ModifierSlotType.None, { prepareExpand(node, cxt) {
|
|
2767
|
+
let { msgs, args, nodes } = bindArgs(node, ["type"], {
|
|
2768
|
+
optional: ["name"],
|
|
2769
|
+
trim: true
|
|
2770
|
+
});
|
|
2771
|
+
if (msgs) return msgs;
|
|
2772
|
+
if (args.type != "on" && args.type != "off") return [new InvalidArgumentMessage(nodes.type.location, "should be `preserve` or `global`")];
|
|
2773
|
+
getSystem(cxt, args.name).autonumber = args.type == "on";
|
|
2774
|
+
return [];
|
|
2775
|
+
} });
|
|
2776
|
+
const noteMarkerInline = new InlineModifierDefinition("note", ModifierSlotType.None, {
|
|
2777
|
+
roleHint: "link",
|
|
2778
|
+
prepareExpand(node) {
|
|
2779
|
+
let { msgs, args } = bindArgs(node, ["index"]);
|
|
2780
|
+
if (msgs) return msgs;
|
|
2781
|
+
node.state = args?.index;
|
|
2782
|
+
return [];
|
|
2783
|
+
}
|
|
2784
|
+
});
|
|
2785
|
+
const noteInline = new InlineModifierDefinition("note-inline", ModifierSlotType.Normal, {
|
|
2786
|
+
roleHint: "quote",
|
|
2787
|
+
prepareExpand(node) {
|
|
2788
|
+
let { msgs, args } = bindArgs(node, [], { optional: ["index"] });
|
|
2789
|
+
if (msgs) return msgs;
|
|
2790
|
+
node.state = args?.index ?? "";
|
|
2791
|
+
return [];
|
|
2792
|
+
},
|
|
2793
|
+
beforeProcessExpansion(node, cxt) {
|
|
2794
|
+
if (node.state !== void 0) {
|
|
2795
|
+
const defs = cxt.get(notes);
|
|
2796
|
+
defs.definitions.push({
|
|
2797
|
+
system: "",
|
|
2798
|
+
id: defs.currentId,
|
|
2799
|
+
name: node.state,
|
|
2800
|
+
location: node.location,
|
|
2801
|
+
content: [{
|
|
2802
|
+
type: NodeType.Paragraph,
|
|
2803
|
+
location: {
|
|
2804
|
+
source: node.location.source,
|
|
2805
|
+
start: node.head.end,
|
|
2806
|
+
end: node.location.actualEnd ?? node.location.end
|
|
2807
|
+
},
|
|
2808
|
+
content: node.content
|
|
2809
|
+
}]
|
|
2810
|
+
});
|
|
2811
|
+
defs.currentId++;
|
|
2812
|
+
}
|
|
2813
|
+
return [];
|
|
2814
|
+
}
|
|
2815
|
+
});
|
|
2816
|
+
const noteBlock = new BlockModifierDefinition("note", ModifierSlotType.Normal, {
|
|
2817
|
+
roleHint: "quote",
|
|
2818
|
+
prepareExpand(node, cxt) {
|
|
2819
|
+
let { msgs, args } = bindArgs(node, ["name"], {
|
|
2820
|
+
optional: ["system"],
|
|
2821
|
+
trim: true
|
|
2822
|
+
});
|
|
2823
|
+
if (msgs) return msgs;
|
|
2824
|
+
const content = stripNode(...node.content);
|
|
2825
|
+
debug.trace(`add note: system=<> name=${args.name} @${node.location.start}`);
|
|
2826
|
+
debug.trace(`-->\n`, debugPrint.node(...content));
|
|
2827
|
+
const defs = cxt.get(notes);
|
|
2828
|
+
const entry = {
|
|
2829
|
+
id: defs.currentId,
|
|
2830
|
+
system: args.system ?? "",
|
|
2831
|
+
name: args.name,
|
|
2832
|
+
location: node.location,
|
|
2833
|
+
content
|
|
2834
|
+
};
|
|
2835
|
+
defs.currentId++;
|
|
2836
|
+
defs.definitions.push(entry);
|
|
2837
|
+
node.state = entry;
|
|
2838
|
+
return [];
|
|
2839
|
+
}
|
|
2840
|
+
});
|
|
2841
|
+
const NoteBlocks = [noteBlock];
|
|
2842
|
+
const NoteInlines = [noteInline, noteMarkerInline];
|
|
2843
|
+
const NoteSystems = [notePositionSystem, noteRenumberingSystem];
|
|
2844
|
+
function makeNoteHTML(def, cxt) {
|
|
2845
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("section", {
|
|
2846
|
+
class: "note",
|
|
2847
|
+
id: `note-id-${def.id}`,
|
|
2848
|
+
children: [/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("div", {
|
|
2849
|
+
class: "note-name",
|
|
2850
|
+
children: /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("p", { children: /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("a", {
|
|
2851
|
+
href: `#notemarker-id-${def.id}`,
|
|
2852
|
+
children: def.name
|
|
2853
|
+
}) })
|
|
2854
|
+
}), /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("div", {
|
|
2855
|
+
class: "note-content",
|
|
2856
|
+
children: cxt.state.render(def.content, cxt)
|
|
2857
|
+
})]
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
const NoteInlineRenderersHTML = [[noteMarkerInline, (node, cxt) => {
|
|
2861
|
+
if (node.state === void 0) return cxt.state.invalidInline(node, "bad format");
|
|
2862
|
+
const note = cxt.parsedDocument.context.get(notes).definitions.findIndex((x) => x.name == node.state);
|
|
2863
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("sup", {
|
|
2864
|
+
class: "note",
|
|
2865
|
+
id: `notemarker-id-${note}`,
|
|
2866
|
+
children: note < 0 ? `Not found: ${node.state}` : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("a", {
|
|
2867
|
+
href: `#note-id-${note}`,
|
|
2868
|
+
children: node.state
|
|
2869
|
+
})
|
|
2870
|
+
});
|
|
2871
|
+
}]];
|
|
2872
|
+
const NoteBlockRenderersHTML = [[noteBlock, (node, cxt) => {
|
|
2873
|
+
if (node.state === void 0) return cxt.state.invalidBlock(node, "bad format");
|
|
2874
|
+
const defs = cxt.parsedDocument.context.get(notes);
|
|
2875
|
+
if ((defs.systems.get(node.state.system) ?? defs.defaultSystem).position != "preserve") return [];
|
|
2876
|
+
return makeNoteHTML(node.state, cxt);
|
|
2877
|
+
}]];
|
|
2878
|
+
const NotesFooterPlugin = (cxt) => {
|
|
2879
|
+
const defs = cxt.parsedDocument.context.get(notes);
|
|
2880
|
+
const items = cxt.parsedDocument.context.get(notes).definitions.filter((x) => (defs.systems.get(x.system) ?? defs.defaultSystem).position == "global");
|
|
2881
|
+
if (items.length == 0) return void 0;
|
|
2882
|
+
return [/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("hr", {}), /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("section", {
|
|
2883
|
+
class: "notes-global",
|
|
2884
|
+
children: items.map((x) => makeNoteHTML(x, cxt))
|
|
2885
|
+
})];
|
|
2886
|
+
};
|
|
2887
|
+
|
|
2888
|
+
//#endregion
|
|
2889
|
+
//#region src/default/code.tsx
|
|
2890
|
+
const CodeBlock = new BlockModifierDefinition("code", ModifierSlotType.Preformatted, { roleHint: "code" });
|
|
2891
|
+
const CodeInline = new InlineModifierDefinition("code", ModifierSlotType.Preformatted, { roleHint: "code" });
|
|
2892
|
+
const CodeBlockRendererHTML = [CodeBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("pre", { children: /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("code", { children: cxt.state.render(node.content, cxt) }) })];
|
|
2893
|
+
const CodeInlineRendererHTML = [CodeInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("span", { children: /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("code", { children: cxt.state.render(node.content, cxt) }) })];
|
|
2894
|
+
|
|
2895
|
+
//#endregion
|
|
2896
|
+
//#region src/default/quotes.tsx
|
|
2897
|
+
const quoteBlock = new BlockModifierDefinition("quote", ModifierSlotType.Normal, { roleHint: "quote" });
|
|
2898
|
+
const epitaphBlock = new BlockModifierDefinition("epitaph", ModifierSlotType.Normal, { roleHint: "quote" });
|
|
2899
|
+
const calloutBlock = new BlockModifierDefinition("callout", ModifierSlotType.Normal, { roleHint: "quote" });
|
|
2900
|
+
const detailBlock = new BlockModifierDefinition("detail", ModifierSlotType.Normal, { roleHint: "quote" });
|
|
2901
|
+
const attributionBlock = new BlockModifierDefinition("by", ModifierSlotType.Normal, {
|
|
2902
|
+
roleHint: "quote",
|
|
2903
|
+
prepareExpand(node) {
|
|
2904
|
+
let msgs = onlyPermitSingleBlock(node);
|
|
2905
|
+
if (msgs) return msgs;
|
|
2906
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
2907
|
+
if (msgs) return msgs;
|
|
2908
|
+
node.state = true;
|
|
2909
|
+
return [];
|
|
2910
|
+
}
|
|
2911
|
+
});
|
|
2912
|
+
const QuoteBlocks = [
|
|
2913
|
+
quoteBlock,
|
|
2914
|
+
epitaphBlock,
|
|
2915
|
+
calloutBlock,
|
|
2916
|
+
detailBlock,
|
|
2917
|
+
attributionBlock
|
|
2918
|
+
];
|
|
2919
|
+
const QuoteBlockRenderersHTML = [
|
|
2920
|
+
[quoteBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("blockquote", { children: cxt.state.render(node.content, cxt) })],
|
|
2921
|
+
[epitaphBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("blockquote", {
|
|
2922
|
+
class: "epitaph",
|
|
2923
|
+
children: cxt.state.render(node.content, cxt)
|
|
2924
|
+
})],
|
|
2925
|
+
[detailBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("div", {
|
|
2926
|
+
class: "detail",
|
|
2927
|
+
children: cxt.state.render(node.content, cxt)
|
|
2928
|
+
})],
|
|
2929
|
+
[calloutBlock, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("aside", { children: cxt.state.render(node.content, cxt) })],
|
|
2930
|
+
[attributionBlock, (node, cxt) => {
|
|
2931
|
+
if (!node.state) return cxt.state.invalidBlock(node, "bad format");
|
|
2932
|
+
let para = node.content[0];
|
|
2933
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("p", {
|
|
2934
|
+
class: "attribution",
|
|
2935
|
+
children: cxt.state.render(para.content, cxt)
|
|
2936
|
+
});
|
|
2937
|
+
}]
|
|
2938
|
+
];
|
|
2939
|
+
|
|
2940
|
+
//#endregion
|
|
2941
|
+
//#region src/default/inline-styles.tsx
|
|
2942
|
+
const emphasisInline = new InlineModifierDefinition("emphasis", ModifierSlotType.Normal, { roleHint: "emphasis" });
|
|
2943
|
+
const keywordInline = new InlineModifierDefinition("keyword", ModifierSlotType.Normal, { roleHint: "keyword" });
|
|
2944
|
+
const highlightInline = new InlineModifierDefinition("highlight", ModifierSlotType.Normal, { roleHint: "highlight" });
|
|
2945
|
+
const commentaryInline = new InlineModifierDefinition("commentary", ModifierSlotType.Normal, { roleHint: "commentary" });
|
|
2946
|
+
const sequenceInline = new InlineModifierDefinition("seq", ModifierSlotType.Normal, { roleHint: "pre" });
|
|
2947
|
+
const InlineStyles = [
|
|
2948
|
+
emphasisInline,
|
|
2949
|
+
keywordInline,
|
|
2950
|
+
highlightInline,
|
|
2951
|
+
commentaryInline,
|
|
2952
|
+
sequenceInline
|
|
2953
|
+
];
|
|
2954
|
+
const InlineStyleRenderersHTML = [
|
|
2955
|
+
[emphasisInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("em", { children: cxt.state.render(node.content, cxt) })],
|
|
2956
|
+
[keywordInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("b", { children: cxt.state.render(node.content, cxt) })],
|
|
2957
|
+
[highlightInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("mark", { children: cxt.state.render(node.content, cxt) })],
|
|
2958
|
+
[commentaryInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("span", {
|
|
2959
|
+
class: "commentary",
|
|
2960
|
+
children: cxt.state.render(node.content, cxt)
|
|
2961
|
+
})],
|
|
2962
|
+
[sequenceInline, (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("span", {
|
|
2963
|
+
class: "seq",
|
|
2964
|
+
children: cxt.state.render(node.content, cxt)
|
|
2965
|
+
})]
|
|
2966
|
+
];
|
|
2967
|
+
|
|
2968
|
+
//#endregion
|
|
2969
|
+
//#region src/default/misc.tsx
|
|
2970
|
+
const rubyInline = new InlineModifierDefinition("ruby", ModifierSlotType.Normal, {
|
|
2971
|
+
roleHint: void 0,
|
|
2972
|
+
prepareExpand(node) {
|
|
2973
|
+
let { msgs, args } = bindArgs(node, ["text"]);
|
|
2974
|
+
if (msgs) return msgs;
|
|
2975
|
+
node.state = args.text;
|
|
2976
|
+
return [];
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2979
|
+
const linkInline = new InlineModifierDefinition("link", ModifierSlotType.Normal, {
|
|
2980
|
+
roleHint: "link",
|
|
2981
|
+
prepareExpand(node) {
|
|
2982
|
+
let { msgs, args } = bindArgs(node, ["url"]);
|
|
2983
|
+
if (msgs) return msgs;
|
|
2984
|
+
node.state = args.url;
|
|
2985
|
+
return [];
|
|
2986
|
+
}
|
|
2987
|
+
});
|
|
2988
|
+
const tabInline = new InlineModifierDefinition("tab", ModifierSlotType.None);
|
|
2989
|
+
const styleBlock = new BlockModifierDefinition("style", ModifierSlotType.Normal, { prepareExpand(node) {
|
|
2990
|
+
let { msgs, args } = bindArgs(node, ["style"]);
|
|
2991
|
+
if (msgs) return msgs;
|
|
2992
|
+
node.state = args.style;
|
|
2993
|
+
return [];
|
|
2994
|
+
} });
|
|
2995
|
+
const breakBlock = new BlockModifierDefinition("break", ModifierSlotType.None);
|
|
2996
|
+
const linkBlock = new BlockModifierDefinition("link", ModifierSlotType.Normal, {
|
|
2997
|
+
roleHint: "link",
|
|
2998
|
+
prepareExpand(node) {
|
|
2999
|
+
let { msgs, args } = bindArgs(node, ["url"]);
|
|
3000
|
+
if (msgs) return msgs;
|
|
3001
|
+
node.state = args.url;
|
|
3002
|
+
return [];
|
|
3003
|
+
}
|
|
3004
|
+
});
|
|
3005
|
+
const imageBlock = new BlockModifierDefinition("image", ModifierSlotType.Normal, {
|
|
3006
|
+
roleHint: "link",
|
|
3007
|
+
prepareExpand(node) {
|
|
3008
|
+
let { msgs, args } = bindArgs(node, ["url"]);
|
|
3009
|
+
if (msgs) return msgs;
|
|
3010
|
+
msgs = onlyPermitSingleBlock(node, { optional: true });
|
|
3011
|
+
if (msgs) return msgs;
|
|
3012
|
+
msgs = onlyPermitSimpleParagraphs(node);
|
|
3013
|
+
if (msgs) return msgs;
|
|
3014
|
+
node.state = args.url;
|
|
3015
|
+
return [];
|
|
3016
|
+
}
|
|
3017
|
+
});
|
|
3018
|
+
const MiscInlines = [
|
|
3019
|
+
rubyInline,
|
|
3020
|
+
linkInline,
|
|
3021
|
+
tabInline
|
|
3022
|
+
];
|
|
3023
|
+
const MiscBlocks = [
|
|
3024
|
+
styleBlock,
|
|
3025
|
+
breakBlock,
|
|
3026
|
+
linkBlock,
|
|
3027
|
+
imageBlock
|
|
3028
|
+
];
|
|
3029
|
+
const MiscInlineRenderersHTML = [
|
|
3030
|
+
[rubyInline, (node, cxt) => node.state === void 0 ? cxt.state.invalidInline(node, "bad format") : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("ruby", { children: [cxt.state.render(node.content, cxt), /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("rt", { children: node.state })] })],
|
|
3031
|
+
[linkInline, (node, cxt) => node.state === void 0 ? cxt.state.invalidInline(node, "bad format") : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("a", {
|
|
3032
|
+
href: encodeURI(node.state),
|
|
3033
|
+
children: cxt.state.render(node.content, cxt)
|
|
3034
|
+
})],
|
|
3035
|
+
[tabInline, () => new Text(" ")]
|
|
3036
|
+
];
|
|
3037
|
+
const MiscBlockRenderersHTML = [
|
|
3038
|
+
[styleBlock, (node, cxt) => node.state === void 0 ? cxt.state.invalidBlock(node, "bad format") : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("div", {
|
|
3039
|
+
class: `emmmstyle-${node.state}`,
|
|
3040
|
+
style: "display:contents",
|
|
3041
|
+
children: cxt.state.render(node.content, cxt)
|
|
3042
|
+
})],
|
|
3043
|
+
[breakBlock, () => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("hr", {})],
|
|
3044
|
+
[linkBlock, (node, cxt) => {
|
|
3045
|
+
if (node.state === void 0) return cxt.state.invalidBlock(node, "bad format");
|
|
3046
|
+
const content = cxt.state.render(node.content, cxt);
|
|
3047
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("a", {
|
|
3048
|
+
href: encodeURI(node.state),
|
|
3049
|
+
children: content.childElementCount > 0 ? content : node.state
|
|
3050
|
+
});
|
|
3051
|
+
}],
|
|
3052
|
+
[imageBlock, (node, cxt) => {
|
|
3053
|
+
if (node.state === void 0) return cxt.state.invalidBlock(node, "bad format");
|
|
3054
|
+
let transformed;
|
|
3055
|
+
try {
|
|
3056
|
+
transformed = cxt.config.options.transformAsset(node.state);
|
|
3057
|
+
} catch {
|
|
3058
|
+
return cxt.state.invalidBlock(node, "unable to transform asset");
|
|
3059
|
+
}
|
|
3060
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("figure", { children: [transformed ? /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("img", {
|
|
3061
|
+
src: transformed,
|
|
3062
|
+
"data-original-src": node.state
|
|
3063
|
+
}) : /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("img", { src: node.state }), node.content.length > 0 ? /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("figcaption", { children: cxt.state.render(node.content[0].content, cxt) }) : []] });
|
|
3064
|
+
}]
|
|
3065
|
+
];
|
|
3066
|
+
|
|
3067
|
+
//#endregion
|
|
3068
|
+
//#region src/default/table.tsx
|
|
3069
|
+
const table = Symbol();
|
|
3070
|
+
function initTable(cxt) {
|
|
3071
|
+
cxt.init(table, { current: void 0 });
|
|
3072
|
+
}
|
|
3073
|
+
const tableBlock = new BlockModifierDefinition("table", ModifierSlotType.Normal, {
|
|
3074
|
+
beforeParseContent(node, cxt, immediate) {
|
|
3075
|
+
if (!immediate || node.state) return [];
|
|
3076
|
+
const t = cxt.get(table);
|
|
3077
|
+
if (t.current) return [new EntityNotAllowedMessage(node.location, "tables cannot be nested")];
|
|
3078
|
+
node.state = {
|
|
3079
|
+
status: "header",
|
|
3080
|
+
header: [],
|
|
3081
|
+
body: [],
|
|
3082
|
+
footer: []
|
|
3083
|
+
};
|
|
3084
|
+
t.current = node.state;
|
|
3085
|
+
debug.trace("entering table");
|
|
3086
|
+
return [];
|
|
3087
|
+
},
|
|
3088
|
+
afterParseContent(_node, cxt) {
|
|
3089
|
+
cxt.get(table).current = void 0;
|
|
3090
|
+
debug.trace("leaving table");
|
|
3091
|
+
return [];
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
3094
|
+
const tableRowBlock = new BlockModifierDefinition("table-row", ModifierSlotType.Normal, { beforeProcessExpansion(node, cxt, immediate) {
|
|
3095
|
+
if (!immediate) return [];
|
|
3096
|
+
const t = cxt.get(table).current;
|
|
3097
|
+
if (!t) return [new EntityNotAllowedMessage(node.location, "rows can only appear in tables")];
|
|
3098
|
+
const newNode = stripNode(cloneNode(node));
|
|
3099
|
+
debug.info("pushing table row\n", debugPrint.node(...newNode));
|
|
3100
|
+
if (t.status == "header") t.header.push(...newNode);
|
|
3101
|
+
if (t.status == "body") t.body.push(...newNode);
|
|
3102
|
+
if (t.status == "footer") t.footer.push(...newNode);
|
|
3103
|
+
return [];
|
|
3104
|
+
} });
|
|
3105
|
+
const tableSeparatorBlock = new BlockModifierDefinition("table-separator", ModifierSlotType.None, {
|
|
3106
|
+
prepareExpand(node, cxt) {
|
|
3107
|
+
const t = cxt.get(table).current;
|
|
3108
|
+
if (!t) return [new EntityNotAllowedMessage(node.location, "separators can only appear in tables")];
|
|
3109
|
+
if (t.status == "header") t.status = "body";
|
|
3110
|
+
else if (t.status == "body") t.status = "footer";
|
|
3111
|
+
else if (t.status == "footer") {}
|
|
3112
|
+
debug.trace("table status ->", t.status);
|
|
3113
|
+
return [];
|
|
3114
|
+
},
|
|
3115
|
+
expand() {
|
|
3116
|
+
return [];
|
|
3117
|
+
}
|
|
3118
|
+
});
|
|
3119
|
+
const tableCellBlock = new BlockModifierDefinition("table-cell", ModifierSlotType.Normal, { beforeProcessExpansion(node, cxt, immediate) {
|
|
3120
|
+
if (!immediate) return [];
|
|
3121
|
+
if (!cxt.get(table).current) return [new EntityNotAllowedMessage(node.location, "cells can only appear in tables")];
|
|
3122
|
+
return [];
|
|
3123
|
+
} });
|
|
3124
|
+
const tableCellInline = new InlineModifierDefinition("table-cell", ModifierSlotType.Normal, { beforeProcessExpansion(node, cxt, immediate) {
|
|
3125
|
+
if (!immediate) return [];
|
|
3126
|
+
if (!cxt.get(table).current) return [new EntityNotAllowedMessage(node.location, "cells can only appear in tables")];
|
|
3127
|
+
return [];
|
|
3128
|
+
} });
|
|
3129
|
+
const TableBlocks = [
|
|
3130
|
+
tableBlock,
|
|
3131
|
+
tableRowBlock,
|
|
3132
|
+
tableCellBlock,
|
|
3133
|
+
tableSeparatorBlock
|
|
3134
|
+
];
|
|
3135
|
+
const TableInlines = [tableCellInline];
|
|
3136
|
+
const TableBlockRenderers = [
|
|
3137
|
+
[tableBlock, (node, cxt) => {
|
|
3138
|
+
const t = node.state;
|
|
3139
|
+
if (!t) return cxt.state.invalidBlock(node, "bad format");
|
|
3140
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("table", { children: [
|
|
3141
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("thead", { children: cxt.state.render(t.header, cxt) }),
|
|
3142
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("tbody", { children: cxt.state.render(t.body, cxt) }),
|
|
3143
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("tfoot", { children: cxt.state.render(t.footer, cxt) })
|
|
3144
|
+
] });
|
|
3145
|
+
}],
|
|
3146
|
+
[tableRowBlock, (node, cxt) => {
|
|
3147
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("tr", { children: cxt.state.render(node.content, cxt) });
|
|
3148
|
+
}],
|
|
3149
|
+
[tableCellBlock, (node, cxt) => {
|
|
3150
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("td", { children: cxt.state.render(node.content, cxt) });
|
|
3151
|
+
}]
|
|
3152
|
+
];
|
|
3153
|
+
const TableInlineRenderers = [[tableCellInline, (node, cxt) => {
|
|
3154
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("td", { children: cxt.state.render(node.content, cxt) });
|
|
3155
|
+
}]];
|
|
3156
|
+
|
|
3157
|
+
//#endregion
|
|
3158
|
+
//#region src/default/gallery.tsx
|
|
3159
|
+
const GalleryBlock = new BlockModifierDefinition("gallery", ModifierSlotType.Normal, {});
|
|
3160
|
+
const GalleryBlockRendererHTML = [GalleryBlock, (node, cxt) => {
|
|
3161
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("ul", {
|
|
3162
|
+
class: "gallery",
|
|
3163
|
+
children: (node.content[0].type == NodeType.Group && node.content.length == 1 ? node.content[0].content : node.content).map((x) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("li", { children: cxt.state.render([x], cxt) }))
|
|
3164
|
+
});
|
|
3165
|
+
}];
|
|
3166
|
+
|
|
3167
|
+
//#endregion
|
|
3168
|
+
//#region src/default/default.ts
|
|
3169
|
+
let config = Configuration.from(BuiltinConfiguration);
|
|
3170
|
+
config.initializers.push(initNotes, initHeadings, initTable);
|
|
3171
|
+
config.blockModifiers.add(...HeadingBlocks, ...BulletBlocks, CodeBlock, ...QuoteBlocks, ...MiscBlocks, ...NoteBlocks, ...TableBlocks, GalleryBlock);
|
|
3172
|
+
config.inlineModifiers.add(CodeInline, ...InlineStyles, ...MiscInlines, ...NoteInlines, ...TableInlines);
|
|
3173
|
+
config.systemModifiers.add(...NoteSystems);
|
|
3174
|
+
const DefaultConfiguration = Object.freeze(config);
|
|
3175
|
+
|
|
3176
|
+
//#endregion
|
|
3177
|
+
//#region src/default/html-renderer.tsx
|
|
3178
|
+
var HTMLRenderState = class {
|
|
3179
|
+
title = "";
|
|
3180
|
+
stylesheet = "";
|
|
3181
|
+
cssVariables = /* @__PURE__ */ new Map();
|
|
3182
|
+
invalidBlock(node, msg) {
|
|
3183
|
+
let name = NodeType[node.type];
|
|
3184
|
+
if (node.type === NodeType.BlockModifier) name += ` (${node.mod.name})`;
|
|
3185
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("details", {
|
|
3186
|
+
class: "invalid",
|
|
3187
|
+
children: [
|
|
3188
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("summary", { children: ["Invalid ", name] }),
|
|
3189
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("i", { children: msg }),
|
|
3190
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("pre", { children: debugPrint.node(node) })
|
|
3191
|
+
]
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
invalidInline(node, msg) {
|
|
3195
|
+
let name = NodeType[node.type];
|
|
3196
|
+
if (node.type === NodeType.InlineModifier) name += ` (${node.mod.name})`;
|
|
3197
|
+
return /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("details", {
|
|
3198
|
+
class: "invalid",
|
|
3199
|
+
children: [
|
|
3200
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("summary", { children: ["Invalid ", name] }),
|
|
3201
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("i", { children: msg }),
|
|
3202
|
+
/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("pre", { children: debugPrint.node(node) })
|
|
3203
|
+
]
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
3206
|
+
render(elems, cxt) {
|
|
3207
|
+
const document$1 = cxt.config.options.document;
|
|
3208
|
+
(0, minimal_jsx_runtime_jsx_runtime.useDocument)(document$1);
|
|
3209
|
+
let fragment = document$1.createDocumentFragment();
|
|
3210
|
+
elems.flatMap((x) => cxt.renderEntity(x)).flat().forEach((x) => fragment.appendChild(x));
|
|
3211
|
+
return fragment;
|
|
3212
|
+
}
|
|
3213
|
+
};
|
|
3214
|
+
const htmlConfig = new RenderConfiguration({
|
|
3215
|
+
document: globalThis.window.document,
|
|
3216
|
+
headPlugins: [],
|
|
3217
|
+
headerPlugins: [],
|
|
3218
|
+
footerPlugins: [NotesFooterPlugin],
|
|
3219
|
+
postprocessPlugins: [],
|
|
3220
|
+
transformAsset: () => void 0
|
|
3221
|
+
}, (results, cxt) => {
|
|
3222
|
+
let styles = cxt.state.stylesheet.replaceAll(/var\(--(.*?)\)/g, (m, c) => cxt.state.cssVariables.get(c) ?? m);
|
|
3223
|
+
let doc = document.implementation.createHTMLDocument(cxt.state.title);
|
|
3224
|
+
doc.head.append(/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("meta", { charset: "UTF-8" }), /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("style", { children: styles }), ...cxt.config.options.headPlugins.map((x) => x(cxt)).filter((x) => x !== void 0).flat());
|
|
3225
|
+
doc.body.append(/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("section", {
|
|
3226
|
+
class: "article-container",
|
|
3227
|
+
children: /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsxs)("section", {
|
|
3228
|
+
class: "article-body",
|
|
3229
|
+
children: [
|
|
3230
|
+
cxt.config.options.headerPlugins.map((x) => x(cxt)).filter((x) => x !== void 0),
|
|
3231
|
+
results,
|
|
3232
|
+
cxt.config.options.footerPlugins.map((x) => x(cxt)).filter((x) => x !== void 0)
|
|
3233
|
+
]
|
|
3234
|
+
})
|
|
3235
|
+
}));
|
|
3236
|
+
for (const p of cxt.config.options.postprocessPlugins) p(cxt, doc);
|
|
3237
|
+
return doc;
|
|
3238
|
+
});
|
|
3239
|
+
htmlConfig.paragraphRenderer = (node, cxt) => /* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("p", { children: node.content.flatMap((x) => cxt.renderEntity(x)) });
|
|
3240
|
+
htmlConfig.textRenderer = (node, cxt) => {
|
|
3241
|
+
switch (node.type) {
|
|
3242
|
+
case NodeType.Preformatted: return new Text(node.content.text);
|
|
3243
|
+
case NodeType.Text:
|
|
3244
|
+
case NodeType.Escaped:
|
|
3245
|
+
const split = node.content.split("\n");
|
|
3246
|
+
const result = [];
|
|
3247
|
+
for (let i = 0; i < split.length; i++) {
|
|
3248
|
+
result.push(new Text(split[i]));
|
|
3249
|
+
if (i < split.length - 1) result.push(/* @__PURE__ */ (0, minimal_jsx_runtime_jsx_runtime.jsx)("br", {}));
|
|
3250
|
+
}
|
|
3251
|
+
return result;
|
|
3252
|
+
default: return debug.never(node);
|
|
3253
|
+
}
|
|
3254
|
+
};
|
|
3255
|
+
htmlConfig.undefinedBlockRenderer = (node, cxt) => {
|
|
3256
|
+
return cxt.state.invalidBlock(node, `No renderer defined! for ${node.mod.name}`);
|
|
3257
|
+
};
|
|
3258
|
+
htmlConfig.undefinedInlineRenderer = (node, cxt) => {
|
|
3259
|
+
return cxt.state.invalidInline(node, `No renderer defined! for ${node.mod.name}`);
|
|
3260
|
+
};
|
|
3261
|
+
htmlConfig.addBlockRenderer(...HeadingBlockRenderersHTML, ...BulletBlockRenderersHTML, CodeBlockRendererHTML, ...QuoteBlockRenderersHTML, ...MiscBlockRenderersHTML, ...NoteBlockRenderersHTML, ...TableBlockRenderers, GalleryBlockRendererHTML);
|
|
3262
|
+
htmlConfig.addInlineRenderer(CodeInlineRendererHTML, ...InlineStyleRenderersHTML, ...MiscInlineRenderersHTML, ...NoteInlineRenderersHTML, ...TableInlineRenderers);
|
|
3263
|
+
const HTMLRenderConfiguration = htmlConfig;
|
|
3264
|
+
|
|
3265
|
+
//#endregion
|
|
3266
|
+
//#region src/index.ts
|
|
3267
|
+
const emmmVersion = "0.0.6";
|
|
3268
|
+
function setDebugLevel(level) {
|
|
3269
|
+
debug.level = level;
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
//#endregion
|
|
3273
|
+
exports.ArgumentInterpolatorDefinition = ArgumentInterpolatorDefinition;
|
|
3274
|
+
exports.BlockModifierDefinition = BlockModifierDefinition;
|
|
3275
|
+
exports.BuiltinConfiguration = BuiltinConfiguration;
|
|
3276
|
+
exports.Configuration = Configuration;
|
|
3277
|
+
exports.DebugLevel = DebugLevel;
|
|
3278
|
+
exports.DefaultConfiguration = DefaultConfiguration;
|
|
3279
|
+
exports.Document = Document;
|
|
3280
|
+
exports.HTMLRenderConfiguration = HTMLRenderConfiguration;
|
|
3281
|
+
exports.HTMLRenderState = HTMLRenderState;
|
|
3282
|
+
exports.InlineModifierDefinition = InlineModifierDefinition;
|
|
3283
|
+
exports.MessageSeverity = MessageSeverity;
|
|
3284
|
+
exports.ModifierSlotType = ModifierSlotType;
|
|
3285
|
+
exports.NodeType = NodeType;
|
|
3286
|
+
exports.ParseContext = ParseContext;
|
|
3287
|
+
exports.Parser = Parser;
|
|
3288
|
+
exports.RenderConfiguration = RenderConfiguration;
|
|
3289
|
+
exports.RenderContext = RenderContext;
|
|
3290
|
+
exports.SimpleScanner = SimpleScanner;
|
|
3291
|
+
exports.StringSource = StringSource;
|
|
3292
|
+
exports.SystemModifierDefinition = SystemModifierDefinition;
|
|
3293
|
+
exports.cloneNode = cloneNode;
|
|
3294
|
+
exports.cloneNodes = cloneNodes;
|
|
3295
|
+
exports.debugPrint = debugPrint;
|
|
3296
|
+
exports.emmmVersion = emmmVersion;
|
|
3297
|
+
Object.defineProperty(exports, 'helper', {
|
|
3298
|
+
enumerable: true,
|
|
3299
|
+
get: function () {
|
|
3300
|
+
return modifier_helper_exports;
|
|
3301
|
+
}
|
|
3302
|
+
});
|
|
3303
|
+
Object.defineProperty(exports, 'messages', {
|
|
3304
|
+
enumerable: true,
|
|
3305
|
+
get: function () {
|
|
3306
|
+
return messages_exports;
|
|
3307
|
+
}
|
|
3308
|
+
});
|
|
3309
|
+
exports.setDebugLevel = setDebugLevel;
|
|
3310
|
+
exports.stripNode = stripNode;
|
|
3311
|
+
//# sourceMappingURL=index.cjs.map
|