@the_dissidents/libemmm 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -23,18 +23,19 @@ var NodeType = /* @__PURE__ */ ((NodeType2) => {
23
23
  NodeType2[NodeType2["Interpolation"] = 8] = "Interpolation";
24
24
  return NodeType2;
25
25
  })(NodeType || {});
26
- var ModifierFlags = /* @__PURE__ */ ((ModifierFlags2) => {
27
- ModifierFlags2[ModifierFlags2["Normal"] = 0] = "Normal";
28
- ModifierFlags2[ModifierFlags2["Preformatted"] = 1] = "Preformatted";
29
- ModifierFlags2[ModifierFlags2["Marker"] = 2] = "Marker";
30
- return ModifierFlags2;
31
- })(ModifierFlags || {});
26
+ var ModifierSlotType = /* @__PURE__ */ ((ModifierSlotType2) => {
27
+ ModifierSlotType2[ModifierSlotType2["Normal"] = 0] = "Normal";
28
+ ModifierSlotType2[ModifierSlotType2["Preformatted"] = 1] = "Preformatted";
29
+ ModifierSlotType2[ModifierSlotType2["None"] = 2] = "None";
30
+ return ModifierSlotType2;
31
+ })(ModifierSlotType || {});
32
32
  var ModifierBase = class {
33
- constructor(name, flags = 0 /* Normal */, args) {
33
+ constructor(name, slotType = 0 /* Normal */, args) {
34
34
  this.name = name;
35
- this.flags = flags;
35
+ this.slotType = slotType;
36
36
  if (args) Object.assign(this, args);
37
37
  }
38
+ roleHint;
38
39
  delayContentExpansion = false;
39
40
  alwaysTryExpand = false;
40
41
  beforeParseContent;
@@ -59,158 +60,433 @@ var ArgumentInterpolatorDefinition = class {
59
60
  alwaysTryExpand = false;
60
61
  expand;
61
62
  };
62
- var ParseContext = class {
63
- constructor(config, variables = /* @__PURE__ */ new Map()) {
64
- this.config = config;
65
- this.variables = variables;
66
- config.initializers.forEach((x) => x(this));
63
+
64
+ // src/util.ts
65
+ var NameManager = class _NameManager {
66
+ array = [];
67
+ data = /* @__PURE__ */ new Map();
68
+ constructor(from) {
69
+ if (from === void 0) return;
70
+ if (from instanceof _NameManager) {
71
+ this.array = [...from.array];
72
+ this.data = new Map(from.data);
73
+ } else {
74
+ const array = [...from];
75
+ assert((from instanceof Set ? from : new Set(array)).size == array.length);
76
+ this.array = array.map((x) => ({ k: x.name, v: x }));
77
+ this.array.sort((a, b) => b.k.length - a.k.length);
78
+ this.data = new Map(array.map((x) => [x.name, x]));
79
+ }
67
80
  }
68
- data = {};
69
- init(key, obj) {
70
- assert(!(key in this.data));
71
- this.data[key] = obj;
81
+ toArray() {
82
+ return this.array.map(({ v }) => v);
72
83
  }
73
- set(key, obj) {
74
- assert(key in this.data);
75
- this.data[key] = obj;
84
+ toSet() {
85
+ return new Set(this.toArray());
76
86
  }
77
- get(key) {
78
- assert(key in this.data);
79
- return this.data[key];
87
+ get(name) {
88
+ return this.data.get(name);
80
89
  }
81
- };
82
- var Document = class {
83
- constructor(root, context, messages) {
84
- this.root = root;
85
- this.context = context;
86
- this.messages = messages;
90
+ has(name) {
91
+ return this.data.has(name);
92
+ }
93
+ remove(name) {
94
+ let i = this.data.get(name);
95
+ assert(i !== void 0);
96
+ this.data.delete(name);
97
+ this.array.splice(this.array.findIndex((x) => x.k == name), 1);
98
+ }
99
+ add(...elems) {
100
+ for (const elem of elems) {
101
+ assert(!this.has(elem.name));
102
+ this.data.set(elem.name, elem);
103
+ const len = elem.name.length;
104
+ let i = 0;
105
+ while (i < this.array.length && this.array[i].k.length > len) i++;
106
+ this.array.splice(i, 0, { k: elem.name, v: elem });
107
+ }
87
108
  }
88
- debugPrint(source) {
89
- return debugDumpDocument(this, source);
109
+ find(predicate) {
110
+ const result = this.array.find((x) => predicate(x.v));
111
+ return result ? result.v : void 0;
90
112
  }
91
113
  };
92
- var Configuration = class {
93
- initializers = [];
94
- blockModifiers;
95
- inlineModifiers;
96
- systemModifiers;
97
- argumentInterpolators;
98
- reparseDepthLimit = 10;
99
- constructor(from) {
100
- this.blockModifiers = new NameManager(from?.blockModifiers);
101
- this.inlineModifiers = new NameManager(from?.inlineModifiers);
102
- this.systemModifiers = new NameManager(from?.systemModifiers);
103
- this.argumentInterpolators = new NameManager(from?.argumentInterpolators);
104
- if (from) {
105
- this.initializers = [...from.initializers];
106
- this.reparseDepthLimit = from.reparseDepthLimit;
114
+ function assert(x) {
115
+ if (!!!x) {
116
+ let error = new Error("assertion failed");
117
+ console.log(error.stack);
118
+ throw error;
119
+ }
120
+ }
121
+ function linePositions(src) {
122
+ let result = [0];
123
+ [...src].forEach((x, i) => {
124
+ if (x == "\n") result.push(i + 1);
125
+ });
126
+ result.push(Infinity);
127
+ return result;
128
+ }
129
+ var cloneArgument = (arg, options) => ({
130
+ location: clonePosition(arg.location, options),
131
+ content: arg.content.map((ent) => {
132
+ switch (ent.type) {
133
+ case 3 /* Text */:
134
+ case 4 /* Escaped */:
135
+ return structuredClone(ent);
136
+ case 8 /* Interpolation */:
137
+ return {
138
+ type: ent.type,
139
+ location: clonePosition(arg.location, options),
140
+ definition: ent.definition,
141
+ argument: cloneArgument(ent.argument, options),
142
+ expansion: ent.expansion
143
+ };
144
+ default:
145
+ return debug.never(ent);
146
+ }
147
+ })
148
+ });
149
+ function clonePosition(pos, options) {
150
+ let base = options.newLocation ?? pos;
151
+ return {
152
+ start: base.start,
153
+ end: base.end,
154
+ actualEnd: base.actualEnd,
155
+ original: options.newLocation ? pos : pos.original,
156
+ source: base.source
157
+ };
158
+ }
159
+ function cloneNode(node, options = {}) {
160
+ switch (node.type) {
161
+ case 7 /* BlockModifier */:
162
+ case 6 /* InlineModifier */:
163
+ case 5 /* SystemModifier */:
164
+ return {
165
+ location: clonePosition(node.location, options),
166
+ type: node.type,
167
+ mod: node.mod,
168
+ state: options.withState ? node.state : void 0,
169
+ head: structuredClone(node.head),
170
+ arguments: node.arguments.map((x) => cloneArgument(x, options)),
171
+ content: node.content.map((x) => cloneNode(x, options)),
172
+ expansion: node.expansion ? cloneNodes(node.expansion, options) : void 0
173
+ };
174
+ case 0 /* Root */:
175
+ return {
176
+ type: node.type,
177
+ source: node.source,
178
+ content: node.content.map((x) => cloneNode(x, options))
179
+ };
180
+ case 1 /* Paragraph */:
181
+ return {
182
+ type: node.type,
183
+ location: clonePosition(node.location, options),
184
+ content: node.content.map((x) => cloneNode(x, options))
185
+ };
186
+ case 2 /* Preformatted */:
187
+ case 3 /* Text */:
188
+ case 4 /* Escaped */:
189
+ return structuredClone(node);
190
+ default:
191
+ return debug.never(node);
192
+ }
193
+ }
194
+ function cloneNodes(nodes, options = {}) {
195
+ return nodes.map((x) => cloneNode(x, options));
196
+ }
197
+ function stripNode(...nodes) {
198
+ return nodes.flatMap((node) => {
199
+ switch (node.type) {
200
+ case 2 /* Preformatted */:
201
+ case 3 /* Text */:
202
+ case 4 /* Escaped */:
203
+ return [node];
204
+ case 7 /* BlockModifier */:
205
+ case 6 /* InlineModifier */:
206
+ if (node.expansion !== void 0)
207
+ return node.expansion.flatMap((x) => stripNode(x));
208
+ // else fallthrough!
209
+ case 1 /* Paragraph */:
210
+ case 0 /* Root */:
211
+ node.content = node.content.flatMap((x) => stripNode(x));
212
+ return [node];
213
+ case 5 /* SystemModifier */:
214
+ return [];
215
+ default:
216
+ return debug.never(node);
107
217
  }
218
+ });
219
+ }
220
+
221
+ // src/debug.ts
222
+ var DebugLevel = /* @__PURE__ */ ((DebugLevel3) => {
223
+ DebugLevel3[DebugLevel3["Trace"] = 0] = "Trace";
224
+ DebugLevel3[DebugLevel3["Info"] = 1] = "Info";
225
+ DebugLevel3[DebugLevel3["Warning"] = 2] = "Warning";
226
+ DebugLevel3[DebugLevel3["Error"] = 3] = "Error";
227
+ DebugLevel3[DebugLevel3["None"] = 4] = "None";
228
+ return DebugLevel3;
229
+ })(DebugLevel || {});
230
+ var debug = {
231
+ level: 1 /* Info */,
232
+ trace(arg0, ...args) {
233
+ if (this.level > 0 /* Trace */) return;
234
+ if (typeof arg0 == "function") arg0 = arg0();
235
+ console.info("TRACE", arg0, ...args);
236
+ },
237
+ info(arg0, ...args) {
238
+ if (this.level > 1 /* Info */) return;
239
+ if (typeof arg0 == "function") arg0 = arg0();
240
+ console.info(" INFO", arg0, ...args);
241
+ },
242
+ warning(arg0, ...args) {
243
+ if (this.level > 2 /* Warning */) return;
244
+ if (typeof arg0 == "function") arg0 = arg0();
245
+ console.warn(" WARN", arg0, ...args);
246
+ },
247
+ error(arg0, ...args) {
248
+ if (this.level > 3 /* Error */) return;
249
+ if (typeof arg0 == "function") arg0 = arg0();
250
+ console.error("ERROR", arg0, ...args);
251
+ },
252
+ never(_) {
253
+ assert(false);
254
+ }
255
+ };
256
+
257
+ // src/scanner.ts
258
+ var SimpleScanner = class {
259
+ constructor(src, source = { name: "<input>" }) {
260
+ this.src = src;
261
+ this.source = source;
262
+ }
263
+ pos = 0;
264
+ position() {
265
+ return this.pos;
266
+ }
267
+ isEOF() {
268
+ return this.pos >= this.src.length;
269
+ }
270
+ peek(str) {
271
+ assert(str !== "");
272
+ let next = this.pos + str.length;
273
+ if (next > this.src.length) return false;
274
+ return this.src.slice(this.pos, this.pos + str.length) == str;
275
+ }
276
+ acceptChar() {
277
+ if (this.isEOF()) throw new RangeError("EOF");
278
+ let char = this.src[this.pos];
279
+ this.pos++;
280
+ return char;
281
+ }
282
+ accept(str) {
283
+ if (!this.peek(str)) return false;
284
+ this.pos += str.length;
285
+ return true;
286
+ }
287
+ acceptWhitespaceChar() {
288
+ if (this.isEOF()) return null;
289
+ let char = this.src[this.pos];
290
+ if (!" ".includes(char)) return null;
291
+ this.pos++;
292
+ return char;
108
293
  }
109
294
  };
110
295
 
296
+ // src/debug-print.ts
297
+ var debugPrint = {
298
+ blockModifier: (x) => `[.${x.name}] (${ModifierSlotType[x.slotType]})`,
299
+ inlineModifier: (x) => `[/${x.name}] (${ModifierSlotType[x.slotType]})`,
300
+ inlineShorthand: (x) => x.name + x.parts.map((x2, i) => ` .. <arg${i}> .. ${x2}`).join("") + (x.mod.slotType == 2 /* None */ ? "" : ` .. <slot> .. ${x.postfix ?? "<no postfix>"}`),
301
+ blockShorthand: (x) => x.name + x.parts.map((x2, i) => ` .. <arg${i}> .. ${x2}`).join("") + (x.mod.slotType == 2 /* None */ ? "" : ` .. <slot> .. ${x.postfix ?? "<no postfix>"}`),
302
+ argument: (arg) => arg.content.map(debugPrintArgEntity).join(""),
303
+ node: (...nodes) => nodes.map((x) => debugPrintNode(x)).join("\n"),
304
+ message: (m, source, descriptor) => debugPrintMsg(m, descriptor, source),
305
+ document: debugDumpDocument
306
+ };
307
+ function debugPrintArgEntity(node) {
308
+ switch (node.type) {
309
+ case 3 /* Text */:
310
+ return node.content;
311
+ case 4 /* Escaped */:
312
+ return `<Escaped:${node.content}>`;
313
+ case 8 /* Interpolation */:
314
+ return `<Interp:${node.definition.name}-${node.definition.postfix}:${debugPrint.argument(node.argument)}${node.expansion ? `=${node.expansion}` : ""}>`;
315
+ default:
316
+ return debug.never(node);
317
+ }
318
+ }
319
+ function debugPrintNode(node, prefix = "") {
320
+ function debugPrintNodes(content, prefix2 = "") {
321
+ let dumps = content.map((x) => debugPrintNode(x, prefix2 + " ")).filter((x) => x.length > 0);
322
+ if (dumps.length == 0) return "";
323
+ return dumps.map((x) => `${prefix2} ${x}`).join("\n");
324
+ }
325
+ let result = `<${NodeType[node.type]}@${node.location.start}`;
326
+ switch (node.type) {
327
+ case 1 /* Paragraph */:
328
+ const content = debugPrintNodes(node.content, prefix);
329
+ if (content.length > 0)
330
+ result += `>
331
+ ${content}
332
+ ${prefix}</${NodeType[node.type]}@${node.location.end}>`;
333
+ else result += `-${node.location.end} />`;
334
+ break;
335
+ case 4 /* Escaped */:
336
+ result += `>
337
+ ${prefix} ${node.content}
338
+ ${prefix}</${NodeType[node.type]}@${node.location.end}>`;
339
+ break;
340
+ case 2 /* Preformatted */:
341
+ result += `>
342
+ ${prefix} ${node.content.text}
343
+ ${prefix}</${NodeType[node.type]}@${node.location.end}>`;
344
+ break;
345
+ case 6 /* InlineModifier */:
346
+ case 7 /* BlockModifier */:
347
+ case 5 /* SystemModifier */:
348
+ const args = node.arguments.map((x, i) => `
349
+ ${prefix} (${i})@${x.location.start}-${x.location.end}=${debugPrint.argument(x)}`).join("");
350
+ if (node.content.length > 0) {
351
+ result += ` id=${node.mod.name}${args}>
352
+ ` + debugPrintNodes(node.content, prefix) + `
353
+ ${prefix}</${NodeType[node.type]}@${node.location.end}>`;
354
+ } else result += `-${node.location.end} id=${node.mod.name}${args} />`;
355
+ if (node.expansion) {
356
+ const content2 = debugPrintNodes(node.expansion, prefix);
357
+ if (content2.length > 0)
358
+ result += `
359
+ ${prefix}<expansion>
360
+ ${content2}
361
+ ${prefix}</expansion>`;
362
+ else if (node.type != 5 /* SystemModifier */)
363
+ result += `
364
+ ${prefix}<expansion />`;
365
+ }
366
+ break;
367
+ case 3 /* Text */:
368
+ return node.content;
369
+ default:
370
+ return debug.never(node);
371
+ }
372
+ return result;
373
+ }
374
+ function debugPrintMsg(m, descriptor, source) {
375
+ let pos = (pos2) => `@${pos2}`;
376
+ if (source) {
377
+ const lines = linePositions(source);
378
+ pos = (pos2) => {
379
+ let line = -1, linepos = 0;
380
+ for (let i = 1; i < lines.length; i++) {
381
+ if (lines[i] > pos2) {
382
+ line = i;
383
+ linepos = lines[i - 1];
384
+ break;
385
+ }
386
+ }
387
+ return `l${line}c${pos2 - linepos + 1}`;
388
+ };
389
+ }
390
+ let loc = m.location;
391
+ let result = `at ${pos(loc.start)}-${pos(loc.end)}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
392
+ if (descriptor && m.location.source !== descriptor) {
393
+ result += `
394
+ warning: source descriptor mismatch: ${m.location.source.name}`;
395
+ }
396
+ while (loc = loc.original) {
397
+ let d = loc.source !== m.location.source ? `(in ${loc.source.name}) ` : "";
398
+ result += `
399
+ ---> original at: ${d}${pos(loc.start)}-${pos(loc.end)}`;
400
+ }
401
+ return result;
402
+ }
403
+ function debugDumpDocument(doc, source) {
404
+ let root = debugPrint.node(...doc.root.content);
405
+ let msgs = doc.messages.map((x) => debugPrintMsg(x, doc.root.source, source)).join("\n");
406
+ if (msgs.length > 0) msgs += "\n";
407
+ return `Document: ${doc.root.source.name}
408
+ ${msgs}${root}`;
409
+ }
410
+
111
411
  // src/messages.ts
112
412
  var messages_exports = {};
113
413
  __export(messages_exports, {
114
414
  ArgumentCountMismatchMessage: () => ArgumentCountMismatchMessage,
115
415
  CannotExpandArgumentMessage: () => CannotExpandArgumentMessage,
116
- CannotPopNotationMessage: () => CannotPopNotationMessage,
416
+ CannotUseModuleInSelfMessage: () => CannotUseModuleInSelfMessage,
117
417
  ContentShouldBeOnNewlineMessage: () => ContentShouldBeOnNewlineMessage,
418
+ EitherNormalOrPreMessage: () => EitherNormalOrPreMessage,
419
+ EntityNotAllowedMessage: () => EntityNotAllowedMessage,
118
420
  ExpectedMessage: () => ExpectedMessage,
119
- InlineDefinitonInvalidEntityMessage: () => InlineDefinitonInvalidEntityMessage,
120
421
  InvalidArgumentMessage: () => InvalidArgumentMessage,
422
+ MultipleBlocksNotPermittedMessage: () => MultipleBlocksNotPermittedMessage,
121
423
  NameAlreadyDefinedMessage: () => NameAlreadyDefinedMessage,
122
424
  NewBlockShouldBeOnNewlineMessage: () => NewBlockShouldBeOnNewlineMessage,
425
+ NoNestedModuleMessage: () => NoNestedModuleMessage,
426
+ OnlySimpleParagraphsPermittedMessage: () => OnlySimpleParagraphsPermittedMessage,
427
+ OverwriteDefinitionsMessage: () => OverwriteDefinitionsMessage,
123
428
  ReachedRecursionLimitMessage: () => ReachedRecursionLimitMessage,
124
- ReferredMessage: () => ReferredMessage,
125
429
  SlotUsedOutsideDefinitionMessage: () => SlotUsedOutsideDefinitionMessage,
126
430
  UnclosedInlineModifierMessage: () => UnclosedInlineModifierMessage,
127
431
  UndefinedVariableMessage: () => UndefinedVariableMessage,
128
432
  UnknownModifierMessage: () => UnknownModifierMessage,
129
433
  UnnecessaryNewlineMessage: () => UnnecessaryNewlineMessage
130
434
  });
131
- var ReferredMessage = class {
132
- constructor(original, position, length) {
133
- this.original = original;
134
- this.position = position;
135
- this.length = length;
136
- }
137
- get severity() {
138
- return this.original.severity;
139
- }
140
- get info() {
141
- return this.original.info;
142
- }
143
- get code() {
144
- return this.original.code;
145
- }
146
- fixes = [];
147
- };
148
435
  var AddThingMessage = class {
149
- constructor(code, severity, position, length, info, fixstr, what) {
436
+ constructor(code, severity, location, info) {
150
437
  this.code = code;
151
438
  this.severity = severity;
152
- this.position = position;
153
- this.length = length;
439
+ this.location = location;
154
440
  this.info = info;
155
- this.fixstr = fixstr;
156
- this.what = what;
157
- }
158
- get fixes() {
159
- let [pos, what, fixstr] = [this.position, this.what, this.fixstr];
160
- return [{
161
- get info() {
162
- return fixstr;
163
- },
164
- apply(src, cursor) {
165
- let newCursor = cursor < pos ? cursor : cursor + what.length;
166
- return [src.substring(0, pos) + what + src.substring(pos), newCursor];
167
- }
168
- }];
169
441
  }
442
+ // get fixes(): readonly FixSuggestion[] {
443
+ // let [start, what, fixstr] = [this.location.start, this.what, this.fixstr];
444
+ // return [{
445
+ // get info() { return fixstr; },
446
+ // apply(src: string, cursor: number) {
447
+ // let newCursor = (cursor < start)
448
+ // ? cursor
449
+ // : cursor + what.length;
450
+ // return [src.substring(0, start) + what + src.substring(start), newCursor];
451
+ // }
452
+ // }];
453
+ // }
170
454
  };
171
455
  var RemoveThingMessage = class {
172
- constructor(code, severity, position, length, info, fixstr) {
456
+ constructor(code, severity, location, info) {
173
457
  this.code = code;
174
458
  this.severity = severity;
175
- this.position = position;
176
- this.length = length;
459
+ this.location = location;
177
460
  this.info = info;
178
- this.fixstr = fixstr;
179
- }
180
- get fixes() {
181
- let [pos, len, fixstr] = [this.position, this.length, this.fixstr];
182
- return [{
183
- get info() {
184
- return fixstr;
185
- },
186
- apply(src, cursor) {
187
- let newCursor = cursor < pos + len && cursor >= pos ? pos : cursor - len;
188
- return [src.substring(0, pos) + src.substring(pos + len), newCursor];
189
- }
190
- }];
191
461
  }
462
+ // get fixes(): readonly FixSuggestion[] {
463
+ // let [start, end, fixstr] = [this.start, this.end, this.fixstr];
464
+ // return [{
465
+ // get info() { return fixstr; },
466
+ // apply(src: string, cursor: number) {
467
+ // let newCursor = (cursor < end && cursor >= start)
468
+ // ? start
469
+ // : cursor; // Removing text, cursor shouldn't shift if it's outside the removed range
470
+ // return [src.substring(0, start) + src.substring(end), newCursor];
471
+ // }
472
+ // }];
473
+ // }
192
474
  };
193
475
  var ExpectedMessage = class {
194
- constructor(position, what) {
195
- this.position = position;
476
+ constructor(location, what) {
477
+ this.location = location;
196
478
  this.what = what;
479
+ assert(location.end == location.start);
197
480
  }
198
481
  code = 1;
199
482
  severity = 2 /* Error */;
200
- get length() {
201
- return 0;
202
- }
203
483
  get info() {
204
484
  return `expected '${this.what}'`;
205
485
  }
206
- get fixes() {
207
- return [];
208
- }
209
486
  };
210
487
  var UnknownModifierMessage = class {
211
- constructor(position, length, what) {
212
- this.position = position;
213
- this.length = length;
488
+ constructor(location, what) {
489
+ this.location = location;
214
490
  this.what = what;
215
491
  }
216
492
  code = 2;
@@ -218,36 +494,34 @@ var UnknownModifierMessage = class {
218
494
  get info() {
219
495
  return `unknown modifier '${this.what}'; did you forget to escape it?`;
220
496
  }
221
- get fixes() {
222
- let [pos, len] = [this.position, this.length];
223
- return [{
224
- get info() {
225
- return "this is not a modifier -- escape it";
226
- },
227
- apply(src, cursor) {
228
- let newCursor = cursor < pos ? cursor : cursor + 1;
229
- return [src.substring(0, pos) + "\\" + src.substring(pos), newCursor];
230
- }
231
- }];
232
- }
497
+ // get fixes(): readonly FixSuggestion[] {
498
+ // let [start, end] = [this.start, this.end];
499
+ // return [{
500
+ // get info() { return 'this is not a modifier -- escape it'; },
501
+ // apply(src: string, cursor: number) {
502
+ // let newCursor = (cursor < start)
503
+ // ? cursor
504
+ // : cursor + 1;
505
+ // return [src.substring(0, start) + '\\' + src.substring(start), newCursor];
506
+ // }
507
+ // }];
508
+ // }
233
509
  };
234
510
  var UnclosedInlineModifierMessage = class {
235
- constructor(position, what) {
236
- this.position = position;
511
+ constructor(location, what) {
512
+ this.location = location;
237
513
  this.what = what;
514
+ assert(location.end == location.start);
238
515
  }
239
516
  code = 3;
240
517
  severity = 2 /* Error */;
241
- length = 0;
242
- fixes = [];
243
518
  get info() {
244
519
  return `unclosed inline modifier ${this.what}'`;
245
520
  }
246
521
  };
247
522
  var ArgumentCountMismatchMessage = class {
248
- constructor(position, length, min, max) {
249
- this.position = position;
250
- this.length = length;
523
+ constructor(location, min, max) {
524
+ this.location = location;
251
525
  if (min !== void 0) {
252
526
  if (max == min) this.msg = `: ${min} expected`;
253
527
  else if (max !== void 0) this.msg = `: ${min} to ${max} expected`;
@@ -259,449 +533,235 @@ var ArgumentCountMismatchMessage = class {
259
533
  msg = "";
260
534
  code = 4;
261
535
  severity = 2 /* Error */;
262
- fixes = [];
263
536
  get info() {
264
537
  return `argument count mismatch` + this.msg;
265
538
  }
266
539
  };
267
540
  var CannotExpandArgumentMessage = class {
268
- constructor(position, length, what) {
269
- this.position = position;
270
- this.length = length;
541
+ constructor(location, what) {
542
+ this.location = location;
271
543
  this.what = what;
272
544
  }
273
545
  code = 5;
274
546
  severity = 2 /* Error */;
275
- fixes = [];
276
547
  get info() {
277
548
  return `failed to expand argument` + (this.what === void 0 ? "" : `: ${this.what}`);
278
549
  }
279
550
  };
280
551
  var InvalidArgumentMessage = class {
281
- constructor(position, length, what) {
282
- this.position = position;
283
- this.length = length;
552
+ constructor(location, what) {
553
+ this.location = location;
284
554
  this.what = what;
285
555
  }
286
556
  code = 6;
287
557
  severity = 2 /* Error */;
288
- fixes = [];
289
558
  get info() {
290
559
  return `invalid argument` + (this.what === void 0 ? "" : `: ${this.what}`);
291
560
  }
292
561
  };
293
- var InlineDefinitonInvalidEntityMessage = class {
294
- constructor(position, length) {
295
- this.position = position;
296
- this.length = length;
562
+ var EntityNotAllowedMessage = class {
563
+ constructor(location, what) {
564
+ this.location = location;
565
+ this.what = what;
297
566
  }
298
567
  code = 7;
299
568
  severity = 2 /* Error */;
300
- fixes = [];
301
569
  get info() {
302
- return `Invalid entity in inline modifier definition`;
570
+ return "This entity is not allowed here" + (this.what ? `: ${this.what}` : "");
303
571
  }
304
572
  };
305
573
  var ReachedRecursionLimitMessage = class {
306
- constructor(position, length, limit, what) {
307
- this.position = position;
308
- this.length = length;
574
+ constructor(location, limit, what) {
575
+ this.location = location;
309
576
  this.limit = limit;
310
577
  this.what = what;
311
578
  }
312
579
  code = 8;
313
580
  severity = 2 /* Error */;
314
- fixes = [];
315
581
  get info() {
316
582
  return `Reached recursion limit ${this.limit} when expanding ${this.what}`;
317
583
  }
318
584
  };
319
585
  var SlotUsedOutsideDefinitionMessage = class {
320
- constructor(position, length) {
321
- this.position = position;
322
- this.length = length;
586
+ constructor(location) {
587
+ this.location = location;
323
588
  }
324
589
  code = 9;
325
590
  severity = 2 /* Error */;
326
- fixes = [];
327
591
  get info() {
328
592
  return `slot used outside a definition`;
329
593
  }
330
594
  };
331
- var CannotPopNotationMessage = class {
332
- constructor(position, length) {
333
- this.position = position;
334
- this.length = length;
595
+ var NoNestedModuleMessage = class {
596
+ constructor(location) {
597
+ this.location = location;
335
598
  }
336
599
  code = 10;
337
600
  severity = 2 /* Error */;
338
- fixes = [];
339
601
  get info() {
340
- return `cannot pop notation`;
602
+ return `nested module definitions not allowed`;
603
+ }
604
+ };
605
+ var CannotUseModuleInSelfMessage = class {
606
+ constructor(location) {
607
+ this.location = location;
608
+ }
609
+ code = 11;
610
+ severity = 2 /* Error */;
611
+ get info() {
612
+ return `cannot use the same module inside its definition`;
613
+ }
614
+ };
615
+ var EitherNormalOrPreMessage = class {
616
+ constructor(location) {
617
+ this.location = location;
618
+ }
619
+ code = 12;
620
+ severity = 2 /* Error */;
621
+ get info() {
622
+ return `a definition cannot be at once normal and preformatted`;
623
+ }
624
+ };
625
+ var MultipleBlocksNotPermittedMessage = class {
626
+ constructor(location) {
627
+ this.location = location;
628
+ }
629
+ code = 13;
630
+ severity = 2 /* Error */;
631
+ get info() {
632
+ return `multiple blocks are not permitted here`;
633
+ }
634
+ };
635
+ var OnlySimpleParagraphsPermittedMessage = class {
636
+ constructor(location) {
637
+ this.location = location;
638
+ }
639
+ code = 14;
640
+ severity = 2 /* Error */;
641
+ get info() {
642
+ return `Only simple paragraphs are permitted here`;
341
643
  }
342
644
  };
343
645
  var UnnecessaryNewlineMessage = class extends RemoveThingMessage {
344
- constructor(pos, len) {
646
+ constructor(location) {
345
647
  super(
346
648
  1,
347
649
  1 /* Warning */,
348
- pos,
349
- len,
350
- "more than one newlines have the same effect as one",
351
- "remove the redundant newlines"
650
+ location,
651
+ "more than one newlines have the same effect as one"
352
652
  );
353
653
  }
354
654
  };
355
655
  var NewBlockShouldBeOnNewlineMessage = class extends AddThingMessage {
356
- constructor(pos) {
656
+ constructor(location) {
357
657
  super(
358
658
  2,
359
659
  1 /* Warning */,
360
- pos,
361
- 0,
362
- "a new block should begin in a new line to avoid confusion",
363
- "add a line break",
364
- "\n"
660
+ location,
661
+ "a new block should begin in a new line to avoid confusion"
365
662
  );
366
663
  }
367
664
  };
368
665
  var ContentShouldBeOnNewlineMessage = class extends AddThingMessage {
369
- constructor(pos) {
666
+ constructor(location) {
370
667
  super(
371
668
  3,
372
669
  1 /* Warning */,
373
- pos,
374
- 0,
375
- "the content should begin in a new line to avoid confusion",
376
- "add a line break",
377
- "\n"
670
+ location,
671
+ "the content should begin in a new line to avoid confusion"
378
672
  );
379
673
  }
380
674
  };
381
675
  var NameAlreadyDefinedMessage = class {
382
- constructor(position, length, what) {
383
- this.position = position;
384
- this.length = length;
676
+ constructor(location, what) {
677
+ this.location = location;
385
678
  this.what = what;
386
679
  }
387
680
  code = 4;
388
681
  severity = 1 /* Warning */;
389
- fixes = [];
390
682
  get info() {
391
683
  return `name is already defined, will overwrite: ${this.what}`;
392
684
  }
393
685
  };
394
686
  var UndefinedVariableMessage = class {
395
- constructor(position, length, what) {
396
- this.position = position;
397
- this.length = length;
687
+ constructor(location, what) {
688
+ this.location = location;
398
689
  this.what = what;
399
690
  }
400
691
  code = 5;
401
692
  severity = 1 /* Warning */;
402
- fixes = [];
403
693
  get info() {
404
694
  return `variable is undefined, will expand to empty string: ${this.what}`;
405
695
  }
406
696
  };
407
-
408
- // src/util.ts
409
- var NameManager = class _NameManager {
410
- array = [];
411
- data = /* @__PURE__ */ new Map();
412
- constructor(from) {
413
- if (from === void 0) return;
414
- if (from instanceof _NameManager) {
415
- this.array = [...from.array];
416
- this.data = new Map(from.data);
417
- } else {
418
- assert(Array.isArray(from));
419
- this.array = from.map((x) => ({ k: x.name, v: x }));
420
- this.array.sort((a, b) => b.k.length - a.k.length);
421
- this.data = new Map(from.map((x) => [x.name, x]));
422
- }
423
- }
424
- toArray() {
425
- return this.array.map(({ v }) => v);
426
- }
427
- get(name) {
428
- return this.data.get(name);
429
- }
430
- has(name) {
431
- return this.data.has(name);
432
- }
433
- remove(name) {
434
- let i = this.data.get(name);
435
- assert(i !== void 0);
436
- this.data.delete(name);
437
- this.array.splice(this.array.findIndex((x) => x.k == name), 1);
438
- }
439
- add(...elems) {
440
- for (const elem of elems) {
441
- assert(!this.has(elem.name));
442
- this.data.set(elem.name, elem);
443
- const len = elem.name.length;
444
- let i = 0;
445
- while (i < this.array.length && this.array[i].k.length > len) i++;
446
- this.array.splice(i, 0, { k: elem.name, v: elem });
447
- }
448
- }
449
- find(predicate) {
450
- const result = this.array.find((x) => predicate(x.v));
451
- return result ? result.v : void 0;
452
- }
453
- };
454
- function assert(x) {
455
- if (!!!x) {
456
- let error = new Error("assertion failed");
457
- console.log(error.stack);
458
- throw error;
459
- }
460
- }
461
- function has(v, f) {
462
- return (v & f) === f;
463
- }
464
- function linePositions(src) {
465
- let result = [0];
466
- [...src].forEach((x, i) => {
467
- if (x == "\n") result.push(i + 1);
468
- });
469
- result.push(Infinity);
470
- return result;
471
- }
472
- var cloneArgument = (arg) => ({
473
- start: arg.start,
474
- end: arg.end,
475
- content: arg.content.map((ent) => {
476
- switch (ent.type) {
477
- case 3 /* Text */:
478
- case 4 /* Escaped */:
479
- return structuredClone(ent);
480
- case 8 /* Interpolation */:
481
- return {
482
- type: ent.type,
483
- start: ent.start,
484
- end: ent.end,
485
- definition: ent.definition,
486
- argument: cloneArgument(ent.argument),
487
- expansion: ent.expansion
488
- };
489
- default:
490
- return debug.never(ent);
491
- }
492
- })
493
- });
494
- function cloneNode(node, referring) {
495
- switch (node.type) {
496
- case 7 /* BlockModifier */:
497
- case 6 /* InlineModifier */:
498
- case 5 /* SystemModifier */:
499
- return {
500
- start: node.start,
501
- end: node.end,
502
- type: node.type,
503
- mod: node.mod,
504
- state: void 0,
505
- head: structuredClone(node.head),
506
- arguments: node.arguments.map(cloneArgument),
507
- content: node.content.map((x) => cloneNode(x, referring)),
508
- expansion: node.expansion ? cloneNodes(node.expansion) : void 0
509
- };
510
- case 0 /* Root */:
511
- case 1 /* Paragraph */:
512
- return {
513
- type: node.type,
514
- start: node.start,
515
- end: node.end,
516
- content: node.content.map((x) => cloneNode(x))
517
- };
518
- case 2 /* Preformatted */:
519
- case 3 /* Text */:
520
- case 4 /* Escaped */:
521
- return structuredClone(node);
522
- default:
523
- return debug.never(node);
524
- }
525
- }
526
- function cloneNodes(nodes) {
527
- return nodes.map((x) => cloneNode(x));
528
- }
529
- function debugPrintArgEntity(node) {
530
- switch (node.type) {
531
- case 3 /* Text */:
532
- return node.content;
533
- case 4 /* Escaped */:
534
- return `<Escaped:${node.content}>`;
535
- case 8 /* Interpolation */:
536
- return `<Interp:${node.definition.name}-${node.definition.postfix}:${debugPrintArgument(node.argument)}${node.expansion ? `=${node.expansion}` : ""}>`;
537
- default:
538
- return debug.never(node);
539
- }
540
- }
541
- function debugPrintArgument(arg) {
542
- return arg.content.map(debugPrintArgEntity).join("");
543
- }
544
- function debugPrintNode(node, prefix = "") {
545
- let result = `<${NodeType[node.type]}@${node.start}`;
546
- switch (node.type) {
547
- case 0 /* Root */:
548
- case 1 /* Paragraph */:
549
- const content = debugPrintNodes(node.content, prefix);
550
- if (content.length > 0)
551
- result += `>
552
- ${content}
553
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
554
- else result += `-${node.end} />`;
555
- break;
556
- case 4 /* Escaped */:
557
- case 2 /* Preformatted */:
558
- result += `>
559
- ${prefix} ${node.content}
560
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
561
- break;
562
- case 6 /* InlineModifier */:
563
- case 7 /* BlockModifier */:
564
- case 5 /* SystemModifier */:
565
- const args = node.arguments.map((x, i) => `
566
- ${prefix} (${i})@${x.start}-${x.end}=${debugPrintArgument(x)}`).join("");
567
- if (node.content.length > 0) {
568
- result += ` id=${node.mod.name}${args}>
569
- ` + debugPrintNodes(node.content, prefix) + `
570
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
571
- } else result += `-${node.end} id=${node.mod.name}${args} />`;
572
- if (node.expansion) {
573
- const content2 = debugPrintNodes(node.expansion, prefix);
574
- if (content2.length > 0)
575
- result += `
576
- ${prefix}<expansion>
577
- ${content2}
578
- ${prefix}</expansion>`;
579
- else if (node.type != 5 /* SystemModifier */)
580
- result += `
581
- ${prefix}<expansion />`;
582
- }
583
- break;
584
- case 3 /* Text */:
585
- return node.content;
586
- default:
587
- return debug.never(node);
588
- }
589
- return result;
590
- }
591
- function debugPrintNodes(content, prefix = "") {
592
- let dumps = content.map((x) => debugPrintNode(x, prefix + " ")).filter((x) => x.length > 0);
593
- if (dumps.length == 0) return "";
594
- return dumps.map((x) => `${prefix} ${x}`).join("\n");
595
- }
596
- function debugDumpDocument(doc, source) {
597
- const lines = linePositions(source);
598
- function pos2lc(pos) {
599
- let line = -1, linepos = 0;
600
- for (let i = 1; i < lines.length; i++) {
601
- if (lines[i] > pos) {
602
- line = i;
603
- linepos = lines[i - 1];
604
- break;
605
- }
606
- }
607
- return `l${line}c${pos - linepos + 1}`;
608
- }
609
- function dumpMsg(m) {
610
- let result = `at ${pos2lc(m.position)}, len ${m.length}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
611
- while (m instanceof ReferredMessage) {
612
- m = m.original;
613
- result += `
614
- ---> original at: ${pos2lc(m.position)}, len ${m.length}`;
615
- }
616
- return result;
697
+ var OverwriteDefinitionsMessage = class {
698
+ constructor(location, what) {
699
+ this.location = location;
700
+ this.what = what;
617
701
  }
618
- let root = debugPrintNode(doc.root);
619
- let msgs = doc.messages.map(dumpMsg).join("\n");
620
- if (msgs.length > 0) msgs += "\n";
621
- return `${msgs}${root}`;
622
- }
623
-
624
- // src/debug.ts
625
- var DebugLevel = /* @__PURE__ */ ((DebugLevel3) => {
626
- DebugLevel3[DebugLevel3["Trace"] = 0] = "Trace";
627
- DebugLevel3[DebugLevel3["Info"] = 1] = "Info";
628
- DebugLevel3[DebugLevel3["Warning"] = 2] = "Warning";
629
- DebugLevel3[DebugLevel3["Error"] = 3] = "Error";
630
- DebugLevel3[DebugLevel3["None"] = 4] = "None";
631
- return DebugLevel3;
632
- })(DebugLevel || {});
633
- var debug = {
634
- level: 1 /* Info */,
635
- trace(arg0, ...args) {
636
- if (this.level > 0 /* Trace */) return;
637
- if (typeof arg0 == "function") arg0 = arg0();
638
- console.info("TRACE", arg0, ...args);
639
- },
640
- info(arg0, ...args) {
641
- if (this.level > 1 /* Info */) return;
642
- if (typeof arg0 == "function") arg0 = arg0();
643
- console.info(" INFO", arg0, ...args);
644
- },
645
- warning(arg0, ...args) {
646
- if (this.level > 2 /* Warning */) return;
647
- if (typeof arg0 == "function") arg0 = arg0();
648
- console.warn(" WARN", arg0, ...args);
649
- },
650
- error(arg0, ...args) {
651
- if (this.level > 3 /* Error */) return;
652
- if (typeof arg0 == "function") arg0 = arg0();
653
- console.error("ERROR", arg0, ...args);
654
- },
655
- never(_) {
656
- assert(false);
702
+ code = 6;
703
+ severity = 1 /* Warning */;
704
+ get info() {
705
+ return `using this module will overwrite: ${this.what}`;
657
706
  }
658
707
  };
659
708
 
660
- // src/front.ts
661
- var SimpleScanner = class {
662
- constructor(src) {
663
- this.src = src;
664
- }
665
- pos = 0;
666
- position() {
667
- return this.pos;
668
- }
669
- isEOF() {
670
- return this.pos >= this.src.length;
709
+ // src/parser-config.ts
710
+ var ParseContext = class {
711
+ constructor(config2, variables = /* @__PURE__ */ new Map()) {
712
+ this.config = config2;
713
+ this.variables = variables;
714
+ config2.initializers.forEach((x) => x(this));
671
715
  }
672
- peek(str) {
673
- let next = this.pos + str.length;
674
- if (next > this.src.length) return false;
675
- return this.src.slice(this.pos, this.pos + str.length) == str;
716
+ data = {};
717
+ init(key, obj) {
718
+ assert(!(key in this.data));
719
+ this.data[key] = obj;
676
720
  }
677
- acceptChar() {
678
- if (this.isEOF()) throw new RangeError("EOF");
679
- let char = this.src[this.pos];
680
- this.pos++;
681
- return char;
721
+ set(key, obj) {
722
+ assert(key in this.data);
723
+ this.data[key] = obj;
682
724
  }
683
- accept(str) {
684
- if (!this.peek(str)) return false;
685
- this.pos += str.length;
686
- return true;
725
+ get(key) {
726
+ assert(key in this.data);
727
+ return this.data[key];
687
728
  }
688
- acceptWhitespaceChar() {
689
- if (this.isEOF()) return null;
690
- let char = this.src[this.pos];
691
- if (!" ".includes(char)) return null;
692
- this.pos++;
693
- return char;
729
+ };
730
+ var Document = class _Document {
731
+ constructor(root, context, messages) {
732
+ this.root = root;
733
+ this.context = context;
734
+ this.messages = messages;
694
735
  }
695
- acceptUntil(str) {
696
- let start = this.pos;
697
- while (!this.isEOF()) {
698
- if (this.peek(str)) {
699
- let result = this.src.slice(start, this.pos);
700
- return result;
701
- }
702
- this.pos++;
703
- }
704
- return null;
736
+ toStripped() {
737
+ let doc = new _Document(
738
+ stripNode(cloneNode(this.root, { withState: true }))[0],
739
+ this.context,
740
+ this.messages
741
+ );
742
+ return doc;
743
+ }
744
+ };
745
+ var Configuration = class _Configuration {
746
+ initializers = [];
747
+ blockModifiers = new NameManager();
748
+ inlineModifiers = new NameManager();
749
+ systemModifiers = new NameManager();
750
+ argumentInterpolators = new NameManager();
751
+ blockShorthands = new NameManager();
752
+ inlineShorthands = new NameManager();
753
+ reparseDepthLimit = 10;
754
+ static from(from) {
755
+ let config2 = new _Configuration();
756
+ config2.initializers = [...from.initializers];
757
+ config2.reparseDepthLimit = from.reparseDepthLimit;
758
+ config2.blockModifiers = new NameManager(from.blockModifiers);
759
+ config2.inlineModifiers = new NameManager(from.inlineModifiers);
760
+ config2.systemModifiers = new NameManager(from.systemModifiers);
761
+ config2.argumentInterpolators = new NameManager(from.argumentInterpolators);
762
+ config2.blockShorthands = new NameManager(from.blockShorthands);
763
+ config2.inlineShorthands = new NameManager(from.inlineShorthands);
764
+ return config2;
705
765
  }
706
766
  };
707
767
 
@@ -722,31 +782,20 @@ var UnknownModifier = {
722
782
  var EmitEnvironment = class {
723
783
  constructor(scanner) {
724
784
  this.scanner = scanner;
785
+ this.root = { type: 0 /* Root */, source: scanner.source, content: [] };
725
786
  }
726
- root = { type: 0 /* Root */, start: 0, end: -1, content: [] };
787
+ root;
727
788
  messages = [];
728
- blockStack = [this.root];
789
+ blockStack = [];
729
790
  inlineStack = [];
730
- referringStack = [];
731
791
  message(...m) {
732
- const referringReverse = [...this.referringStack].reverse();
733
792
  for (let msg of m) {
734
- for (const range of referringReverse)
735
- msg = new ReferredMessage(msg, range.start, range.end - range.start);
736
793
  this.messages.push(msg);
737
794
  debug.trace("issued msg", msg.code, msg.info);
738
795
  }
739
796
  }
740
- pushReferring(start, end) {
741
- this.referringStack.push({ start, end });
742
- }
743
- popReferring() {
744
- assert(this.referringStack.length > 0);
745
- this.referringStack.pop();
746
- }
747
797
  addBlockNode(n) {
748
- assert(this.blockStack.length > 0);
749
- this.blockStack.at(-1).content.push(n);
798
+ (this.blockStack.at(-1) ?? this.root).content.push(n);
750
799
  return n;
751
800
  }
752
801
  addInlineNode(n) {
@@ -760,11 +809,14 @@ var EmitEnvironment = class {
760
809
  const last = content.at(-1);
761
810
  if (last?.type == 3 /* Text */) {
762
811
  last.content += str;
763
- last.end = this.scanner.position();
812
+ last.location.end = this.scanner.position();
764
813
  } else content.push({
765
814
  type: 3 /* Text */,
766
- start: this.scanner.position() - str.length,
767
- end: this.scanner.position(),
815
+ location: {
816
+ source: this.scanner.source,
817
+ start: this.scanner.position() - str.length,
818
+ end: this.scanner.position()
819
+ },
768
820
  content: str
769
821
  });
770
822
  }
@@ -773,9 +825,9 @@ var EmitEnvironment = class {
773
825
  this.blockStack.push(block);
774
826
  }
775
827
  endBlock() {
776
- assert(this.blockStack.length >= 2);
828
+ assert(this.blockStack.length > 0);
777
829
  const node = this.blockStack.pop();
778
- node.end = this.scanner.position();
830
+ node.location.end = this.scanner.position();
779
831
  }
780
832
  startInline(n) {
781
833
  if (n.type == 1 /* Paragraph */) this.addBlockNode(n);
@@ -785,19 +837,32 @@ var EmitEnvironment = class {
785
837
  endInline() {
786
838
  assert(this.inlineStack.length > 0);
787
839
  const node = this.inlineStack.pop();
788
- node.end = this.scanner.position();
840
+ node.location.end = this.scanner.position();
789
841
  }
790
842
  };
791
843
  var Parser = class {
792
- constructor(scanner, config) {
844
+ constructor(scanner, cxt) {
793
845
  this.scanner = scanner;
846
+ this.cxt = cxt;
794
847
  this.emit = new EmitEnvironment(scanner);
795
- this.cxt = new ParseContext(config);
796
848
  }
797
849
  emit;
798
- cxt;
799
850
  delayDepth = 0;
800
851
  groupDepth = 0;
852
+ #loc(to) {
853
+ return {
854
+ source: this.scanner.source,
855
+ start: this.scanner.position(),
856
+ end: to ?? this.scanner.position()
857
+ };
858
+ }
859
+ #locFrom(from, to) {
860
+ return {
861
+ source: this.scanner.source,
862
+ start: from,
863
+ end: to ?? this.scanner.position()
864
+ };
865
+ }
801
866
  #defs(type) {
802
867
  switch (type) {
803
868
  case 5 /* SystemModifier */:
@@ -897,30 +962,23 @@ var Parser = class {
897
962
  node.expansion = node.mod.expand(node, this.cxt, immediate);
898
963
  if (!node.expansion) {
899
964
  return true;
900
- } else if (node.expansion.length > 0) {
901
- debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
902
- debug.trace(() => "-->\n" + debugPrintNodes(node.expansion, " "));
903
- } else {
904
- debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
905
965
  }
966
+ debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
967
+ if (node.expansion.length > 0)
968
+ debug.trace(() => "-->\n" + debugPrint.node(...node.expansion));
906
969
  }
907
970
  const expansion = node.expansion ?? node.content;
908
971
  if (expansion.length == 0) return true;
909
972
  if (node.mod.beforeProcessExpansion)
910
973
  this.emit.message(...node.mod.beforeProcessExpansion(node, this.cxt, immediate));
911
- this.emit.pushReferring(node.start, node.end);
912
974
  let ok = this.#reparse(expansion, depth);
913
- this.emit.popReferring();
914
975
  if (node.mod.afterProcessExpansion)
915
976
  this.emit.message(...node.mod.afterProcessExpansion(node, this.cxt, immediate));
916
977
  if (!ok && depth == 0) {
917
978
  const limit = this.cxt.config.reparseDepthLimit;
918
- this.emit.message(new ReachedRecursionLimitMessage(
919
- node.start,
920
- node.end - node.start,
921
- limit,
922
- node.mod.name
923
- ));
979
+ this.emit.message(
980
+ new ReachedRecursionLimitMessage(node.location, limit, node.mod.name)
981
+ );
924
982
  }
925
983
  return ok;
926
984
  }
@@ -928,15 +986,18 @@ var Parser = class {
928
986
  this.DOCUMENT();
929
987
  return new Document(this.emit.root, this.cxt, this.emit.messages);
930
988
  }
989
+ WHITESPACES() {
990
+ while (this.scanner.acceptWhitespaceChar() !== null) {
991
+ }
992
+ }
931
993
  WHITESPACES_OR_NEWLINES() {
932
994
  while (this.scanner.acceptWhitespaceChar() !== null || this.scanner.accept("\n")) {
933
995
  }
934
996
  }
935
997
  SHOULD_BE_A_NEWLINE() {
936
- while (this.scanner.acceptWhitespaceChar() !== null) {
937
- }
998
+ this.WHITESPACES();
938
999
  if (!this.scanner.accept("\n")) this.emit.message(
939
- new ContentShouldBeOnNewlineMessage(this.scanner.position())
1000
+ new ContentShouldBeOnNewlineMessage(this.#loc())
940
1001
  );
941
1002
  }
942
1003
  // TODO: this is awkward and doesn't emit messages in the most appropriate way
@@ -952,7 +1013,7 @@ var Parser = class {
952
1013
  }
953
1014
  const end = this.scanner.position();
954
1015
  if (nlines > n) this.emit.message(
955
- new UnnecessaryNewlineMessage(start, end - start)
1016
+ new UnnecessaryNewlineMessage(this.#locFrom(start, end))
956
1017
  );
957
1018
  }
958
1019
  DOCUMENT() {
@@ -972,6 +1033,8 @@ var Parser = class {
972
1033
  this.MODIFIER(5 /* SystemModifier */);
973
1034
  return;
974
1035
  }
1036
+ const short = this.cxt.config.blockShorthands.find((x) => this.scanner.accept(x.name));
1037
+ if (short) return this.SHORTHAND(7 /* BlockModifier */, short);
975
1038
  this.MAYBE_GROUPED_PARAGRAPH();
976
1039
  }
977
1040
  MODIFIER(type) {
@@ -992,71 +1055,29 @@ var Parser = class {
992
1055
  name += this.scanner.acceptChar();
993
1056
  }
994
1057
  this.emit.message(
995
- new UnknownModifierMessage(posStart, this.scanner.position() - posStart, name)
1058
+ new UnknownModifierMessage(this.#locFrom(posStart), name)
996
1059
  );
997
1060
  }
998
1061
  const args = this.ARGUMENTS();
999
1062
  debug.trace(`PARSE ${NodeType[type]}:`, mod.name);
1000
1063
  const endsign = this.scanner.accept(MODIFIER_END_SIGN);
1001
- const flagMarker = has(mod.flags, 2 /* Marker */);
1002
- const isMarker = flagMarker || endsign;
1064
+ const flagMarker = mod.slotType == 2 /* None */;
1003
1065
  if (!this.scanner.accept(MODIFIER_CLOSE_SIGN))
1004
- this.emit.message(new ExpectedMessage(
1005
- this.scanner.position(),
1006
- MODIFIER_CLOSE_SIGN
1007
- ));
1066
+ this.emit.message(
1067
+ new ExpectedMessage(this.#loc(), MODIFIER_CLOSE_SIGN)
1068
+ );
1008
1069
  const headEnd = this.scanner.position();
1009
1070
  const node = {
1010
1071
  type,
1011
1072
  mod,
1012
- head: { start: posStart, end: headEnd },
1073
+ head: this.#locFrom(posStart, headEnd),
1074
+ location: this.#locFrom(posStart, headEnd),
1013
1075
  arguments: args,
1014
- start: posStart,
1015
- end: headEnd,
1016
1076
  content: [],
1017
1077
  expansion: void 0
1018
1078
  };
1019
- this.#expandArguments(node);
1020
- const immediate = this.delayDepth == 0;
1021
- if (node.mod.beforeParseContent)
1022
- this.emit.message(...node.mod.beforeParseContent(node, this.cxt, immediate));
1023
- if (node.mod.delayContentExpansion) this.delayDepth++;
1024
- let ok = true;
1025
- if (isMarker) {
1026
- if (type === 6 /* InlineModifier */) this.emit.addInlineNode(node);
1027
- else this.emit.addBlockNode(node);
1028
- } else if (type == 6 /* InlineModifier */) {
1029
- this.emit.startInline(node);
1030
- const entity = has(mod.flags, 1 /* Preformatted */) ? this.PREFORMATTED_INLINE_ENTITY.bind(this) : this.INLINE_ENTITY.bind(this);
1031
- while (true) {
1032
- if (this.scanner.accept(MODIFIER_INLINE_END_TAG)) break;
1033
- if (this.scanner.isEOF() || !(ok = entity())) {
1034
- this.emit.message(new UnclosedInlineModifierMessage(
1035
- this.scanner.position(),
1036
- mod.name
1037
- ));
1038
- break;
1039
- }
1040
- }
1041
- this.emit.endInline();
1042
- } else {
1043
- this.emit.startBlock(node);
1044
- this.WARN_IF_MORE_NEWLINES_THAN(1);
1045
- if (!this.scanner.isEOF()) {
1046
- if (has(mod.flags, 1 /* Preformatted */))
1047
- this.PRE_PARAGRAPH();
1048
- else
1049
- this.BLOCK_ENTITY();
1050
- }
1051
- this.emit.endBlock();
1052
- }
1053
- const last = node.content.at(-1);
1054
- node.actualEnd = last?.actualEnd ?? last?.end;
1055
- if (node.mod.delayContentExpansion) this.delayDepth--;
1056
- if (node.mod.afterParseContent)
1057
- this.emit.message(...node.mod.afterParseContent(node, this.cxt, immediate));
1058
- this.#expand(node);
1059
- return ok;
1079
+ const isMarker = flagMarker || endsign;
1080
+ return this.MODIFIER_BODY(type, node, MODIFIER_INLINE_END_TAG, isMarker);
1060
1081
  }
1061
1082
  // also handles "grouped" (delimited) pre-paragraphs
1062
1083
  PRE_PARAGRAPH() {
@@ -1075,10 +1096,9 @@ var Parser = class {
1075
1096
  white += char;
1076
1097
  if (grouped && this.scanner.accept(GROUP_END) || !grouped && this.scanner.accept("\n")) break;
1077
1098
  if (this.scanner.isEOF()) {
1078
- if (grouped) this.emit.message(new ExpectedMessage(
1079
- this.scanner.position(),
1080
- GROUP_END
1081
- ));
1099
+ if (grouped) this.emit.message(
1100
+ new ExpectedMessage(this.#loc(), GROUP_END)
1101
+ );
1082
1102
  break;
1083
1103
  }
1084
1104
  string += white;
@@ -1089,8 +1109,7 @@ var Parser = class {
1089
1109
  }
1090
1110
  const node = {
1091
1111
  type: 2 /* Preformatted */,
1092
- start: posStart,
1093
- end: this.scanner.position(),
1112
+ location: this.#locFrom(posStart),
1094
1113
  content: {
1095
1114
  start: posContentStart,
1096
1115
  end: posContentEnd,
@@ -1113,54 +1132,128 @@ var Parser = class {
1113
1132
  this.BLOCK_ENTITY();
1114
1133
  this.WARN_IF_MORE_NEWLINES_THAN(1);
1115
1134
  }
1116
- this.emit.message(new ExpectedMessage(
1117
- this.scanner.position(),
1118
- GROUP_END
1119
- ));
1135
+ this.emit.message(
1136
+ new ExpectedMessage(this.#loc(), GROUP_END)
1137
+ );
1120
1138
  } else {
1121
1139
  this.PARAGRAPH();
1122
1140
  }
1123
1141
  }
1142
+ #trimNode(node) {
1143
+ if (node.content.length == 0) return;
1144
+ let first = node.content[0];
1145
+ let last = node.content.at(-1);
1146
+ if (first.type == 3 /* Text */)
1147
+ first.content = first.content.trimStart();
1148
+ if (last.type == 3 /* Text */)
1149
+ last.content = last.content.trimEnd();
1150
+ }
1124
1151
  PARAGRAPH() {
1125
1152
  assert(!this.scanner.isEOF());
1126
1153
  const node = {
1127
1154
  type: 1 /* Paragraph */,
1128
- start: this.scanner.position(),
1129
- end: -1,
1155
+ location: this.#loc(),
1130
1156
  content: []
1131
1157
  };
1132
- debug.trace("PARSE para");
1133
1158
  this.emit.startInline(node);
1134
1159
  while (!this.scanner.isEOF() && this.INLINE_ENTITY()) {
1135
1160
  }
1136
1161
  this.emit.endInline();
1137
1162
  const last = node.content.at(-1);
1138
- node.actualEnd = last?.actualEnd ?? last?.end;
1139
- debug.trace("PARSE para end");
1163
+ node.location.actualEnd = last?.location.actualEnd ?? last?.location.end;
1164
+ this.#trimNode(node);
1165
+ }
1166
+ // returns false if breaking out of paragraph
1167
+ SHORTHAND(type, d) {
1168
+ const posStart = this.scanner.position() - d.name.length;
1169
+ let args = [];
1170
+ for (const part of d.parts) {
1171
+ let [arg, ok] = this.ARGUMENT_CONTENT(part, ["\n\n"]);
1172
+ if (!ok) {
1173
+ this.emit.message(new ExpectedMessage(this.#loc(), part));
1174
+ return false;
1175
+ }
1176
+ args.push(arg);
1177
+ }
1178
+ const headEnd = this.scanner.position();
1179
+ const node = {
1180
+ type,
1181
+ mod: d.mod,
1182
+ head: this.#locFrom(posStart, headEnd),
1183
+ location: this.#locFrom(posStart, headEnd),
1184
+ arguments: args,
1185
+ content: [],
1186
+ expansion: void 0
1187
+ };
1188
+ const isMarker = node.mod.slotType == 2 /* None */;
1189
+ return this.MODIFIER_BODY(type, node, d.postfix, isMarker);
1190
+ }
1191
+ MODIFIER_BODY(type, node, postfix, isMarker) {
1192
+ this.#expandArguments(node);
1193
+ const immediate = this.delayDepth == 0;
1194
+ if (node.mod.beforeParseContent)
1195
+ this.emit.message(...node.mod.beforeParseContent(node, this.cxt, immediate));
1196
+ if (node.mod.delayContentExpansion) this.delayDepth++;
1197
+ let ok = true;
1198
+ if (isMarker) {
1199
+ if (type === 6 /* InlineModifier */) this.emit.addInlineNode(node);
1200
+ else this.emit.addBlockNode(node);
1201
+ } else if (type == 6 /* InlineModifier */) {
1202
+ node = node;
1203
+ this.emit.startInline(node);
1204
+ const pre = node.mod.slotType == 1 /* Preformatted */;
1205
+ const entity = pre ? this.PREFORMATTED_INLINE_ENTITY.bind(this) : this.INLINE_ENTITY.bind(this);
1206
+ while (true) {
1207
+ if (postfix && this.scanner.accept(postfix)) break;
1208
+ if (this.scanner.isEOF() || !(ok = entity())) {
1209
+ if (postfix) this.emit.message(
1210
+ new ExpectedMessage(this.#loc(), postfix)
1211
+ );
1212
+ break;
1213
+ }
1214
+ }
1215
+ this.emit.endInline();
1216
+ if (!pre && node.content.length > 0) {
1217
+ this.#trimNode(node);
1218
+ }
1219
+ } else {
1220
+ this.emit.startBlock(node);
1221
+ this.WARN_IF_MORE_NEWLINES_THAN(1);
1222
+ if (!this.scanner.isEOF()) {
1223
+ if (node.mod.slotType == 1 /* Preformatted */)
1224
+ this.PRE_PARAGRAPH();
1225
+ else
1226
+ this.BLOCK_ENTITY();
1227
+ }
1228
+ this.emit.endBlock();
1229
+ }
1230
+ const last = node.content.at(-1);
1231
+ node.location.actualEnd = last?.location.actualEnd ?? last?.location.end;
1232
+ if (node.mod.delayContentExpansion) this.delayDepth--;
1233
+ if (node.mod.afterParseContent)
1234
+ this.emit.message(...node.mod.afterParseContent(node, this.cxt, immediate));
1235
+ this.#expand(node);
1236
+ return ok;
1140
1237
  }
1141
1238
  // returns false if breaking out of paragraph
1142
1239
  INLINE_ENTITY() {
1143
1240
  assert(!this.scanner.isEOF());
1144
- if (this.scanner.peek(MODIFIER_BLOCK_OPEN)) {
1145
- this.emit.message(new NewBlockShouldBeOnNewlineMessage(this.scanner.position()));
1146
- return false;
1147
- }
1148
- if (this.scanner.peek(MODIFIER_INLINE_OPEN)) {
1241
+ if (this.scanner.peek(MODIFIER_INLINE_OPEN))
1149
1242
  return this.MODIFIER(6 /* InlineModifier */);
1150
- }
1151
- if (this.scanner.peek(MODIFIER_SYSTEM_OPEN)) {
1243
+ if (this.scanner.peek(MODIFIER_SYSTEM_OPEN))
1152
1244
  return false;
1153
- }
1245
+ const short = this.cxt.config.inlineShorthands.find((x) => this.scanner.accept(x.name));
1246
+ if (short) return this.SHORTHAND(6 /* InlineModifier */, short);
1154
1247
  if (this.scanner.accept("\\")) {
1155
1248
  if (this.scanner.isEOF()) {
1156
1249
  this.emit.addString("\\");
1157
1250
  return true;
1158
1251
  }
1252
+ const start = this.scanner.position();
1159
1253
  const node = {
1160
1254
  type: 4 /* Escaped */,
1161
- start: this.scanner.position() - 1,
1162
1255
  content: this.scanner.acceptChar(),
1163
- end: this.scanner.position()
1256
+ location: this.#locFrom(start - 1)
1164
1257
  };
1165
1258
  this.emit.addInlineNode(node);
1166
1259
  return true;
@@ -1171,9 +1264,8 @@ var Parser = class {
1171
1264
  PREFORMATTED_INLINE_ENTITY() {
1172
1265
  assert(!this.scanner.isEOF());
1173
1266
  if (this.scanner.accept("\n")) {
1174
- while (this.scanner.acceptWhitespaceChar() !== null) {
1175
- }
1176
- if (this.scanner.peek(MODIFIER_BLOCK_OPEN) || this.scanner.peek(MODIFIER_SYSTEM_OPEN) || this.scanner.peek(GROUP_END) && this.groupDepth > 0 || this.scanner.isEOF()) return false;
1267
+ this.WHITESPACES();
1268
+ 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.groupDepth > 0 || this.scanner.isEOF()) return false;
1177
1269
  if (this.scanner.accept("\n")) {
1178
1270
  this.WARN_IF_MORE_NEWLINES_THAN(0);
1179
1271
  return false;
@@ -1184,7 +1276,8 @@ var Parser = class {
1184
1276
  this.emit.addString(this.scanner.acceptChar());
1185
1277
  return true;
1186
1278
  }
1187
- ARGUMENT_CONTENT(end) {
1279
+ // returns argument and isOk
1280
+ ARGUMENT_CONTENT(end = void 0, close = [MODIFIER_END_SIGN, MODIFIER_CLOSE_SIGN]) {
1188
1281
  let ok = true;
1189
1282
  const content = [];
1190
1283
  const posStart = this.scanner.position();
@@ -1193,25 +1286,22 @@ var Parser = class {
1193
1286
  const last = content.at(-1);
1194
1287
  if (last?.type == 3 /* Text */) {
1195
1288
  last.content += s;
1196
- last.end += s.length;
1289
+ last.location.end += s.length;
1197
1290
  } else {
1198
1291
  const end2 = this.scanner.position();
1199
1292
  content.push({
1200
1293
  type: 3 /* Text */,
1201
- end: end2,
1202
- start: end2 - s.length,
1294
+ location: this.#locFrom(end2 - s.length),
1203
1295
  content: s
1204
1296
  });
1205
1297
  }
1206
1298
  };
1207
1299
  while (true) {
1208
- if (end !== void 0 && this.scanner.accept(end))
1300
+ if (end && this.scanner.accept(end))
1209
1301
  break;
1210
- if (this.scanner.accept(":")) {
1211
- ok = end === void 0;
1302
+ if (end === void 0 && this.scanner.accept(":"))
1212
1303
  break;
1213
- }
1214
- if (this.scanner.peek(MODIFIER_END_SIGN) || this.scanner.peek(MODIFIER_CLOSE_SIGN) || this.scanner.isEOF()) {
1304
+ if (close.find((x) => this.scanner.peek(x)) || this.scanner.isEOF()) {
1215
1305
  ok = false;
1216
1306
  break;
1217
1307
  }
@@ -1225,8 +1315,7 @@ var Parser = class {
1225
1315
  content.push({
1226
1316
  type: 4 /* Escaped */,
1227
1317
  content: this.scanner.acceptChar(),
1228
- start: posEnd - 1,
1229
- end: posEnd + 1
1318
+ location: this.#locFrom(posEnd - 1)
1230
1319
  });
1231
1320
  continue;
1232
1321
  }
@@ -1241,11 +1330,10 @@ var Parser = class {
1241
1330
  type: 8 /* Interpolation */,
1242
1331
  definition: result,
1243
1332
  argument: inner,
1244
- start: beforeInterp,
1245
- end: posEnd
1333
+ location: this.#locFrom(beforeInterp)
1246
1334
  });
1247
1335
  if (!ok2) {
1248
- this.emit.message(new ExpectedMessage(posEnd, result.postfix));
1336
+ this.emit.message(new ExpectedMessage(this.#loc(), result.postfix));
1249
1337
  ok = false;
1250
1338
  break;
1251
1339
  }
@@ -1255,8 +1343,7 @@ var Parser = class {
1255
1343
  }
1256
1344
  }
1257
1345
  return [{
1258
- start: posStart,
1259
- end: posEnd,
1346
+ location: this.#locFrom(posStart, posEnd),
1260
1347
  content
1261
1348
  }, ok];
1262
1349
  }
@@ -1277,24 +1364,171 @@ var Parser = class {
1277
1364
  return list;
1278
1365
  }
1279
1366
  };
1280
- function parse(scanner, config) {
1281
- return new Parser(scanner, config).parse();
1367
+ function parse(scanner, cxt) {
1368
+ return new Parser(scanner, cxt).parse();
1282
1369
  }
1283
1370
 
1371
+ // src/renderer.ts
1372
+ var RenderContext = class {
1373
+ constructor(config2, parseContext, state) {
1374
+ this.config = config2;
1375
+ this.parseContext = parseContext;
1376
+ this.state = state;
1377
+ }
1378
+ renderEntity(node) {
1379
+ switch (node.type) {
1380
+ case 1 /* Paragraph */:
1381
+ return this.config.paragraphRenderer?.(node, this);
1382
+ case 2 /* Preformatted */:
1383
+ case 3 /* Text */:
1384
+ case 4 /* Escaped */:
1385
+ return this.config.textRenderer?.(node, this);
1386
+ case 6 /* InlineModifier */:
1387
+ let ir = this.config.inlineRenderers.get(node.mod);
1388
+ if (ir) return ir(node, this);
1389
+ return this.config.undefinedInlineRenderer?.(node, this);
1390
+ case 7 /* BlockModifier */:
1391
+ let br = this.config.blockRenderers.get(node.mod);
1392
+ if (br) return br(node, this);
1393
+ return this.config.undefinedBlockRenderer?.(node, this);
1394
+ case 5 /* SystemModifier */:
1395
+ return void 0;
1396
+ default:
1397
+ return debug.never(node);
1398
+ }
1399
+ }
1400
+ };
1401
+ var RenderConfiguration = class _RenderConfiguration {
1402
+ constructor(options, postprocessor) {
1403
+ this.options = options;
1404
+ this.postprocessor = postprocessor;
1405
+ }
1406
+ paragraphRenderer;
1407
+ textRenderer;
1408
+ undefinedBlockRenderer;
1409
+ undefinedInlineRenderer;
1410
+ blockRenderers = /* @__PURE__ */ new Map();
1411
+ inlineRenderers = /* @__PURE__ */ new Map();
1412
+ render(doc, state) {
1413
+ let cxt = new RenderContext(this, doc.context, state);
1414
+ let results = doc.toStripped().root.content.map((x) => cxt.renderEntity(x)).filter((x) => x !== void 0);
1415
+ return this.postprocessor(results, cxt);
1416
+ }
1417
+ addBlockRenderer(...rs) {
1418
+ rs.forEach(([x, y]) => this.blockRenderers.set(x, y));
1419
+ }
1420
+ addInlineRenderer(...rs) {
1421
+ rs.forEach(([x, y]) => this.inlineRenderers.set(x, y));
1422
+ }
1423
+ static from(from) {
1424
+ let config2 = new _RenderConfiguration(from.options, from.postprocessor);
1425
+ config2.paragraphRenderer = from.paragraphRenderer;
1426
+ config2.textRenderer = from.textRenderer;
1427
+ config2.undefinedBlockRenderer = from.undefinedBlockRenderer;
1428
+ config2.undefinedInlineRenderer = from.undefinedInlineRenderer;
1429
+ config2.inlineRenderers = new Map(from.inlineRenderers);
1430
+ config2.blockRenderers = new Map(from.blockRenderers);
1431
+ return config2;
1432
+ }
1433
+ };
1434
+
1284
1435
  // src/modifier-helper.ts
1285
1436
  function checkArgumentLength(node, min, max = min) {
1286
1437
  if (min !== void 0 && node.arguments.length < min || max !== void 0 && node.arguments.length > max) {
1287
- return [new ArgumentCountMismatchMessage(node.head.start, node.head.end - node.head.start, min, max)];
1438
+ return [new ArgumentCountMismatchMessage({
1439
+ source: node.location.source,
1440
+ start: node.head.start,
1441
+ end: node.head.end
1442
+ }, min, max)];
1288
1443
  }
1289
1444
  return null;
1290
1445
  }
1291
1446
  function checkArguments(node, min, max = min) {
1292
1447
  const arg = node.arguments.find((x) => x.expansion === void 0);
1293
1448
  if (arg !== void 0) {
1294
- return [new CannotExpandArgumentMessage(arg.start, arg.end - arg.start)];
1449
+ return [new CannotExpandArgumentMessage(arg.location)];
1295
1450
  }
1296
1451
  return checkArgumentLength(node, min, max);
1297
1452
  }
1453
+ function onlyPermitPlaintextParagraph(node) {
1454
+ function checkInline(ents) {
1455
+ let result = "";
1456
+ for (const ent of ents) {
1457
+ switch (ent.type) {
1458
+ case 3 /* Text */:
1459
+ case 4 /* Escaped */:
1460
+ result += ent.content;
1461
+ break;
1462
+ case 5 /* SystemModifier */:
1463
+ break;
1464
+ case 6 /* InlineModifier */:
1465
+ if (!ent.expansion) return [new EntityNotAllowedMessage(
1466
+ ent.location,
1467
+ "it does not expand to plain text"
1468
+ )];
1469
+ let checkInner = checkInline(ent.expansion);
1470
+ if (Array.isArray(checkInner)) return checkInner;
1471
+ result += checkInner;
1472
+ break;
1473
+ default:
1474
+ return debug.never(ent);
1475
+ }
1476
+ }
1477
+ return result;
1478
+ }
1479
+ function check(ent) {
1480
+ if (ent.type == 7 /* BlockModifier */) {
1481
+ if (!ent.expansion) return [new EntityNotAllowedMessage(
1482
+ ent.location,
1483
+ "it does not expand to plain text"
1484
+ )];
1485
+ if (ent.expansion.length == 0) return "";
1486
+ else if (ent.expansion.length > 1) {
1487
+ let last = ent.expansion.at(-1).location;
1488
+ return [new MultipleBlocksNotPermittedMessage({
1489
+ source: last.source,
1490
+ start: ent.expansion[1].location.start,
1491
+ end: last.actualEnd ?? last.end
1492
+ })];
1493
+ }
1494
+ return check(ent.expansion[0]);
1495
+ } else if (ent.type !== 1 /* Paragraph */) {
1496
+ return [new OnlySimpleParagraphsPermittedMessage(ent.location)];
1497
+ }
1498
+ return checkInline(ent.content);
1499
+ }
1500
+ return check(node);
1501
+ }
1502
+ function onlyPermitSimpleParagraphs(node) {
1503
+ function check(nodes) {
1504
+ for (let ent of nodes) {
1505
+ if (ent.type == 7 /* BlockModifier */ && ent.expansion !== void 0) {
1506
+ const cs = check(ent.expansion);
1507
+ if (cs) return cs;
1508
+ } else if (ent.type !== 1 /* Paragraph */) {
1509
+ return [new OnlySimpleParagraphsPermittedMessage(ent.location)];
1510
+ }
1511
+ }
1512
+ return null;
1513
+ }
1514
+ return check(node.content);
1515
+ }
1516
+ function onlyPermitSingleBlock(node) {
1517
+ function check(nodes) {
1518
+ if (nodes.length > 1) {
1519
+ let last = nodes.at(-1).location;
1520
+ return [new MultipleBlocksNotPermittedMessage({
1521
+ source: last.source,
1522
+ start: nodes[1].location.start,
1523
+ end: last.actualEnd ?? last.end
1524
+ })];
1525
+ } else if (nodes.length == 1 && nodes[0].type === 7 /* BlockModifier */ && nodes[0].expansion !== void 0) {
1526
+ return check(nodes[0].expansion);
1527
+ }
1528
+ return null;
1529
+ }
1530
+ return check(node.content);
1531
+ }
1298
1532
 
1299
1533
  // src/builtin/internal.ts
1300
1534
  var builtins = Symbol();
@@ -1302,358 +1536,706 @@ function initParseContext(cxt) {
1302
1536
  cxt.init(builtins, {
1303
1537
  blockSlotDelayedStack: [],
1304
1538
  inlineSlotDelayedStack: [],
1305
- blockSlotData: [],
1306
- inlineSlotData: [],
1307
- notationStack: []
1539
+ blockInstantiationData: [],
1540
+ inlineInstantiationData: [],
1541
+ modules: /* @__PURE__ */ new Map(),
1542
+ usedModules: /* @__PURE__ */ new Set(),
1543
+ insideModule: void 0
1308
1544
  });
1309
1545
  }
1310
- function customModifier(type, name, argNames, slotName, content) {
1311
- debug.info(`registered custom ${type} modifier:`, name);
1312
- debug.info("args:", argNames, `with ${slotName == "" ? "no slot name" : "slot name: " + slotName}`);
1313
- debug.trace(() => "content is\n" + debugPrintNodes(content));
1314
- const mod = type == 7 /* BlockModifier */ ? new BlockModifierDefinition(name, 0 /* Normal */) : new InlineModifierDefinition(name, 0 /* Normal */);
1546
+ function customModifier(type, name, signature, content) {
1547
+ debug.info(`created custom ${NodeType[type]}:`, name);
1548
+ debug.info("args:", signature.args, `with ${signature.slotName === void 0 ? "no slot" : signature.slotName == "" ? "empty slot name" : "slot name: " + signature.slotName}`);
1549
+ debug.trace(() => "content is\n" + debugPrint.node(...content));
1550
+ const flag = signature.slotName === void 0 ? 2 /* None */ : signature.preformatted ? 1 /* Preformatted */ : 0 /* Normal */;
1551
+ const mod = type == 7 /* BlockModifier */ ? new BlockModifierDefinition(name, flag) : new InlineModifierDefinition(name, flag);
1315
1552
  const isInline = type == 6 /* InlineModifier */;
1553
+ if (content.length == 1 && (content[0].type == 7 /* BlockModifier */ || content[0].type == 6 /* InlineModifier */))
1554
+ mod.roleHint = content[0].mod.roleHint;
1316
1555
  mod.delayContentExpansion = true;
1317
1556
  mod.prepareExpand = (node, cxt) => {
1318
- let check = checkArguments(node, argNames.length);
1557
+ let check = checkArguments(node, signature.args.length);
1319
1558
  if (check) return check;
1320
1559
  node.state = {
1321
1560
  ok: true,
1322
- args: new Map(node.arguments.map((x, i) => [argNames[i], x.expansion]))
1561
+ args: new Map(node.arguments.map((x, i) => [signature.args[i], x.expansion]))
1323
1562
  };
1324
1563
  return [];
1325
1564
  };
1326
- mod.expand = (node, cxt) => {
1565
+ mod.expand = (node) => {
1327
1566
  if (!node.state?.ok) return [];
1328
- const contentClone = cloneNodes(content);
1567
+ const contentClone = cloneNodes(content, { newLocation: node.location });
1329
1568
  return contentClone;
1330
1569
  };
1331
1570
  mod.beforeProcessExpansion = (node, cxt) => {
1332
1571
  if (!node.state?.ok) return [];
1333
1572
  const store = cxt.get(builtins);
1334
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1335
- data.push([slotName, {
1573
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1574
+ data.push({
1575
+ slotName: signature.slotName,
1336
1576
  mod,
1337
1577
  args: node.state.args,
1338
1578
  slotContent: node.content
1339
- }]);
1579
+ });
1340
1580
  debug.trace(
1341
- `pushed ${type} slot data for`,
1581
+ `pushed ${NodeType[type]} slot data for`,
1342
1582
  name,
1343
- slotName == "" ? "(unnamed)" : `= ${slotName}`
1583
+ signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1344
1584
  );
1345
1585
  return [];
1346
1586
  };
1347
1587
  mod.afterProcessExpansion = (node, cxt) => {
1348
- if (!node.state?.ok) return [];
1588
+ if (!node.state?.ok || signature.slotName === void 0) return [];
1349
1589
  const store = cxt.get(builtins);
1350
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1590
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1351
1591
  const pop = data.pop();
1352
- assert(pop !== void 0 && pop[0] == slotName);
1592
+ assert(pop !== void 0);
1353
1593
  debug.trace(
1354
- `popped ${type} slot data for`,
1594
+ `popped ${NodeType[type]} slot data for`,
1355
1595
  name,
1356
- slotName == "" ? "(unnamed)" : `= ${slotName}`
1596
+ signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1357
1597
  );
1358
1598
  return [];
1359
1599
  };
1360
1600
  return mod;
1361
1601
  }
1362
-
1363
- // src/builtin/define-block.ts
1364
- var DefineBlockMod = new SystemModifierDefinition("define-block", 0 /* Normal */, {
1365
- // .define-block:name:args...[:(slot-id)]
1366
- delayContentExpansion: true,
1367
- alwaysTryExpand: true,
1368
- beforeParseContent(node, cxt) {
1369
- const check = checkArgumentLength(node, 1, Infinity);
1370
- if (check) return check;
1371
- const msgs = [];
1372
- const name = node.arguments[0];
1373
- const nameValue = name.expansion;
1374
- let slotName = "";
1375
- if (node.arguments.length > 1) {
1376
- const last = node.arguments.at(-1);
1377
- if (last.expansion)
1378
- slotName = /^\(.+\)$/.test(last.expansion) ? last.expansion.substring(1, last.expansion.length - 1) : "";
1379
- else msgs.push(
1380
- new InvalidArgumentMessage(last.start, last.end - last.start)
1381
- );
1602
+ function makeInlineDefinition(node, msgs) {
1603
+ let lastIsParagraph = false;
1604
+ let concat = [];
1605
+ for (const n of node.content) {
1606
+ switch (n.type) {
1607
+ case 1 /* Paragraph */:
1608
+ if (!lastIsParagraph) {
1609
+ lastIsParagraph = true;
1610
+ concat.push(...n.content);
1611
+ continue;
1612
+ }
1613
+ case 2 /* Preformatted */:
1614
+ case 7 /* BlockModifier */:
1615
+ msgs.push(new EntityNotAllowedMessage(n.location));
1616
+ break;
1617
+ case 5 /* SystemModifier */:
1618
+ lastIsParagraph = false;
1619
+ concat.push(n);
1620
+ break;
1621
+ default:
1622
+ debug.never(n);
1382
1623
  }
1383
- const args = node.arguments.slice(1, slotName !== "" ? node.arguments.length - 1 : void 0).map((x) => {
1384
- if (!x.expansion) msgs.push(
1385
- new InvalidArgumentMessage(x.start, x.end - x.start)
1386
- );
1387
- return x.expansion ?? "";
1388
- });
1389
- node.state = { name: nameValue, slotName, args, msgs };
1390
- const store = cxt.get(builtins);
1391
- store.blockSlotDelayedStack.push(node.state.slotName);
1392
- debug.trace("entering block definition:", node.state.name);
1393
- return [];
1394
- },
1395
- afterParseContent(node, cxt) {
1396
- if (!node.state) return [];
1397
- const store = cxt.get(builtins);
1398
- assert(store.blockSlotDelayedStack.pop() == node.state.slotName);
1399
- debug.trace("leaving block definition", node.state.name);
1400
- return [];
1401
- },
1402
- prepareExpand(node, cxt, immediate) {
1403
- if (!immediate || !node.state) return [];
1404
- const arg = node.arguments[0];
1405
- if (!node.state.name)
1406
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1407
- if (cxt.config.blockModifiers.has(node.state.name))
1408
- return [new NameAlreadyDefinedMessage(
1409
- arg.start,
1410
- arg.end - arg.start,
1411
- node.state.name
1412
- )];
1413
- return [];
1414
- },
1415
- expand(node, cxt, immediate) {
1416
- if (!immediate) return void 0;
1417
- if (node.state?.name) {
1418
- if (cxt.config.blockModifiers.has(node.state.name))
1419
- cxt.config.blockModifiers.remove(node.state.name);
1420
- cxt.config.blockModifiers.add(
1421
- customModifier(
1624
+ }
1625
+ return concat;
1626
+ }
1627
+
1628
+ // src/builtin/define-modifier.ts
1629
+ function parseDefineArguments(node, stack) {
1630
+ const check = checkArgumentLength(node, 1, Infinity);
1631
+ if (check) return check;
1632
+ const msgs = [];
1633
+ const name = node.arguments[0];
1634
+ const nameValue = name.expansion;
1635
+ if (nameValue === "" || nameValue?.includes("\n")) return [
1636
+ new InvalidArgumentMessage(name.location, nameValue)
1637
+ ];
1638
+ let slotName = "";
1639
+ if (node.arguments.length > 1) {
1640
+ const last = node.arguments.at(-1);
1641
+ if (last.expansion) {
1642
+ const match = /^\((.*)\)$/.exec(last.expansion);
1643
+ slotName = match ? match[1] : "";
1644
+ } else msgs.push(
1645
+ new InvalidArgumentMessage(last.location)
1646
+ );
1647
+ }
1648
+ const args = node.arguments.slice(1, slotName !== "" ? node.arguments.length - 1 : void 0).map((x) => {
1649
+ if (!x.expansion) msgs.push(
1650
+ new InvalidArgumentMessage(x.location)
1651
+ );
1652
+ return x.expansion ?? "";
1653
+ });
1654
+ let signature = { slotName, args, preformatted: void 0 };
1655
+ node.state = { name: nameValue, signature, msgs };
1656
+ stack.push(signature);
1657
+ return void 0;
1658
+ }
1659
+ var DefineBlockMod = new SystemModifierDefinition(
1660
+ "define-block",
1661
+ 0 /* Normal */,
1662
+ {
1663
+ // .define-block:name:args...[:(slot-id)]
1664
+ delayContentExpansion: true,
1665
+ alwaysTryExpand: true,
1666
+ beforeParseContent(node, cxt) {
1667
+ const store = cxt.get(builtins);
1668
+ const check = parseDefineArguments(node, store.blockSlotDelayedStack);
1669
+ if (check) return check;
1670
+ debug.trace("entering block definition:", node.state.name);
1671
+ return [];
1672
+ },
1673
+ afterParseContent(node, cxt) {
1674
+ if (!node.state) return [];
1675
+ const store = cxt.get(builtins);
1676
+ const pop = store.blockSlotDelayedStack.pop();
1677
+ assert(pop === node.state.signature);
1678
+ debug.trace("leaving block definition", node.state.name);
1679
+ return [];
1680
+ },
1681
+ prepareExpand(node, cxt, immediate) {
1682
+ if (!immediate || !node.state) return [];
1683
+ const arg = node.arguments[0];
1684
+ const msgs = node.state.msgs;
1685
+ if (!node.state.name)
1686
+ msgs.push(new InvalidArgumentMessage(arg.location));
1687
+ else if (cxt.config.blockModifiers.has(node.state.name))
1688
+ msgs.push(new NameAlreadyDefinedMessage(arg.location, node.state.name));
1689
+ return msgs;
1690
+ },
1691
+ expand(node, cxt, immediate) {
1692
+ if (!immediate) return void 0;
1693
+ if (node.state?.name) {
1694
+ if (cxt.config.blockModifiers.has(node.state.name))
1695
+ cxt.config.blockModifiers.remove(node.state.name);
1696
+ cxt.config.blockModifiers.add(customModifier(
1422
1697
  7 /* BlockModifier */,
1423
1698
  node.state.name,
1424
- node.state.args,
1425
- node.state.slotName,
1699
+ node.state.signature,
1426
1700
  node.content
1427
- )
1428
- );
1701
+ ));
1702
+ }
1703
+ return [];
1704
+ }
1705
+ }
1706
+ );
1707
+ var DefineInlineMod = new SystemModifierDefinition(
1708
+ "define-inline",
1709
+ 0 /* Normal */,
1710
+ {
1711
+ // .define-inline name:args...[:(slot-id)]
1712
+ delayContentExpansion: true,
1713
+ alwaysTryExpand: true,
1714
+ beforeParseContent(node, cxt) {
1715
+ const store = cxt.get(builtins);
1716
+ const check = parseDefineArguments(node, store.inlineSlotDelayedStack);
1717
+ if (check) return check;
1718
+ debug.trace("entering inline definition:", node.state.name);
1719
+ return [];
1720
+ },
1721
+ afterParseContent(node, cxt) {
1722
+ if (!node.state) return [];
1723
+ const store = cxt.get(builtins);
1724
+ const pop = store.inlineSlotDelayedStack.pop();
1725
+ assert(pop === node.state.signature);
1726
+ debug.trace("leaving inline definition", node.state.name);
1727
+ return [];
1728
+ },
1729
+ prepareExpand(node, cxt, immediate) {
1730
+ if (!immediate || !node.state) return [];
1731
+ const arg = node.arguments[0];
1732
+ if (!node.state.name)
1733
+ return [new InvalidArgumentMessage(arg.location)];
1734
+ const msgs = node.state.msgs;
1735
+ if (cxt.config.inlineModifiers.has(node.state.name))
1736
+ msgs.push(new NameAlreadyDefinedMessage(arg.location, node.state.name));
1737
+ node.state.definition = makeInlineDefinition(node, msgs);
1738
+ return msgs;
1739
+ },
1740
+ expand(node, cxt, immediate) {
1741
+ if (!immediate) return void 0;
1742
+ if (node.state?.name) {
1743
+ if (cxt.config.inlineModifiers.has(node.state.name))
1744
+ cxt.config.inlineModifiers.remove(node.state.name);
1745
+ cxt.config.inlineModifiers.add(
1746
+ customModifier(
1747
+ 6 /* InlineModifier */,
1748
+ node.state.name,
1749
+ node.state.signature,
1750
+ node.state.definition
1751
+ )
1752
+ );
1753
+ }
1754
+ return [];
1429
1755
  }
1430
- return [];
1431
1756
  }
1432
- });
1757
+ );
1433
1758
 
1434
- // src/builtin/define-inline.ts
1435
- var DefineInlineMod = new SystemModifierDefinition("define-inline", 0 /* Normal */, {
1436
- // .define-inline name:args...[:(slot-id)]
1437
- delayContentExpansion: true,
1438
- alwaysTryExpand: true,
1439
- beforeParseContent(node, cxt) {
1440
- const check = checkArgumentLength(node, 1, Infinity);
1441
- if (check) return check;
1442
- const msgs = [];
1443
- const name = node.arguments[0];
1444
- const nameValue = name.expansion;
1445
- if (nameValue && cxt.config.inlineModifiers.has(nameValue))
1446
- msgs.push(new NameAlreadyDefinedMessage(
1447
- node.start,
1448
- name.end - name.start,
1449
- nameValue
1450
- ));
1451
- let slotName = "";
1452
- if (node.arguments.length > 1) {
1453
- const last = node.arguments.at(-1);
1454
- if (last.expansion)
1455
- slotName = /^\(.+\)$/.test(last.expansion) ? last.expansion.substring(1, last.expansion.length - 1) : "";
1456
- else msgs.push(
1457
- new InvalidArgumentMessage(last.start, last.end - last.start)
1458
- );
1459
- }
1460
- const args = node.arguments.slice(1, slotName !== "" ? node.arguments.length - 1 : void 0).map((x) => {
1461
- if (!x.expansion) msgs.push(
1462
- new InvalidArgumentMessage(x.start, x.end - x.start)
1463
- );
1464
- return x.expansion ?? "";
1465
- });
1466
- node.state = { name: nameValue, slotName, args, msgs };
1467
- const store = cxt.get(builtins);
1468
- store.inlineSlotDelayedStack.push(node.state.slotName);
1469
- debug.trace("entering inline definition:", node.state.name);
1470
- return [];
1471
- },
1472
- afterParseContent(node, cxt) {
1473
- if (!node.state) return [];
1474
- const store = cxt.get(builtins);
1475
- assert(store.inlineSlotDelayedStack.pop() == node.state.slotName);
1476
- debug.trace("leaving inline definition", node.state.name);
1477
- return [];
1478
- },
1479
- prepareExpand(node, cxt, immediate) {
1480
- if (!immediate || !node.state) return [];
1481
- const arg = node.arguments[0];
1482
- if (!node.state.name)
1483
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1484
- const msgs = [];
1485
- if (cxt.config.inlineModifiers.has(node.state.name))
1486
- msgs.push(new NameAlreadyDefinedMessage(
1487
- arg.start,
1488
- arg.end - arg.start,
1489
- node.state.name
1490
- ));
1491
- let lastIsParagraph = false;
1492
- let concat = [];
1493
- for (const n of node.content) {
1494
- switch (n.type) {
1495
- case 1 /* Paragraph */:
1496
- if (!lastIsParagraph) {
1497
- lastIsParagraph = true;
1498
- concat.push(...n.content);
1499
- continue;
1759
+ // src/builtin/define-shorthand.ts
1760
+ function parseDefineArguments2(type, node, stack) {
1761
+ const check = checkArguments(node, 1, Infinity);
1762
+ if (check) return check;
1763
+ const msgs = [];
1764
+ const name = node.arguments[0];
1765
+ const nameValue = name.expansion;
1766
+ if (nameValue === "" || nameValue?.includes("\n")) return [
1767
+ new InvalidArgumentMessage(name.location, nameValue)
1768
+ ];
1769
+ let slotName = void 0;
1770
+ let parts = [];
1771
+ let postfix = void 0;
1772
+ let i = 1;
1773
+ while (i < node.arguments.length) {
1774
+ const arg = node.arguments[i];
1775
+ const match = /^\((.*)\)$/.exec(arg.expansion);
1776
+ if (match) {
1777
+ slotName = match[1];
1778
+ i++;
1779
+ if (type == 6 /* InlineModifier */) {
1780
+ if (i < node.arguments.length) {
1781
+ if (node.arguments[i].expansion === "") {
1782
+ msgs.push(new InvalidArgumentMessage(
1783
+ node.arguments[i].location,
1784
+ "postfix"
1785
+ ));
1786
+ } else {
1787
+ postfix = node.arguments[i].expansion;
1788
+ i++;
1500
1789
  }
1501
- case 2 /* Preformatted */:
1502
- case 7 /* BlockModifier */:
1503
- msgs.push(new InlineDefinitonInvalidEntityMessage(n.start, n.end - n.start));
1504
- break;
1505
- case 5 /* SystemModifier */:
1506
- lastIsParagraph = false;
1507
- concat.push(n);
1508
- break;
1509
- default:
1510
- debug.never(n);
1790
+ } else msgs.push(
1791
+ new ArgumentCountMismatchMessage(node.location)
1792
+ );
1511
1793
  }
1794
+ break;
1512
1795
  }
1513
- node.state.definition = concat;
1514
- return msgs;
1515
- },
1516
- expand(node, cxt, immediate) {
1517
- if (!immediate) return void 0;
1518
- if (node.state?.name) {
1519
- if (cxt.config.inlineModifiers.has(node.state.name))
1520
- cxt.config.inlineModifiers.remove(node.state.name);
1521
- cxt.config.inlineModifiers.add(
1522
- customModifier(
1523
- 6 /* InlineModifier */,
1524
- node.state.name,
1525
- node.state.args,
1526
- node.state.slotName,
1527
- node.state.definition
1528
- )
1796
+ i++;
1797
+ if (i < node.arguments.length) {
1798
+ const id = arg.expansion;
1799
+ if (id === "") {
1800
+ return [new InvalidArgumentMessage(arg.location, "id")];
1801
+ }
1802
+ const part = node.arguments[i].expansion;
1803
+ if (part === "") {
1804
+ return [new InvalidArgumentMessage(
1805
+ node.arguments[i].location,
1806
+ "part"
1807
+ )];
1808
+ }
1809
+ parts.push([id, part]);
1810
+ i++;
1811
+ } else {
1812
+ msgs.push(new ArgumentCountMismatchMessage(node.location));
1813
+ break;
1814
+ }
1815
+ }
1816
+ if (i == node.arguments.length - 1) {
1817
+ const last = node.arguments[i];
1818
+ if (last.expansion !== "") msgs.push(
1819
+ new InvalidArgumentMessage(last.location, "(must be empty)")
1820
+ );
1821
+ } else if (i < node.arguments.length - 1)
1822
+ msgs.push(new ArgumentCountMismatchMessage(node.location));
1823
+ let signature = { slotName, args: parts.map((x) => x[0]), preformatted: void 0 };
1824
+ node.state = { name: nameValue, signature, parts, postfix, msgs };
1825
+ stack.push(signature);
1826
+ return [];
1827
+ }
1828
+ var DefineBlockShorthandMod = new SystemModifierDefinition(
1829
+ "block-shorthand",
1830
+ 0 /* Normal */,
1831
+ {
1832
+ // -inline-shorthand prefix:arg1:part1:arg2:part2...:(slot):postfix:
1833
+ delayContentExpansion: true,
1834
+ alwaysTryExpand: true,
1835
+ beforeParseContent(node, cxt) {
1836
+ const store = cxt.get(builtins);
1837
+ const check = parseDefineArguments2(
1838
+ 7 /* BlockModifier */,
1839
+ node,
1840
+ store.blockSlotDelayedStack
1841
+ );
1842
+ if (check) return check;
1843
+ debug.trace("entering block shorthand definition", node.state.name);
1844
+ return [];
1845
+ },
1846
+ afterParseContent(node, cxt) {
1847
+ if (!node.state) return [];
1848
+ const store = cxt.get(builtins);
1849
+ const pop = store.blockSlotDelayedStack.pop();
1850
+ assert(pop === node.state.signature);
1851
+ debug.trace("leaving inline shorthand definition", node.state.name);
1852
+ return [];
1853
+ },
1854
+ prepareExpand(node, cxt, immediate) {
1855
+ if (!immediate || !node.state) return [];
1856
+ const arg = node.arguments[0];
1857
+ if (!node.state)
1858
+ return [new InvalidArgumentMessage(arg.location)];
1859
+ const msgs = node.state.msgs;
1860
+ if (cxt.config.blockShorthands.has(node.state.name))
1861
+ msgs.push(new NameAlreadyDefinedMessage(arg.location, node.state.name));
1862
+ return msgs;
1863
+ },
1864
+ expand(node, cxt, immediate) {
1865
+ if (!immediate || !node.state) return void 0;
1866
+ const name = "<block shorthand>";
1867
+ const parts = node.state.parts.map((x) => x[1]);
1868
+ const mod = customModifier(
1869
+ 7 /* BlockModifier */,
1870
+ name,
1871
+ node.state.signature,
1872
+ node.content
1529
1873
  );
1874
+ const shorthand = {
1875
+ name: node.state.name,
1876
+ postfix: node.state.postfix,
1877
+ mod,
1878
+ parts
1879
+ };
1880
+ if (cxt.config.blockShorthands.has(node.state.name))
1881
+ cxt.config.blockShorthands.remove(node.state.name);
1882
+ cxt.config.blockShorthands.add(shorthand);
1883
+ debug.info(() => "created block shorthand: " + debugPrint.blockShorthand(shorthand));
1884
+ return [];
1530
1885
  }
1531
- return [];
1532
1886
  }
1533
- });
1887
+ );
1888
+ var DefineInlineShorthandMod = new SystemModifierDefinition(
1889
+ "inline-shorthand",
1890
+ 0 /* Normal */,
1891
+ {
1892
+ // -inline-shorthand prefix:arg1:part1:arg2:part2...:(slot):postfix:
1893
+ delayContentExpansion: true,
1894
+ alwaysTryExpand: true,
1895
+ beforeParseContent(node, cxt) {
1896
+ const store = cxt.get(builtins);
1897
+ const check = parseDefineArguments2(
1898
+ 6 /* InlineModifier */,
1899
+ node,
1900
+ store.inlineSlotDelayedStack
1901
+ );
1902
+ if (check) return check;
1903
+ debug.trace("entering inline shorthand definition", node.state.name);
1904
+ return [];
1905
+ },
1906
+ afterParseContent(node, cxt) {
1907
+ if (!node.state) return [];
1908
+ const store = cxt.get(builtins);
1909
+ const pop = store.inlineSlotDelayedStack.pop();
1910
+ assert(pop === node.state.signature);
1911
+ debug.trace("leaving inline shorthand definition", node.state.name);
1912
+ return [];
1913
+ },
1914
+ prepareExpand(node, cxt, immediate) {
1915
+ if (!immediate || !node.state) return [];
1916
+ const arg = node.arguments[0];
1917
+ if (!node.state)
1918
+ return [new InvalidArgumentMessage(arg.location)];
1919
+ const msgs = node.state.msgs;
1920
+ if (cxt.config.inlineShorthands.has(node.state.name))
1921
+ msgs.push(new NameAlreadyDefinedMessage(arg.location, node.state.name));
1922
+ node.state.definition = makeInlineDefinition(node, msgs);
1923
+ return msgs;
1924
+ },
1925
+ expand(node, cxt, immediate) {
1926
+ if (!immediate || !node.state) return void 0;
1927
+ const name = "<inline shorthand>";
1928
+ const parts = node.state.parts.map((x) => x[1]);
1929
+ const mod = customModifier(
1930
+ 6 /* InlineModifier */,
1931
+ name,
1932
+ node.state.signature,
1933
+ node.state.definition
1934
+ );
1935
+ const shorthand = {
1936
+ name: node.state.name,
1937
+ postfix: node.state.postfix,
1938
+ mod,
1939
+ parts
1940
+ };
1941
+ if (cxt.config.inlineShorthands.has(node.state.name))
1942
+ cxt.config.inlineShorthands.remove(node.state.name);
1943
+ cxt.config.inlineShorthands.add(shorthand);
1944
+ debug.info(() => "created inline shorthand: " + debugPrint.inlineShorthand(shorthand));
1945
+ return [];
1946
+ }
1947
+ }
1948
+ );
1534
1949
 
1535
- // src/builtin/pushpop.ts
1536
- var PushNotationMod = new SystemModifierDefinition(
1537
- "push-notation",
1538
- 2 /* Marker */,
1950
+ // src/builtin/module.ts
1951
+ function getDefs(cxt) {
1952
+ const data = cxt.get(builtins);
1953
+ return {
1954
+ usedModules: new Set(data.usedModules),
1955
+ blocks: cxt.config.blockModifiers.toSet(),
1956
+ inlines: cxt.config.inlineModifiers.toSet(),
1957
+ inlineShorthands: cxt.config.inlineShorthands.toSet(),
1958
+ blockShorthands: cxt.config.blockShorthands.toSet()
1959
+ };
1960
+ }
1961
+ function applyDefs(cxt, defs) {
1962
+ const data = cxt.get(builtins);
1963
+ data.usedModules = new Set(defs.usedModules);
1964
+ cxt.config.blockModifiers = new NameManager(defs.blocks);
1965
+ cxt.config.inlineModifiers = new NameManager(defs.inlines);
1966
+ cxt.config.inlineShorthands = new NameManager(defs.inlineShorthands);
1967
+ cxt.config.blockShorthands = new NameManager(defs.blockShorthands);
1968
+ }
1969
+ function add(snew, sold, transform) {
1970
+ let newNames = new Set([...snew].map((x) => x.name));
1971
+ let out = new Set(snew);
1972
+ let overlap = [];
1973
+ for (const x of sold) {
1974
+ if (newNames.has(x.name))
1975
+ overlap.push(x);
1976
+ else
1977
+ out.add(x);
1978
+ }
1979
+ return [out, overlap.map(transform).join(", ")];
1980
+ }
1981
+ function diffDef(cnew, cold) {
1982
+ return {
1983
+ usedModules: cnew.usedModules.difference(cold.usedModules),
1984
+ blocks: cnew.blocks.difference(cold.blocks),
1985
+ inlines: cnew.inlines.difference(cold.inlines),
1986
+ inlineShorthands: cnew.inlineShorthands.difference(cold.inlineShorthands),
1987
+ blockShorthands: cnew.blockShorthands.difference(cold.blockShorthands)
1988
+ };
1989
+ }
1990
+ function addDef(cnew, cold) {
1991
+ let [blocks, s1] = add(cnew.blocks, cold.blocks, debugPrint.blockModifier);
1992
+ let [inlines, s2] = add(cnew.inlines, cold.inlines, debugPrint.inlineModifier);
1993
+ let [inlineShorthands, s3] = add(cnew.inlineShorthands, cold.inlineShorthands, debugPrint.inlineShorthand);
1994
+ let [blockShorthands, s4] = add(cnew.blockShorthands, cold.blockShorthands, debugPrint.blockShorthand);
1995
+ return [
1996
+ {
1997
+ usedModules: cnew.usedModules.union(cold.usedModules),
1998
+ blocks,
1999
+ inlines,
2000
+ inlineShorthands,
2001
+ blockShorthands
2002
+ },
2003
+ (s1 ? s1 + "; " : "") + (s2 ? s2 + "; " : "") + (s3 ? "inline shorthand " + s3 + "; " : "") + (s4 ? "block shorthand " + s4 : "")
2004
+ ];
2005
+ }
2006
+ var ModuleMod = new BlockModifierDefinition(
2007
+ "module",
2008
+ 0 /* Normal */,
1539
2009
  {
1540
- expand(_, cxt) {
2010
+ expand(node) {
2011
+ return [];
2012
+ },
2013
+ beforeParseContent(node, cxt) {
2014
+ const check = checkArguments(node, 1);
2015
+ if (check) return check;
2016
+ const data = cxt.get(builtins);
2017
+ const name = node.arguments[0].expansion;
2018
+ const defs = getDefs(cxt);
2019
+ if (data.insideModule !== void 0) {
2020
+ return [new NoNestedModuleMessage(node.head)];
2021
+ }
2022
+ let msgs = [];
2023
+ node.state = { name, defs };
2024
+ data.insideModule = name;
2025
+ if (data.modules.has(name)) {
2026
+ const [added, msg] = addDef(defs, data.modules.get(name));
2027
+ if (msg) msgs.push(
2028
+ new OverwriteDefinitionsMessage(node.head, msg)
2029
+ );
2030
+ applyDefs(cxt, added);
2031
+ debug.trace("entering defs for module", name, "(earlier data loaded)");
2032
+ } else {
2033
+ debug.trace("entering defs for module", name);
2034
+ }
2035
+ return msgs;
2036
+ },
2037
+ afterParseContent(node, cxt) {
2038
+ if (!node.state) return [];
1541
2039
  const data = cxt.get(builtins);
1542
- data.notationStack.push({
1543
- blocks: cxt.config.blockModifiers.toArray(),
1544
- inlines: cxt.config.inlineModifiers.toArray()
1545
- });
2040
+ data.insideModule = void 0;
2041
+ data.modules.set(
2042
+ node.state.name,
2043
+ diffDef(getDefs(cxt), node.state.defs)
2044
+ );
2045
+ applyDefs(cxt, node.state.defs);
2046
+ debug.trace("exiting defs for module", node.state.name);
1546
2047
  return [];
1547
2048
  }
1548
2049
  }
1549
2050
  );
1550
- var PopNotationMod = new SystemModifierDefinition(
1551
- "pop-notation",
1552
- 2 /* Marker */,
2051
+ var UseSystemMod = new SystemModifierDefinition(
2052
+ "use",
2053
+ 2 /* None */,
1553
2054
  {
1554
2055
  prepareExpand(node, cxt) {
2056
+ const check = checkArguments(node, 1);
2057
+ if (check) return check;
1555
2058
  const data = cxt.get(builtins);
1556
- const result = data.notationStack.pop();
1557
- if (!result) return [
1558
- new CannotPopNotationMessage(node.start, node.end - node.start)
1559
- ];
1560
- cxt.config.blockModifiers = new NameManager(result.blocks);
1561
- cxt.config.inlineModifiers = new NameManager(result.inlines);
2059
+ const name = node.arguments[0];
2060
+ if (!data.modules.has(name.expansion))
2061
+ return [new InvalidArgumentMessage(name.location)];
2062
+ if (data.insideModule === name.expansion)
2063
+ return [new CannotUseModuleInSelfMessage(name.location)];
2064
+ const [added, msg] = addDef(data.modules.get(name.expansion), getDefs(cxt));
2065
+ node.state = added;
2066
+ if (msg)
2067
+ return [new OverwriteDefinitionsMessage(node.head, msg)];
1562
2068
  return [];
1563
2069
  },
1564
- expand() {
2070
+ expand(node, cxt) {
2071
+ if (node.state)
2072
+ applyDefs(cxt, node.state);
1565
2073
  return [];
1566
2074
  }
1567
2075
  }
1568
2076
  );
2077
+ var UseBlockMod = new BlockModifierDefinition(
2078
+ "use",
2079
+ 0 /* Normal */,
2080
+ {
2081
+ beforeParseContent(node, cxt) {
2082
+ const check = checkArguments(node, 1);
2083
+ if (check) return check;
2084
+ const data = cxt.get(builtins);
2085
+ const name = node.arguments[0];
2086
+ if (!data.modules.has(name.expansion))
2087
+ return [new InvalidArgumentMessage(name.location)];
2088
+ if (data.insideModule === name.expansion)
2089
+ return [new CannotUseModuleInSelfMessage(name.location)];
2090
+ const old = getDefs(cxt);
2091
+ const [added, msg] = addDef(data.modules.get(name.expansion), old);
2092
+ applyDefs(cxt, added);
2093
+ node.state = { old };
2094
+ if (msg)
2095
+ return [new OverwriteDefinitionsMessage(node.head, msg)];
2096
+ return [];
2097
+ },
2098
+ afterParseContent(node, cxt) {
2099
+ if (node.state)
2100
+ applyDefs(cxt, node.state.old);
2101
+ return [];
2102
+ },
2103
+ expand(node) {
2104
+ return node.content;
2105
+ }
2106
+ }
2107
+ );
1569
2108
 
1570
2109
  // src/builtin/slot.ts
1571
- function slotModifier(type) {
1572
- const mod = type == 7 /* BlockModifier */ ? new BlockModifierDefinition("slot", 2 /* Marker */) : new InlineModifierDefinition("slot", 2 /* Marker */);
2110
+ function slotModifier(name, type, preformatted, inject) {
2111
+ const mod = type == 7 /* BlockModifier */ ? new BlockModifierDefinition(name, 2 /* None */) : new InlineModifierDefinition(name, 2 /* None */);
1573
2112
  const isInline = type == 6 /* InlineModifier */;
1574
2113
  mod.alwaysTryExpand = true;
1575
2114
  mod.prepareExpand = (node, cxt, immediate) => {
1576
2115
  if (node.state) return [];
1577
- const check = checkArgumentLength(node, 0, 1);
1578
- if (check && immediate) {
2116
+ function processSignature(s) {
2117
+ if (s.preformatted === void 0) {
2118
+ s.preformatted = preformatted;
2119
+ debug.trace("set preformatted to ", preformatted);
2120
+ } else if (s.preformatted !== preformatted) {
2121
+ return [new EitherNormalOrPreMessage(node.location)];
2122
+ }
2123
+ return [];
2124
+ }
2125
+ const check = inject ? checkArguments(node, 1, 2) : checkArguments(node, 0, 1);
2126
+ if (check) {
1579
2127
  node.state = { ok: false };
1580
2128
  return check;
1581
2129
  }
1582
- const store = cxt.get(builtins);
1583
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1584
- let id = "";
1585
- if (node.arguments.length == 1) {
1586
- const arg = node.arguments[0];
1587
- if (!arg.expansion) {
2130
+ const msgs = (() => {
2131
+ const store = cxt.get(builtins);
2132
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
2133
+ const stack = isInline ? store.inlineSlotDelayedStack : store.blockSlotDelayedStack;
2134
+ if (data.length == 0 && stack.length == 0) {
1588
2135
  node.state = { ok: false };
1589
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
2136
+ return [new SlotUsedOutsideDefinitionMessage(node.location)];
2137
+ }
2138
+ if (node.arguments.length == (inject ? 1 : 0)) {
2139
+ let signature2 = stack.at(-1);
2140
+ if (signature2) return processSignature(signature2);
2141
+ node.state = { ok: true, data: data.at(-1), index: data.length - 1 };
2142
+ return;
2143
+ }
2144
+ const id = node.arguments[0].expansion;
2145
+ let signature = stack.find((x) => x.slotName == id);
2146
+ if (signature) return processSignature(signature);
2147
+ for (let i = data.length - 1; i >= 0; i--) if (data[i].slotName === id) {
2148
+ node.state = { ok: true, data: data[i], index: i };
2149
+ return;
1590
2150
  }
1591
- id = arg.expansion;
1592
- }
1593
- if (data.length == 0) {
1594
2151
  if (immediate) {
1595
2152
  node.state = { ok: false };
1596
- return [new SlotUsedOutsideDefinitionMessage(node.start, node.head.end - node.start)];
2153
+ const arg = node.arguments[0];
2154
+ return [new InvalidArgumentMessage(arg.location, id)];
1597
2155
  }
1598
- return [];
1599
- }
1600
- const stack = isInline ? store.inlineSlotDelayedStack : store.blockSlotDelayedStack;
1601
- if (stack.includes(id)) {
1602
- debug.trace("delaying", id == "" ? "unnamed slot" : "slot: " + id);
1603
- return [];
1604
- }
1605
- if (node.arguments.length == 0) {
1606
- node.state = { ok: true, data: data.at(-1), index: data.length - 1 };
1607
- return [];
1608
- }
1609
- for (let i = data.length - 1; i >= 0; i--) if (data[i][0] == id) {
1610
- node.state = { ok: true, data: data[i], index: i };
1611
- return [];
1612
- }
1613
- if (immediate) {
1614
- node.state = { ok: false };
1615
- const arg = node.arguments[0];
1616
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start, id)];
2156
+ })();
2157
+ if (inject) {
2158
+ const arg = node.arguments.at(-1);
2159
+ const modName = arg.expansion;
2160
+ const mod2 = (isInline ? cxt.config.inlineModifiers : cxt.config.blockModifiers).get(modName);
2161
+ if (!mod2) {
2162
+ node.state = { ok: false };
2163
+ return [new UnknownModifierMessage(arg.location, modName)];
2164
+ }
2165
+ if (node.state?.ok)
2166
+ node.state.injectMod = mod2;
1617
2167
  }
2168
+ if (msgs) return msgs;
1618
2169
  return [];
1619
2170
  };
1620
2171
  mod.expand = (node, cxt) => {
1621
2172
  if (!node.state) return void 0;
1622
2173
  if (!node.state.ok) return [];
1623
- return cloneNodes(node.state.data[1].slotContent);
2174
+ let cloned = cloneNodes(node.state.data.slotContent);
2175
+ if (inject) {
2176
+ const mod2 = node.state.injectMod;
2177
+ const modNode = {
2178
+ type,
2179
+ mod: mod2,
2180
+ location: node.location,
2181
+ head: node.head,
2182
+ arguments: [],
2183
+ // TODO: enable injecting args
2184
+ content: cloned
2185
+ };
2186
+ return [modNode];
2187
+ } else return cloned;
1624
2188
  };
1625
2189
  mod.beforeProcessExpansion = (node, cxt) => {
1626
2190
  if (!node.state?.ok) return [];
1627
2191
  const store = cxt.get(builtins);
1628
- debug.trace("temporarily removed slot data for", node.state.data[1].mod.name);
1629
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
2192
+ debug.trace("temporarily removed slot data for", node.state.data.mod.name);
2193
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1630
2194
  data.splice(node.state.index, 1);
1631
2195
  return [];
1632
2196
  };
1633
2197
  mod.afterProcessExpansion = (node, cxt) => {
1634
2198
  if (!node.state?.ok) return [];
1635
2199
  const store = cxt.get(builtins);
1636
- debug.trace("reinstated slot data for", node.state.data[1].mod.name);
1637
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
2200
+ debug.trace("reinstated slot data for", node.state.data.mod.name);
2201
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1638
2202
  data.splice(node.state.index, 0, node.state.data);
1639
2203
  return [];
1640
2204
  };
1641
2205
  return mod;
1642
2206
  }
1643
- var SlotBlockMod = slotModifier(7 /* BlockModifier */);
1644
- var SlotInlineMod = slotModifier(6 /* InlineModifier */);
2207
+ var SlotBlockMod = slotModifier("slot", 7 /* BlockModifier */, false, false);
2208
+ var SlotInlineMod = slotModifier("slot", 6 /* InlineModifier */, false, false);
2209
+ var PreSlotBlockMod = slotModifier("pre-slot", 7 /* BlockModifier */, true, false);
2210
+ var PreSlotInlineMod = slotModifier("pre-slot", 6 /* InlineModifier */, true, false);
2211
+ var InjectPreSlotBlockMod = slotModifier(
2212
+ "inject-pre-slot",
2213
+ 7 /* BlockModifier */,
2214
+ true,
2215
+ true
2216
+ );
2217
+ var InjectPreSlotInlineMod = slotModifier(
2218
+ "inject-pre-slot",
2219
+ 6 /* InlineModifier */,
2220
+ true,
2221
+ true
2222
+ );
1645
2223
 
1646
2224
  // src/builtin/var.ts
1647
2225
  function resolveId(id, cxt) {
1648
2226
  const store = cxt.get(builtins);
2227
+ if (store.inlineSlotDelayedStack.find((x) => x.args.includes(id)) || store.blockSlotDelayedStack.find((x) => x.args.includes(id))) {
2228
+ debug.trace("delaying the yet unknown argument", id);
2229
+ return void 0;
2230
+ }
1649
2231
  let value = void 0;
1650
- for (let i = store.inlineSlotData.length - 1; i >= 0; i--) {
1651
- const [_, data] = store.inlineSlotData[i];
2232
+ for (let i = store.inlineInstantiationData.length - 1; i >= 0; i--) {
2233
+ const data = store.inlineInstantiationData[i];
1652
2234
  if ((value = data.args.get(id)) !== void 0)
1653
2235
  break;
1654
2236
  }
1655
- for (let i = store.blockSlotData.length - 1; i >= 0; i--) {
1656
- const [_, data] = store.blockSlotData[i];
2237
+ for (let i = store.blockInstantiationData.length - 1; i >= 0; i--) {
2238
+ const data = store.blockInstantiationData[i];
1657
2239
  if ((value = data.args.get(id)) !== void 0)
1658
2240
  break;
1659
2241
  }
@@ -1661,53 +2243,62 @@ function resolveId(id, cxt) {
1661
2243
  value = cxt.variables.get(id);
1662
2244
  return value;
1663
2245
  }
1664
- var GetVarInlineMod = new InlineModifierDefinition("$", 2 /* Marker */, {
1665
- // .$:id
1666
- prepareExpand(node, cxt) {
1667
- const check = checkArguments(node, 1);
1668
- if (check) return check;
1669
- const arg = node.arguments[0];
1670
- const id = arg.expansion;
1671
- if (id == "")
1672
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1673
- const value = resolveId(id, cxt);
1674
- if (value === void 0)
1675
- return [new UndefinedVariableMessage(arg.start, arg.end - arg.start, id)];
1676
- node.state = { value };
1677
- return [];
1678
- },
1679
- expand(node, cxt) {
1680
- if (!node.state) return [];
1681
- return [{ type: 3 /* Text */, content: node.state.value, start: -1, end: -1 }];
2246
+ var GetVarInlineMod = new InlineModifierDefinition(
2247
+ "$",
2248
+ 2 /* None */,
2249
+ {
2250
+ alwaysTryExpand: true,
2251
+ // .$:id
2252
+ prepareExpand(node, cxt, immediate) {
2253
+ const check = checkArguments(node, 1);
2254
+ if (check)
2255
+ return immediate ? check : [];
2256
+ const arg = node.arguments[0];
2257
+ const id = arg.expansion;
2258
+ if (id == "")
2259
+ return immediate ? [new InvalidArgumentMessage(arg.location)] : [];
2260
+ const value = resolveId(id, cxt);
2261
+ if (value === void 0)
2262
+ return immediate ? [new UndefinedVariableMessage(arg.location, id)] : [];
2263
+ node.state = { value };
2264
+ return [];
2265
+ },
2266
+ expand(node, _, immediate) {
2267
+ if (!node.state) return immediate ? [] : void 0;
2268
+ return [{ type: 3 /* Text */, content: node.state.value, location: node.location }];
2269
+ }
1682
2270
  }
1683
- });
1684
- var PrintInlineMod = new InlineModifierDefinition("print", 2 /* Marker */, {
1685
- // .print:args...
1686
- prepareExpand(node) {
1687
- const check = checkArguments(node);
1688
- if (check) return check;
1689
- node.state = { value: node.arguments.map((x) => x.expansion).join("") };
1690
- return [];
1691
- },
1692
- expand(node) {
1693
- if (!node.state) return [];
1694
- return [{ type: 3 /* Text */, content: node.state.value, start: -1, end: -1 }];
2271
+ );
2272
+ var PrintInlineMod = new InlineModifierDefinition(
2273
+ "print",
2274
+ 2 /* None */,
2275
+ {
2276
+ // .print:args...
2277
+ prepareExpand(node) {
2278
+ const check = checkArguments(node);
2279
+ if (check) return check;
2280
+ node.state = { value: node.arguments.map((x) => x.expansion).join("") };
2281
+ return [];
2282
+ },
2283
+ expand(node) {
2284
+ if (!node.state) return [];
2285
+ return [{ type: 3 /* Text */, content: node.state.value, location: node.location }];
2286
+ }
1695
2287
  }
1696
- });
2288
+ );
1697
2289
  var GetVarInterpolator = new ArgumentInterpolatorDefinition(
1698
2290
  "$(",
1699
2291
  ")",
1700
2292
  {
1701
2293
  alwaysTryExpand: true,
1702
- expand(content, cxt, immediate) {
2294
+ expand(content, cxt) {
1703
2295
  const result = resolveId(content, cxt);
1704
- if (result === void 0) debug.trace("var interp failed:", content);
1705
- else debug.trace(`$(${content}) --> ${result}`);
2296
+ if (result !== void 0) debug.trace(`$(${content}) --> ${result}`);
1706
2297
  return result;
1707
2298
  }
1708
2299
  }
1709
2300
  );
1710
- var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
2301
+ var VarMod = new SystemModifierDefinition("var", 2 /* None */, {
1711
2302
  // .var id:value
1712
2303
  prepareExpand(node, cxt) {
1713
2304
  const check = checkArguments(node, 2);
@@ -1715,7 +2306,7 @@ var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
1715
2306
  const arg = node.arguments[0];
1716
2307
  const id = arg.expansion;
1717
2308
  if (id == "")
1718
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
2309
+ return [new InvalidArgumentMessage(arg.location)];
1719
2310
  node.state = {
1720
2311
  id,
1721
2312
  value: node.arguments[1].expansion
@@ -1732,13 +2323,576 @@ var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
1732
2323
  });
1733
2324
 
1734
2325
  // src/builtin/builtin.ts
1735
- var basic = new Configuration();
1736
- basic.initializers = [initParseContext];
1737
- basic.systemModifiers.add(DefineBlockMod, DefineInlineMod, VarMod, PushNotationMod, PopNotationMod);
1738
- basic.blockModifiers.add(SlotBlockMod);
1739
- basic.inlineModifiers.add(SlotInlineMod, GetVarInlineMod, PrintInlineMod);
1740
- basic.argumentInterpolators.add(GetVarInterpolator);
1741
- var BuiltinConfiguration = Object.freeze(basic);
2326
+ var builtin = new Configuration();
2327
+ builtin.initializers = [initParseContext];
2328
+ builtin.systemModifiers.add(
2329
+ DefineBlockMod,
2330
+ DefineInlineMod,
2331
+ DefineBlockShorthandMod,
2332
+ DefineInlineShorthandMod,
2333
+ VarMod,
2334
+ UseSystemMod
2335
+ );
2336
+ builtin.blockModifiers.add(
2337
+ SlotBlockMod,
2338
+ PreSlotBlockMod,
2339
+ InjectPreSlotBlockMod,
2340
+ ModuleMod,
2341
+ UseBlockMod
2342
+ );
2343
+ builtin.inlineModifiers.add(
2344
+ SlotInlineMod,
2345
+ PreSlotInlineMod,
2346
+ InjectPreSlotInlineMod,
2347
+ GetVarInlineMod,
2348
+ PrintInlineMod
2349
+ );
2350
+ builtin.argumentInterpolators.add(GetVarInterpolator);
2351
+ var BuiltinConfiguration = Object.freeze(builtin);
2352
+
2353
+ // src/default/bullets.ts
2354
+ var bulletItemBlock = new BlockModifierDefinition(
2355
+ "bullet-item",
2356
+ 0 /* Normal */,
2357
+ { roleHint: void 0 }
2358
+ );
2359
+ var orderedListItemBlock = new BlockModifierDefinition(
2360
+ "ordered-item",
2361
+ 0 /* Normal */,
2362
+ {
2363
+ roleHint: void 0,
2364
+ prepareExpand(node) {
2365
+ let msgs = checkArguments(node, 0, 1);
2366
+ if (msgs) return msgs;
2367
+ let arg = node.arguments[0];
2368
+ let num = Number.parseInt(arg.expansion);
2369
+ if (isNaN(num)) return [
2370
+ new InvalidArgumentMessage(arg.location, "should be a number")
2371
+ ];
2372
+ node.state = num;
2373
+ return [];
2374
+ }
2375
+ }
2376
+ );
2377
+ var subItemBlock = new BlockModifierDefinition(
2378
+ "subitem",
2379
+ 0 /* Normal */,
2380
+ { roleHint: void 0 }
2381
+ );
2382
+ var BulletBlocks = [bulletItemBlock, orderedListItemBlock, subItemBlock];
2383
+ var BulletBlockRenderersHTML = [
2384
+ [bulletItemBlock, (node, cxt) => {
2385
+ return `<li>${cxt.state.render(node.content, cxt)}</li>`;
2386
+ }],
2387
+ [subItemBlock, (node, cxt) => {
2388
+ return `<div class='subitem'>${cxt.state.render(node.content, cxt)}</div>`;
2389
+ }],
2390
+ [orderedListItemBlock, (node, cxt) => {
2391
+ if (node.state === void 0)
2392
+ return cxt.state.invalidBlock(node, "bad format");
2393
+ return `<li value='${node.state}'>${cxt.state.render(node.content, cxt)}</li>`;
2394
+ }]
2395
+ ];
2396
+
2397
+ // src/default/headings.ts
2398
+ var headingBlock = new BlockModifierDefinition(
2399
+ "heading",
2400
+ 0 /* Normal */,
2401
+ {
2402
+ delayContentExpansion: true,
2403
+ roleHint: "heading",
2404
+ prepareExpand(node) {
2405
+ let msgs = checkArguments(node, 0, 1);
2406
+ if (msgs) return msgs;
2407
+ msgs = onlyPermitSingleBlock(node);
2408
+ if (msgs) return msgs;
2409
+ msgs = onlyPermitSimpleParagraphs(node);
2410
+ if (msgs) return msgs;
2411
+ if (node.arguments.length == 1) {
2412
+ let arg = node.arguments[0];
2413
+ let num = Number.parseInt(arg.expansion);
2414
+ if (isNaN(num)) return [
2415
+ new InvalidArgumentMessage(arg.location, "should be a number between 1 and 6")
2416
+ ];
2417
+ node.state = num;
2418
+ } else {
2419
+ node.state = 1;
2420
+ }
2421
+ return [];
2422
+ }
2423
+ }
2424
+ );
2425
+ var numberedHeadingBlock = new BlockModifierDefinition(
2426
+ "numbered-heading",
2427
+ 0 /* Normal */,
2428
+ {
2429
+ delayContentExpansion: true,
2430
+ roleHint: "heading",
2431
+ prepareExpand(node) {
2432
+ let msgs = checkArguments(node, 1);
2433
+ if (msgs) return msgs;
2434
+ msgs = onlyPermitSingleBlock(node);
2435
+ if (msgs) return msgs;
2436
+ msgs = onlyPermitSimpleParagraphs(node);
2437
+ if (msgs) return msgs;
2438
+ let arg = node.arguments[0];
2439
+ let split = arg.expansion.trim().split(".").filter((x) => x.length > 0);
2440
+ if (split.length == 0 || split.length > 6) return [
2441
+ new InvalidArgumentMessage(arg.location, "heading level must be between 1 and 6")
2442
+ ];
2443
+ node.state = split;
2444
+ debug.trace("numbered-heading", node.state);
2445
+ return [];
2446
+ }
2447
+ }
2448
+ );
2449
+ var HeadingBlocks = [headingBlock, numberedHeadingBlock];
2450
+ var HeadingBlockRenderersHTML = [
2451
+ [headingBlock, (node, cxt) => {
2452
+ if (node.state !== void 0) {
2453
+ assert(node.state >= 1 && node.state <= 6);
2454
+ let tag = "h" + node.state;
2455
+ let para = node.content[0];
2456
+ return `<${tag}>${cxt.state.render(para.content, cxt)}</${tag}>`;
2457
+ }
2458
+ return cxt.state.invalidBlock(node, "Bad format");
2459
+ }],
2460
+ [numberedHeadingBlock, (node, cxt) => {
2461
+ if (node.state !== void 0) {
2462
+ assert(node.state.length >= 1 && node.state.length <= 6);
2463
+ let tag = "h" + node.state.length;
2464
+ let para = node.content[0];
2465
+ return `<${tag}><span class='heading-number'>${node.state.join(".")}</span>${cxt.state.render(para.content, cxt)}</${tag}>`;
2466
+ }
2467
+ return cxt.state.invalidBlock(node, "Bad format");
2468
+ }]
2469
+ ];
2470
+
2471
+ // src/default/notes.ts
2472
+ var notes = Symbol();
2473
+ function initNotes(cxt) {
2474
+ cxt.init(notes, {
2475
+ systems: /* @__PURE__ */ new Map(),
2476
+ definitions: []
2477
+ });
2478
+ }
2479
+ var noteMarkerInline = new InlineModifierDefinition(
2480
+ "note",
2481
+ 2 /* None */,
2482
+ {
2483
+ roleHint: "link",
2484
+ prepareExpand(node) {
2485
+ let msgs = checkArguments(node, 1);
2486
+ if (msgs) return msgs;
2487
+ node.state = node.arguments[0].expansion;
2488
+ return [];
2489
+ }
2490
+ }
2491
+ );
2492
+ var noteInline = new InlineModifierDefinition(
2493
+ "note-inline",
2494
+ 0 /* Normal */,
2495
+ {
2496
+ roleHint: "quote",
2497
+ prepareExpand(node) {
2498
+ let msgs = checkArguments(node, 0, 1);
2499
+ if (msgs) return msgs;
2500
+ node.state = node.arguments.at(0)?.expansion ?? "";
2501
+ return [];
2502
+ },
2503
+ afterProcessExpansion(node, cxt) {
2504
+ if (node.state !== void 0) {
2505
+ cxt.get(notes).definitions.push({
2506
+ system: "",
2507
+ name: node.state,
2508
+ location: node.location,
2509
+ content: [{
2510
+ type: 1 /* Paragraph */,
2511
+ location: {
2512
+ source: node.location.source,
2513
+ start: node.head.end,
2514
+ end: node.location.actualEnd ?? node.location.end
2515
+ },
2516
+ content: node.content
2517
+ }]
2518
+ });
2519
+ }
2520
+ return [];
2521
+ }
2522
+ }
2523
+ );
2524
+ var noteBlock = new BlockModifierDefinition(
2525
+ "note",
2526
+ 0 /* Normal */,
2527
+ {
2528
+ roleHint: "quote",
2529
+ prepareExpand(node) {
2530
+ let msgs = checkArguments(node, 1);
2531
+ if (msgs) return msgs;
2532
+ node.state = node.arguments[0].expansion;
2533
+ return [];
2534
+ },
2535
+ afterProcessExpansion(node, cxt) {
2536
+ if (node.state !== void 0) {
2537
+ let content = stripNode(...node.content);
2538
+ debug.trace(`add note: system=<${""}> name=${node.state} @${node.location.start}`);
2539
+ debug.trace(`-->
2540
+ `, debugPrint.node(...content));
2541
+ cxt.get(notes).definitions.push({
2542
+ system: "",
2543
+ name: node.state,
2544
+ location: node.location,
2545
+ content
2546
+ });
2547
+ }
2548
+ node.expansion = [];
2549
+ return [];
2550
+ }
2551
+ }
2552
+ );
2553
+ var NoteBlocks = [noteBlock];
2554
+ var NoteInlines = [noteInline, noteMarkerInline];
2555
+ var NoteInlineRenderersHTML = [
2556
+ [noteMarkerInline, (node, cxt) => {
2557
+ if (node.state === void 0)
2558
+ return cxt.state.invalidInline(node, "bad format");
2559
+ const defs = cxt.parseContext.get(notes).definitions;
2560
+ const note = defs.findIndex((x) => (
2561
+ /*x.position >= node.start &&*/
2562
+ x.name == node.state
2563
+ ));
2564
+ if (note < 0)
2565
+ return `<sup class='note invalid'>Not found: ${node.state}</sup>`;
2566
+ return `<sup class='note' id='notemarker-id-${note}'><a href='#note-id-${note}'>${node.state}</a></sup>`;
2567
+ }]
2568
+ ];
2569
+ var NotesFooterPlugin = (cxt) => {
2570
+ let defs = cxt.parseContext.get(notes).definitions;
2571
+ if (defs.length == 0) return void 0;
2572
+ return `<hr/>
2573
+ <section class='notes'>
2574
+ ${defs.map((x, i) => `<section class='note' id='note-id-${i}'>
2575
+ <div class='note-name'><p><a href='#notemarker-id-${i}'>${x.name}</a></p></div>
2576
+ <div class='note-content'>${cxt.state.render(x.content, cxt)}</div></section>`).join("\n")}
2577
+ </section>`;
2578
+ };
2579
+
2580
+ // src/default/code.ts
2581
+ var CodeBlock = new BlockModifierDefinition(
2582
+ "code",
2583
+ 1 /* Preformatted */,
2584
+ { roleHint: "code" }
2585
+ );
2586
+ var CodeInline = new InlineModifierDefinition(
2587
+ "code",
2588
+ 1 /* Preformatted */,
2589
+ { roleHint: "code" }
2590
+ );
2591
+ var CodeBlockRendererHTML = [CodeBlock, (node, cxt) => {
2592
+ return `<pre><code>${cxt.state.render(node.content, cxt)}</code></pre>`;
2593
+ }];
2594
+ var CodeInlineRendererHTML = [CodeInline, (node, cxt) => {
2595
+ return `<span><code>${cxt.state.render(node.content, cxt)}</code></span>`;
2596
+ }];
2597
+
2598
+ // src/default/quotes.ts
2599
+ var quoteBlock = new BlockModifierDefinition(
2600
+ "quote",
2601
+ 0 /* Normal */,
2602
+ { roleHint: "quote" }
2603
+ );
2604
+ var epitaphBlock = new BlockModifierDefinition(
2605
+ "epitaph",
2606
+ 0 /* Normal */,
2607
+ { roleHint: "quote" }
2608
+ );
2609
+ var attributionBlock = new BlockModifierDefinition(
2610
+ "by",
2611
+ 0 /* Normal */,
2612
+ {
2613
+ roleHint: "quote",
2614
+ prepareExpand(node) {
2615
+ let msgs = onlyPermitSingleBlock(node);
2616
+ if (msgs) return msgs;
2617
+ msgs = onlyPermitSimpleParagraphs(node);
2618
+ if (msgs) return msgs;
2619
+ node.state = true;
2620
+ return [];
2621
+ }
2622
+ }
2623
+ );
2624
+ var QuoteBlocks = [quoteBlock, epitaphBlock, attributionBlock];
2625
+ var QuoteBlockRenderersHTML = [
2626
+ [quoteBlock, (node, cxt) => {
2627
+ return `<blockquote>${cxt.state.render(node.content, cxt)}</blockquote>`;
2628
+ }],
2629
+ [epitaphBlock, (node, cxt) => {
2630
+ return `<blockquote class='epitaph'>${cxt.state.render(node.content, cxt)}</blockquote>`;
2631
+ }],
2632
+ [attributionBlock, (node, cxt) => {
2633
+ if (!node.state)
2634
+ return cxt.state.invalidBlock(node, "bad format");
2635
+ let para = node.content[0];
2636
+ return `<p class='attribution'>${cxt.state.render(para.content, cxt)}</p>`;
2637
+ }]
2638
+ ];
2639
+
2640
+ // src/default/inline-styles.ts
2641
+ var emphasisInline = new InlineModifierDefinition(
2642
+ "emphasis",
2643
+ 0 /* Normal */,
2644
+ { roleHint: "emphasis" }
2645
+ );
2646
+ var keywordInline = new InlineModifierDefinition(
2647
+ "keyword",
2648
+ 0 /* Normal */,
2649
+ { roleHint: "keyword" }
2650
+ );
2651
+ var highlightInline = new InlineModifierDefinition(
2652
+ "highlight",
2653
+ 0 /* Normal */,
2654
+ { roleHint: "highlight" }
2655
+ );
2656
+ var commentaryInline = new InlineModifierDefinition(
2657
+ "commentary",
2658
+ 0 /* Normal */,
2659
+ { roleHint: "commentary" }
2660
+ );
2661
+ var InlineStyles = [emphasisInline, keywordInline, highlightInline, commentaryInline];
2662
+ var InlineStyleRenderersHTML = [
2663
+ [emphasisInline, (node, cxt) => {
2664
+ return `<em>${cxt.state.render(node.content, cxt)}</em>`;
2665
+ }],
2666
+ [keywordInline, (node, cxt) => {
2667
+ return `<b>${cxt.state.render(node.content, cxt)}</b>`;
2668
+ }],
2669
+ [highlightInline, (node, cxt) => {
2670
+ return `<mark>${cxt.state.render(node.content, cxt)}</mark>`;
2671
+ }],
2672
+ [commentaryInline, (node, cxt) => {
2673
+ return `<span class='commentary'>${cxt.state.render(node.content, cxt)}</span>`;
2674
+ }]
2675
+ ];
2676
+
2677
+ // src/default/misc.ts
2678
+ var rubyInline = new InlineModifierDefinition(
2679
+ "ruby",
2680
+ 0 /* Normal */,
2681
+ {
2682
+ roleHint: void 0,
2683
+ prepareExpand(node) {
2684
+ let msgs = checkArguments(node, 1);
2685
+ if (msgs) return msgs;
2686
+ node.state = node.arguments[0].expansion;
2687
+ return [];
2688
+ }
2689
+ }
2690
+ );
2691
+ var linkInline = new InlineModifierDefinition(
2692
+ "link",
2693
+ 0 /* Normal */,
2694
+ {
2695
+ roleHint: "link",
2696
+ prepareExpand(node) {
2697
+ let msgs = checkArguments(node, 1);
2698
+ if (msgs) return msgs;
2699
+ node.state = node.arguments[0].expansion;
2700
+ return [];
2701
+ }
2702
+ }
2703
+ );
2704
+ var imageBlock = new BlockModifierDefinition(
2705
+ "image",
2706
+ 0 /* Normal */,
2707
+ {
2708
+ roleHint: "link",
2709
+ prepareExpand(node) {
2710
+ let msgs = checkArguments(node, 1, 2);
2711
+ if (msgs) return msgs;
2712
+ msgs = onlyPermitSingleBlock(node);
2713
+ if (msgs) return msgs;
2714
+ msgs = onlyPermitSimpleParagraphs(node);
2715
+ if (msgs) return msgs;
2716
+ let url = URL.parse(node.arguments.map((x) => x.expansion).join(":"));
2717
+ if (url) node.state = url;
2718
+ return [];
2719
+ }
2720
+ }
2721
+ );
2722
+ var MiscInlines = [rubyInline, linkInline];
2723
+ var MiscBlocks = [imageBlock];
2724
+ var MiscInlineRenderersHTML = [
2725
+ [rubyInline, (node, cxt) => {
2726
+ if (node.state === void 0)
2727
+ return cxt.state.invalidInline(node, "bad format");
2728
+ return `<ruby>${cxt.state.render(node.content, cxt)}<rt>${node.state}</rt></ruby>`;
2729
+ }],
2730
+ [linkInline, (node, cxt) => {
2731
+ if (node.state === void 0)
2732
+ return cxt.state.invalidInline(node, "bad format");
2733
+ return `<a href="${encodeURI(node.state)}">${cxt.state.render(node.content, cxt)}</a>`;
2734
+ }]
2735
+ ];
2736
+ var MiscBlockRenderersHTML = [
2737
+ [imageBlock, (node, cxt) => {
2738
+ let transformed;
2739
+ if (node.state === void 0)
2740
+ return cxt.state.invalidBlock(node, "bad format");
2741
+ try {
2742
+ transformed = cxt.config.options.transformAsset(node.state);
2743
+ } catch {
2744
+ return cxt.state.invalidBlock(node, "bad format");
2745
+ }
2746
+ const img = transformed ? `<img src="${transformed}" data-original-src="${node.state.href}"/>` : `<img src="${node.state.href}"/>`;
2747
+ const para = node.content.length == 0 ? "" : "\n<figcaption>" + cxt.state.render(node.content[0].content, cxt) + "</figcaption>";
2748
+ return `<figure>${img}${para}</figure>`;
2749
+ }]
2750
+ ];
2751
+
2752
+ // src/default/vars.ts
2753
+ function createWrapper(name, varname) {
2754
+ varname = varname ?? name.toUpperCase();
2755
+ return new SystemModifierDefinition(name, 0 /* Normal */, {
2756
+ delayContentExpansion: true,
2757
+ afterProcessExpansion(node, cxt) {
2758
+ let msgs = checkArguments(node, 0);
2759
+ if (msgs) return msgs;
2760
+ let result = onlyPermitPlaintextParagraph(node);
2761
+ if (typeof result !== "string") return result;
2762
+ cxt.variables.set(varname, result);
2763
+ return [];
2764
+ }
2765
+ });
2766
+ }
2767
+ var VarWrappers = [
2768
+ createWrapper("title"),
2769
+ createWrapper("subtitle"),
2770
+ createWrapper("author"),
2771
+ createWrapper("translator"),
2772
+ createWrapper("proofreader"),
2773
+ createWrapper("typeset-by"),
2774
+ createWrapper("cover-by"),
2775
+ createWrapper("cover-img"),
2776
+ createWrapper("orig-title"),
2777
+ createWrapper("orig-link"),
2778
+ createWrapper("theme-color")
2779
+ ];
2780
+
2781
+ // src/default/default.ts
2782
+ var config = Configuration.from(BuiltinConfiguration);
2783
+ config.initializers.push(initNotes);
2784
+ config.blockModifiers.add(
2785
+ ...HeadingBlocks,
2786
+ ...BulletBlocks,
2787
+ CodeBlock,
2788
+ ...QuoteBlocks,
2789
+ ...MiscBlocks,
2790
+ ...NoteBlocks
2791
+ );
2792
+ config.inlineModifiers.add(
2793
+ CodeInline,
2794
+ ...InlineStyles,
2795
+ ...MiscInlines,
2796
+ ...NoteInlines
2797
+ );
2798
+ config.systemModifiers.add(
2799
+ ...VarWrappers
2800
+ );
2801
+ var DefaultConfiguration = Object.freeze(config);
2802
+
2803
+ // src/default/html-renderer.ts
2804
+ var HTMLRenderState = class {
2805
+ title = "";
2806
+ stylesheet = "";
2807
+ // FIXME: very unsafe!
2808
+ cssVariables = /* @__PURE__ */ new Map();
2809
+ // https://stackoverflow.com/questions/7381974
2810
+ escape(content) {
2811
+ return content.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("\n", "<br/>");
2812
+ }
2813
+ invalidBlock(node, msg) {
2814
+ let name = NodeType[node.type];
2815
+ if (node.type === 7 /* BlockModifier */)
2816
+ name += ` (${node.mod.name})`;
2817
+ return `<details class='invalid'><summary>Invalid ${this.escape(name)}</summary><i>${this.escape(msg)}</i></details>`;
2818
+ }
2819
+ invalidInline(node, msg) {
2820
+ let name = NodeType[node.type];
2821
+ if (node.type === 6 /* InlineModifier */)
2822
+ name += ` (${node.mod.name})`;
2823
+ return `<span class='invalid'>Invalid ${this.escape(name)} \u2013 <i>${this.escape(msg)}</i></span>`;
2824
+ }
2825
+ render(elems, cxt) {
2826
+ return elems.map((x) => cxt.renderEntity(x)).filter((x) => x !== void 0).join("");
2827
+ }
2828
+ };
2829
+ var htmlConfig = new RenderConfiguration(
2830
+ {
2831
+ headPlugins: [],
2832
+ headerPlugins: [],
2833
+ footerPlugins: [NotesFooterPlugin],
2834
+ transformAsset: (x) => void 0
2835
+ // postprocessPlugins: [],
2836
+ },
2837
+ (results, cxt) => {
2838
+ let styles = cxt.state.stylesheet.replaceAll(
2839
+ /var\(--(.*?)\)/g,
2840
+ (m, c) => cxt.state.cssVariables.get(c) ?? m
2841
+ );
2842
+ return `
2843
+ <!DOCTYPE html>
2844
+ <html>
2845
+ <head>
2846
+ <meta charset="UTF-8">
2847
+ ${cxt.config.options.headPlugins.map((x) => x(cxt)).filter((x) => x !== void 0).join("\n")}
2848
+ <title>${cxt.state.escape(cxt.state.title)}</title>
2849
+ <style>${styles}</style>
2850
+ </head>
2851
+ <body>
2852
+ <section class="article-container">
2853
+ <section class="article-body">
2854
+ ${cxt.config.options.headerPlugins.map((x) => x(cxt)).filter((x) => x !== void 0).join("\n")}
2855
+ ${results.join("\n")}
2856
+ ${cxt.config.options.footerPlugins.map((x) => x(cxt)).filter((x) => x !== void 0).join("\n")}
2857
+ </section>
2858
+ </section>
2859
+ </body>
2860
+ </html>`;
2861
+ }
2862
+ );
2863
+ htmlConfig.paragraphRenderer = (node, cxt) => `<p>${node.content.map((x) => cxt.renderEntity(x)).filter((x) => x !== void 0).join("")}</p>`;
2864
+ htmlConfig.textRenderer = (node, cxt) => {
2865
+ switch (node.type) {
2866
+ case 2 /* Preformatted */:
2867
+ return cxt.state.escape(node.content.text);
2868
+ case 3 /* Text */:
2869
+ case 4 /* Escaped */:
2870
+ return cxt.state.escape(node.content);
2871
+ default:
2872
+ return debug.never(node);
2873
+ }
2874
+ };
2875
+ htmlConfig.undefinedBlockRenderer = (node, cxt) => {
2876
+ return cxt.state.invalidBlock(node, `No renderer defined for ${node.mod.name}`);
2877
+ };
2878
+ htmlConfig.undefinedInlineRenderer = (node, cxt) => {
2879
+ return cxt.state.invalidInline(node, `No renderer defined for ${node.mod.name}`);
2880
+ };
2881
+ htmlConfig.addBlockRenderer(
2882
+ ...HeadingBlockRenderersHTML,
2883
+ ...BulletBlockRenderersHTML,
2884
+ CodeBlockRendererHTML,
2885
+ ...QuoteBlockRenderersHTML,
2886
+ ...MiscBlockRenderersHTML
2887
+ // TODO: notes
2888
+ );
2889
+ htmlConfig.addInlineRenderer(
2890
+ CodeInlineRendererHTML,
2891
+ ...InlineStyleRenderersHTML,
2892
+ ...MiscInlineRenderersHTML,
2893
+ ...NoteInlineRenderersHTML
2894
+ );
2895
+ var HTMLRenderConfiguration = htmlConfig;
1742
2896
 
1743
2897
  // src/index.ts
1744
2898
  function setDebugLevel(level) {
@@ -1750,14 +2904,20 @@ export {
1750
2904
  BuiltinConfiguration,
1751
2905
  Configuration,
1752
2906
  DebugLevel,
2907
+ DefaultConfiguration,
1753
2908
  Document,
2909
+ HTMLRenderConfiguration,
2910
+ HTMLRenderState,
1754
2911
  InlineModifierDefinition,
1755
2912
  MessageSeverity,
1756
- ModifierFlags,
2913
+ ModifierSlotType,
1757
2914
  NodeType,
1758
2915
  ParseContext,
2916
+ RenderConfiguration,
2917
+ RenderContext,
1759
2918
  SimpleScanner,
1760
2919
  SystemModifierDefinition,
2920
+ debugPrint,
1761
2921
  messages_exports as messages,
1762
2922
  parse,
1763
2923
  setDebugLevel