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