@the_dissidents/libemmm 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,158 +101,433 @@ 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);
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);
142
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,
151
- CannotPopNotationMessage: () => CannotPopNotationMessage,
457
+ CannotUseModuleInSelfMessage: () => CannotUseModuleInSelfMessage,
152
458
  ContentShouldBeOnNewlineMessage: () => ContentShouldBeOnNewlineMessage,
459
+ EitherNormalOrPreMessage: () => EitherNormalOrPreMessage,
460
+ EntityNotAllowedMessage: () => EntityNotAllowedMessage,
153
461
  ExpectedMessage: () => ExpectedMessage,
154
- InlineDefinitonInvalidEntityMessage: () => InlineDefinitonInvalidEntityMessage,
155
462
  InvalidArgumentMessage: () => InvalidArgumentMessage,
463
+ MultipleBlocksNotPermittedMessage: () => MultipleBlocksNotPermittedMessage,
156
464
  NameAlreadyDefinedMessage: () => NameAlreadyDefinedMessage,
157
465
  NewBlockShouldBeOnNewlineMessage: () => NewBlockShouldBeOnNewlineMessage,
466
+ NoNestedModuleMessage: () => NoNestedModuleMessage,
467
+ OnlySimpleParagraphsPermittedMessage: () => OnlySimpleParagraphsPermittedMessage,
468
+ OverwriteDefinitionsMessage: () => OverwriteDefinitionsMessage,
158
469
  ReachedRecursionLimitMessage: () => ReachedRecursionLimitMessage,
159
- ReferredMessage: () => ReferredMessage,
160
470
  SlotUsedOutsideDefinitionMessage: () => SlotUsedOutsideDefinitionMessage,
161
471
  UnclosedInlineModifierMessage: () => UnclosedInlineModifierMessage,
162
472
  UndefinedVariableMessage: () => UndefinedVariableMessage,
163
473
  UnknownModifierMessage: () => UnknownModifierMessage,
164
474
  UnnecessaryNewlineMessage: () => UnnecessaryNewlineMessage
165
475
  });
166
- var ReferredMessage = class {
167
- constructor(original, position, length) {
168
- this.original = original;
169
- this.position = position;
170
- this.length = length;
171
- }
172
- get severity() {
173
- return this.original.severity;
174
- }
175
- get info() {
176
- return this.original.info;
177
- }
178
- get code() {
179
- return this.original.code;
180
- }
181
- fixes = [];
182
- };
183
476
  var AddThingMessage = class {
184
- constructor(code, severity, position, length, info, fixstr, what) {
477
+ constructor(code, severity, location, info) {
185
478
  this.code = code;
186
479
  this.severity = severity;
187
- this.position = position;
188
- this.length = length;
480
+ this.location = location;
189
481
  this.info = info;
190
- this.fixstr = fixstr;
191
- this.what = what;
192
- }
193
- get fixes() {
194
- let [pos, what, fixstr] = [this.position, this.what, this.fixstr];
195
- return [{
196
- get info() {
197
- return fixstr;
198
- },
199
- apply(src, cursor) {
200
- let newCursor = cursor < pos ? cursor : cursor + what.length;
201
- return [src.substring(0, pos) + what + src.substring(pos), newCursor];
202
- }
203
- }];
204
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
+ // }
205
495
  };
206
496
  var RemoveThingMessage = class {
207
- constructor(code, severity, position, length, info, fixstr) {
497
+ constructor(code, severity, location, info) {
208
498
  this.code = code;
209
499
  this.severity = severity;
210
- this.position = position;
211
- this.length = length;
500
+ this.location = location;
212
501
  this.info = info;
213
- this.fixstr = fixstr;
214
- }
215
- get fixes() {
216
- let [pos, len, fixstr] = [this.position, this.length, this.fixstr];
217
- return [{
218
- get info() {
219
- return fixstr;
220
- },
221
- apply(src, cursor) {
222
- let newCursor = cursor < pos + len && cursor >= pos ? pos : cursor - len;
223
- return [src.substring(0, pos) + src.substring(pos + len), newCursor];
224
- }
225
- }];
226
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
+ // }
227
515
  };
228
516
  var ExpectedMessage = class {
229
- constructor(position, what) {
230
- this.position = position;
517
+ constructor(location, what) {
518
+ this.location = location;
231
519
  this.what = what;
520
+ assert(location.end == location.start);
232
521
  }
233
522
  code = 1;
234
523
  severity = 2 /* Error */;
235
- get length() {
236
- return 0;
237
- }
238
524
  get info() {
239
525
  return `expected '${this.what}'`;
240
526
  }
241
- get fixes() {
242
- return [];
243
- }
244
527
  };
245
528
  var UnknownModifierMessage = class {
246
- constructor(position, length, what) {
247
- this.position = position;
248
- this.length = length;
529
+ constructor(location, what) {
530
+ this.location = location;
249
531
  this.what = what;
250
532
  }
251
533
  code = 2;
@@ -253,36 +535,34 @@ var UnknownModifierMessage = class {
253
535
  get info() {
254
536
  return `unknown modifier '${this.what}'; did you forget to escape it?`;
255
537
  }
256
- get fixes() {
257
- let [pos, len] = [this.position, this.length];
258
- return [{
259
- get info() {
260
- return "this is not a modifier -- escape it";
261
- },
262
- apply(src, cursor) {
263
- let newCursor = cursor < pos ? cursor : cursor + 1;
264
- return [src.substring(0, pos) + "\\" + src.substring(pos), newCursor];
265
- }
266
- }];
267
- }
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
+ // }
268
550
  };
269
551
  var UnclosedInlineModifierMessage = class {
270
- constructor(position, what) {
271
- this.position = position;
552
+ constructor(location, what) {
553
+ this.location = location;
272
554
  this.what = what;
555
+ assert(location.end == location.start);
273
556
  }
274
557
  code = 3;
275
558
  severity = 2 /* Error */;
276
- length = 0;
277
- fixes = [];
278
559
  get info() {
279
560
  return `unclosed inline modifier ${this.what}'`;
280
561
  }
281
562
  };
282
563
  var ArgumentCountMismatchMessage = class {
283
- constructor(position, length, min, max) {
284
- this.position = position;
285
- this.length = length;
564
+ constructor(location, min, max) {
565
+ this.location = location;
286
566
  if (min !== void 0) {
287
567
  if (max == min) this.msg = `: ${min} expected`;
288
568
  else if (max !== void 0) this.msg = `: ${min} to ${max} expected`;
@@ -294,449 +574,235 @@ var ArgumentCountMismatchMessage = class {
294
574
  msg = "";
295
575
  code = 4;
296
576
  severity = 2 /* Error */;
297
- fixes = [];
298
577
  get info() {
299
578
  return `argument count mismatch` + this.msg;
300
579
  }
301
580
  };
302
581
  var CannotExpandArgumentMessage = class {
303
- constructor(position, length, what) {
304
- this.position = position;
305
- this.length = length;
582
+ constructor(location, what) {
583
+ this.location = location;
306
584
  this.what = what;
307
585
  }
308
586
  code = 5;
309
587
  severity = 2 /* Error */;
310
- fixes = [];
311
588
  get info() {
312
589
  return `failed to expand argument` + (this.what === void 0 ? "" : `: ${this.what}`);
313
590
  }
314
591
  };
315
592
  var InvalidArgumentMessage = class {
316
- constructor(position, length, what) {
317
- this.position = position;
318
- this.length = length;
593
+ constructor(location, what) {
594
+ this.location = location;
319
595
  this.what = what;
320
596
  }
321
597
  code = 6;
322
598
  severity = 2 /* Error */;
323
- fixes = [];
324
599
  get info() {
325
600
  return `invalid argument` + (this.what === void 0 ? "" : `: ${this.what}`);
326
601
  }
327
602
  };
328
- var InlineDefinitonInvalidEntityMessage = class {
329
- constructor(position, length) {
330
- this.position = position;
331
- this.length = length;
603
+ var EntityNotAllowedMessage = class {
604
+ constructor(location, what) {
605
+ this.location = location;
606
+ this.what = what;
332
607
  }
333
608
  code = 7;
334
609
  severity = 2 /* Error */;
335
- fixes = [];
336
610
  get info() {
337
- return `Invalid entity in inline modifier definition`;
611
+ return "This entity is not allowed here" + (this.what ? `: ${this.what}` : "");
338
612
  }
339
613
  };
340
614
  var ReachedRecursionLimitMessage = class {
341
- constructor(position, length, limit, what) {
342
- this.position = position;
343
- this.length = length;
615
+ constructor(location, limit, what) {
616
+ this.location = location;
344
617
  this.limit = limit;
345
618
  this.what = what;
346
619
  }
347
620
  code = 8;
348
621
  severity = 2 /* Error */;
349
- fixes = [];
350
622
  get info() {
351
623
  return `Reached recursion limit ${this.limit} when expanding ${this.what}`;
352
624
  }
353
625
  };
354
626
  var SlotUsedOutsideDefinitionMessage = class {
355
- constructor(position, length) {
356
- this.position = position;
357
- this.length = length;
627
+ constructor(location) {
628
+ this.location = location;
358
629
  }
359
630
  code = 9;
360
631
  severity = 2 /* Error */;
361
- fixes = [];
362
632
  get info() {
363
633
  return `slot used outside a definition`;
364
634
  }
365
635
  };
366
- var CannotPopNotationMessage = class {
367
- constructor(position, length) {
368
- this.position = position;
369
- this.length = length;
636
+ var NoNestedModuleMessage = class {
637
+ constructor(location) {
638
+ this.location = location;
370
639
  }
371
640
  code = 10;
372
641
  severity = 2 /* Error */;
373
- fixes = [];
374
642
  get info() {
375
- return `cannot pop notation`;
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`;
376
684
  }
377
685
  };
378
686
  var UnnecessaryNewlineMessage = class extends RemoveThingMessage {
379
- constructor(pos, len) {
687
+ constructor(location) {
380
688
  super(
381
689
  1,
382
690
  1 /* Warning */,
383
- pos,
384
- len,
385
- "more than one newlines have the same effect as one",
386
- "remove the redundant newlines"
691
+ location,
692
+ "more than one newlines have the same effect as one"
387
693
  );
388
694
  }
389
695
  };
390
696
  var NewBlockShouldBeOnNewlineMessage = class extends AddThingMessage {
391
- constructor(pos) {
697
+ constructor(location) {
392
698
  super(
393
699
  2,
394
700
  1 /* Warning */,
395
- pos,
396
- 0,
397
- "a new block should begin in a new line to avoid confusion",
398
- "add a line break",
399
- "\n"
701
+ location,
702
+ "a new block should begin in a new line to avoid confusion"
400
703
  );
401
704
  }
402
705
  };
403
706
  var ContentShouldBeOnNewlineMessage = class extends AddThingMessage {
404
- constructor(pos) {
707
+ constructor(location) {
405
708
  super(
406
709
  3,
407
710
  1 /* Warning */,
408
- pos,
409
- 0,
410
- "the content should begin in a new line to avoid confusion",
411
- "add a line break",
412
- "\n"
711
+ location,
712
+ "the content should begin in a new line to avoid confusion"
413
713
  );
414
714
  }
415
715
  };
416
716
  var NameAlreadyDefinedMessage = class {
417
- constructor(position, length, what) {
418
- this.position = position;
419
- this.length = length;
717
+ constructor(location, what) {
718
+ this.location = location;
420
719
  this.what = what;
421
720
  }
422
721
  code = 4;
423
722
  severity = 1 /* Warning */;
424
- fixes = [];
425
723
  get info() {
426
724
  return `name is already defined, will overwrite: ${this.what}`;
427
725
  }
428
726
  };
429
727
  var UndefinedVariableMessage = class {
430
- constructor(position, length, what) {
431
- this.position = position;
432
- this.length = length;
728
+ constructor(location, what) {
729
+ this.location = location;
433
730
  this.what = what;
434
731
  }
435
732
  code = 5;
436
733
  severity = 1 /* Warning */;
437
- fixes = [];
438
734
  get info() {
439
735
  return `variable is undefined, will expand to empty string: ${this.what}`;
440
736
  }
441
737
  };
442
-
443
- // src/util.ts
444
- var NameManager = class _NameManager {
445
- array = [];
446
- data = /* @__PURE__ */ new Map();
447
- constructor(from) {
448
- if (from === void 0) return;
449
- if (from instanceof _NameManager) {
450
- this.array = [...from.array];
451
- this.data = new Map(from.data);
452
- } else {
453
- assert(Array.isArray(from));
454
- this.array = from.map((x) => ({ k: x.name, v: x }));
455
- this.array.sort((a, b) => b.k.length - a.k.length);
456
- this.data = new Map(from.map((x) => [x.name, x]));
457
- }
458
- }
459
- toArray() {
460
- return this.array.map(({ v }) => v);
461
- }
462
- get(name) {
463
- return this.data.get(name);
464
- }
465
- has(name) {
466
- return this.data.has(name);
467
- }
468
- remove(name) {
469
- let i = this.data.get(name);
470
- assert(i !== void 0);
471
- this.data.delete(name);
472
- this.array.splice(this.array.findIndex((x) => x.k == name), 1);
473
- }
474
- add(...elems) {
475
- for (const elem of elems) {
476
- assert(!this.has(elem.name));
477
- this.data.set(elem.name, elem);
478
- const len = elem.name.length;
479
- let i = 0;
480
- while (i < this.array.length && this.array[i].k.length > len) i++;
481
- this.array.splice(i, 0, { k: elem.name, v: elem });
482
- }
483
- }
484
- find(predicate) {
485
- const result = this.array.find((x) => predicate(x.v));
486
- return result ? result.v : void 0;
487
- }
488
- };
489
- function assert(x) {
490
- if (!!!x) {
491
- let error = new Error("assertion failed");
492
- console.log(error.stack);
493
- throw error;
494
- }
495
- }
496
- function has(v, f) {
497
- return (v & f) === f;
498
- }
499
- function linePositions(src) {
500
- let result = [0];
501
- [...src].forEach((x, i) => {
502
- if (x == "\n") result.push(i + 1);
503
- });
504
- result.push(Infinity);
505
- return result;
506
- }
507
- var cloneArgument = (arg) => ({
508
- start: arg.start,
509
- end: arg.end,
510
- content: arg.content.map((ent) => {
511
- switch (ent.type) {
512
- case 3 /* Text */:
513
- case 4 /* Escaped */:
514
- return structuredClone(ent);
515
- case 8 /* Interpolation */:
516
- return {
517
- type: ent.type,
518
- start: ent.start,
519
- end: ent.end,
520
- definition: ent.definition,
521
- argument: cloneArgument(ent.argument),
522
- expansion: ent.expansion
523
- };
524
- default:
525
- return debug.never(ent);
526
- }
527
- })
528
- });
529
- function cloneNode(node, referring) {
530
- switch (node.type) {
531
- case 7 /* BlockModifier */:
532
- case 6 /* InlineModifier */:
533
- case 5 /* SystemModifier */:
534
- return {
535
- start: node.start,
536
- end: node.end,
537
- type: node.type,
538
- mod: node.mod,
539
- state: void 0,
540
- head: structuredClone(node.head),
541
- arguments: node.arguments.map(cloneArgument),
542
- content: node.content.map((x) => cloneNode(x, referring)),
543
- expansion: node.expansion ? cloneNodes(node.expansion) : void 0
544
- };
545
- case 0 /* Root */:
546
- case 1 /* Paragraph */:
547
- return {
548
- type: node.type,
549
- start: node.start,
550
- end: node.end,
551
- content: node.content.map((x) => cloneNode(x))
552
- };
553
- case 2 /* Preformatted */:
554
- case 3 /* Text */:
555
- case 4 /* Escaped */:
556
- return structuredClone(node);
557
- default:
558
- return debug.never(node);
559
- }
560
- }
561
- function cloneNodes(nodes) {
562
- return nodes.map((x) => cloneNode(x));
563
- }
564
- function debugPrintArgEntity(node) {
565
- switch (node.type) {
566
- case 3 /* Text */:
567
- return node.content;
568
- case 4 /* Escaped */:
569
- return `<Escaped:${node.content}>`;
570
- case 8 /* Interpolation */:
571
- return `<Interp:${node.definition.name}-${node.definition.postfix}:${debugPrintArgument(node.argument)}${node.expansion ? `=${node.expansion}` : ""}>`;
572
- default:
573
- return debug.never(node);
574
- }
575
- }
576
- function debugPrintArgument(arg) {
577
- return arg.content.map(debugPrintArgEntity).join("");
578
- }
579
- function debugPrintNode(node, prefix = "") {
580
- let result = `<${NodeType[node.type]}@${node.start}`;
581
- switch (node.type) {
582
- case 0 /* Root */:
583
- case 1 /* Paragraph */:
584
- const content = debugPrintNodes(node.content, prefix);
585
- if (content.length > 0)
586
- result += `>
587
- ${content}
588
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
589
- else result += `-${node.end} />`;
590
- break;
591
- case 4 /* Escaped */:
592
- case 2 /* Preformatted */:
593
- result += `>
594
- ${prefix} ${node.content}
595
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
596
- break;
597
- case 6 /* InlineModifier */:
598
- case 7 /* BlockModifier */:
599
- case 5 /* SystemModifier */:
600
- const args = node.arguments.map((x, i) => `
601
- ${prefix} (${i})@${x.start}-${x.end}=${debugPrintArgument(x)}`).join("");
602
- if (node.content.length > 0) {
603
- result += ` id=${node.mod.name}${args}>
604
- ` + debugPrintNodes(node.content, prefix) + `
605
- ${prefix}</${NodeType[node.type]}@${node.end}>`;
606
- } else result += `-${node.end} id=${node.mod.name}${args} />`;
607
- if (node.expansion) {
608
- const content2 = debugPrintNodes(node.expansion, prefix);
609
- if (content2.length > 0)
610
- result += `
611
- ${prefix}<expansion>
612
- ${content2}
613
- ${prefix}</expansion>`;
614
- else if (node.type != 5 /* SystemModifier */)
615
- result += `
616
- ${prefix}<expansion />`;
617
- }
618
- break;
619
- case 3 /* Text */:
620
- return node.content;
621
- default:
622
- return debug.never(node);
623
- }
624
- return result;
625
- }
626
- function debugPrintNodes(content, prefix = "") {
627
- let dumps = content.map((x) => debugPrintNode(x, prefix + " ")).filter((x) => x.length > 0);
628
- if (dumps.length == 0) return "";
629
- return dumps.map((x) => `${prefix} ${x}`).join("\n");
630
- }
631
- function debugDumpDocument(doc, source) {
632
- const lines = linePositions(source);
633
- function pos2lc(pos) {
634
- let line = -1, linepos = 0;
635
- for (let i = 1; i < lines.length; i++) {
636
- if (lines[i] > pos) {
637
- line = i;
638
- linepos = lines[i - 1];
639
- break;
640
- }
641
- }
642
- return `l${line}c${pos - linepos + 1}`;
643
- }
644
- function dumpMsg(m) {
645
- let result = `at ${pos2lc(m.position)}, len ${m.length}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
646
- while (m instanceof ReferredMessage) {
647
- m = m.original;
648
- result += `
649
- ---> original at: ${pos2lc(m.position)}, len ${m.length}`;
650
- }
651
- return result;
738
+ var OverwriteDefinitionsMessage = class {
739
+ constructor(location, what) {
740
+ this.location = location;
741
+ this.what = what;
652
742
  }
653
- let root = debugPrintNode(doc.root);
654
- let msgs = doc.messages.map(dumpMsg).join("\n");
655
- if (msgs.length > 0) msgs += "\n";
656
- return `${msgs}${root}`;
657
- }
658
-
659
- // src/debug.ts
660
- var DebugLevel = /* @__PURE__ */ ((DebugLevel3) => {
661
- DebugLevel3[DebugLevel3["Trace"] = 0] = "Trace";
662
- DebugLevel3[DebugLevel3["Info"] = 1] = "Info";
663
- DebugLevel3[DebugLevel3["Warning"] = 2] = "Warning";
664
- DebugLevel3[DebugLevel3["Error"] = 3] = "Error";
665
- DebugLevel3[DebugLevel3["None"] = 4] = "None";
666
- return DebugLevel3;
667
- })(DebugLevel || {});
668
- var debug = {
669
- level: 1 /* Info */,
670
- trace(arg0, ...args) {
671
- if (this.level > 0 /* Trace */) return;
672
- if (typeof arg0 == "function") arg0 = arg0();
673
- console.info("TRACE", arg0, ...args);
674
- },
675
- info(arg0, ...args) {
676
- if (this.level > 1 /* Info */) return;
677
- if (typeof arg0 == "function") arg0 = arg0();
678
- console.info(" INFO", arg0, ...args);
679
- },
680
- warning(arg0, ...args) {
681
- if (this.level > 2 /* Warning */) return;
682
- if (typeof arg0 == "function") arg0 = arg0();
683
- console.warn(" WARN", arg0, ...args);
684
- },
685
- error(arg0, ...args) {
686
- if (this.level > 3 /* Error */) return;
687
- if (typeof arg0 == "function") arg0 = arg0();
688
- console.error("ERROR", arg0, ...args);
689
- },
690
- never(_) {
691
- assert(false);
743
+ code = 6;
744
+ severity = 1 /* Warning */;
745
+ get info() {
746
+ return `using this module will overwrite: ${this.what}`;
692
747
  }
693
748
  };
694
749
 
695
- // src/front.ts
696
- var SimpleScanner = class {
697
- constructor(src) {
698
- this.src = src;
699
- }
700
- pos = 0;
701
- position() {
702
- return this.pos;
703
- }
704
- isEOF() {
705
- return this.pos >= this.src.length;
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));
706
756
  }
707
- peek(str) {
708
- let next = this.pos + str.length;
709
- if (next > this.src.length) return false;
710
- return this.src.slice(this.pos, this.pos + str.length) == str;
757
+ data = {};
758
+ init(key, obj) {
759
+ assert(!(key in this.data));
760
+ this.data[key] = obj;
711
761
  }
712
- acceptChar() {
713
- if (this.isEOF()) throw new RangeError("EOF");
714
- let char = this.src[this.pos];
715
- this.pos++;
716
- return char;
762
+ set(key, obj) {
763
+ assert(key in this.data);
764
+ this.data[key] = obj;
717
765
  }
718
- accept(str) {
719
- if (!this.peek(str)) return false;
720
- this.pos += str.length;
721
- return true;
766
+ get(key) {
767
+ assert(key in this.data);
768
+ return this.data[key];
722
769
  }
723
- acceptWhitespaceChar() {
724
- if (this.isEOF()) return null;
725
- let char = this.src[this.pos];
726
- if (!" ".includes(char)) return null;
727
- this.pos++;
728
- return char;
770
+ };
771
+ var Document = class _Document {
772
+ constructor(root, context, messages) {
773
+ this.root = root;
774
+ this.context = context;
775
+ this.messages = messages;
729
776
  }
730
- acceptUntil(str) {
731
- let start = this.pos;
732
- while (!this.isEOF()) {
733
- if (this.peek(str)) {
734
- let result = this.src.slice(start, this.pos);
735
- return result;
736
- }
737
- this.pos++;
738
- }
739
- return null;
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;
784
+ }
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;
740
806
  }
741
807
  };
742
808
 
@@ -757,31 +823,20 @@ var UnknownModifier = {
757
823
  var EmitEnvironment = class {
758
824
  constructor(scanner) {
759
825
  this.scanner = scanner;
826
+ this.root = { type: 0 /* Root */, source: scanner.source, content: [] };
760
827
  }
761
- root = { type: 0 /* Root */, start: 0, end: -1, content: [] };
828
+ root;
762
829
  messages = [];
763
- blockStack = [this.root];
830
+ blockStack = [];
764
831
  inlineStack = [];
765
- referringStack = [];
766
832
  message(...m) {
767
- const referringReverse = [...this.referringStack].reverse();
768
833
  for (let msg of m) {
769
- for (const range of referringReverse)
770
- msg = new ReferredMessage(msg, range.start, range.end - range.start);
771
834
  this.messages.push(msg);
772
835
  debug.trace("issued msg", msg.code, msg.info);
773
836
  }
774
837
  }
775
- pushReferring(start, end) {
776
- this.referringStack.push({ start, end });
777
- }
778
- popReferring() {
779
- assert(this.referringStack.length > 0);
780
- this.referringStack.pop();
781
- }
782
838
  addBlockNode(n) {
783
- assert(this.blockStack.length > 0);
784
- this.blockStack.at(-1).content.push(n);
839
+ (this.blockStack.at(-1) ?? this.root).content.push(n);
785
840
  return n;
786
841
  }
787
842
  addInlineNode(n) {
@@ -795,11 +850,14 @@ var EmitEnvironment = class {
795
850
  const last = content.at(-1);
796
851
  if (last?.type == 3 /* Text */) {
797
852
  last.content += str;
798
- last.end = this.scanner.position();
853
+ last.location.end = this.scanner.position();
799
854
  } else content.push({
800
855
  type: 3 /* Text */,
801
- start: this.scanner.position() - str.length,
802
- end: this.scanner.position(),
856
+ location: {
857
+ source: this.scanner.source,
858
+ start: this.scanner.position() - str.length,
859
+ end: this.scanner.position()
860
+ },
803
861
  content: str
804
862
  });
805
863
  }
@@ -808,9 +866,9 @@ var EmitEnvironment = class {
808
866
  this.blockStack.push(block);
809
867
  }
810
868
  endBlock() {
811
- assert(this.blockStack.length >= 2);
869
+ assert(this.blockStack.length > 0);
812
870
  const node = this.blockStack.pop();
813
- node.end = this.scanner.position();
871
+ node.location.end = this.scanner.position();
814
872
  }
815
873
  startInline(n) {
816
874
  if (n.type == 1 /* Paragraph */) this.addBlockNode(n);
@@ -820,19 +878,32 @@ var EmitEnvironment = class {
820
878
  endInline() {
821
879
  assert(this.inlineStack.length > 0);
822
880
  const node = this.inlineStack.pop();
823
- node.end = this.scanner.position();
881
+ node.location.end = this.scanner.position();
824
882
  }
825
883
  };
826
884
  var Parser = class {
827
- constructor(scanner, config) {
885
+ constructor(scanner, cxt) {
828
886
  this.scanner = scanner;
887
+ this.cxt = cxt;
829
888
  this.emit = new EmitEnvironment(scanner);
830
- this.cxt = new ParseContext(config);
831
889
  }
832
890
  emit;
833
- cxt;
834
891
  delayDepth = 0;
835
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
+ }
836
907
  #defs(type) {
837
908
  switch (type) {
838
909
  case 5 /* SystemModifier */:
@@ -932,30 +1003,23 @@ var Parser = class {
932
1003
  node.expansion = node.mod.expand(node, this.cxt, immediate);
933
1004
  if (!node.expansion) {
934
1005
  return true;
935
- } else if (node.expansion.length > 0) {
936
- debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
937
- debug.trace(() => "-->\n" + debugPrintNodes(node.expansion, " "));
938
- } else {
939
- debug.trace(`${this.delayDepth > 0 ? "early " : ""}expanding:`, node.mod.name);
940
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));
941
1010
  }
942
1011
  const expansion = node.expansion ?? node.content;
943
1012
  if (expansion.length == 0) return true;
944
1013
  if (node.mod.beforeProcessExpansion)
945
1014
  this.emit.message(...node.mod.beforeProcessExpansion(node, this.cxt, immediate));
946
- this.emit.pushReferring(node.start, node.end);
947
1015
  let ok = this.#reparse(expansion, depth);
948
- this.emit.popReferring();
949
1016
  if (node.mod.afterProcessExpansion)
950
1017
  this.emit.message(...node.mod.afterProcessExpansion(node, this.cxt, immediate));
951
1018
  if (!ok && depth == 0) {
952
1019
  const limit = this.cxt.config.reparseDepthLimit;
953
- this.emit.message(new ReachedRecursionLimitMessage(
954
- node.start,
955
- node.end - node.start,
956
- limit,
957
- node.mod.name
958
- ));
1020
+ this.emit.message(
1021
+ new ReachedRecursionLimitMessage(node.location, limit, node.mod.name)
1022
+ );
959
1023
  }
960
1024
  return ok;
961
1025
  }
@@ -963,15 +1027,18 @@ var Parser = class {
963
1027
  this.DOCUMENT();
964
1028
  return new Document(this.emit.root, this.cxt, this.emit.messages);
965
1029
  }
1030
+ WHITESPACES() {
1031
+ while (this.scanner.acceptWhitespaceChar() !== null) {
1032
+ }
1033
+ }
966
1034
  WHITESPACES_OR_NEWLINES() {
967
1035
  while (this.scanner.acceptWhitespaceChar() !== null || this.scanner.accept("\n")) {
968
1036
  }
969
1037
  }
970
1038
  SHOULD_BE_A_NEWLINE() {
971
- while (this.scanner.acceptWhitespaceChar() !== null) {
972
- }
1039
+ this.WHITESPACES();
973
1040
  if (!this.scanner.accept("\n")) this.emit.message(
974
- new ContentShouldBeOnNewlineMessage(this.scanner.position())
1041
+ new ContentShouldBeOnNewlineMessage(this.#loc())
975
1042
  );
976
1043
  }
977
1044
  // TODO: this is awkward and doesn't emit messages in the most appropriate way
@@ -987,7 +1054,7 @@ var Parser = class {
987
1054
  }
988
1055
  const end = this.scanner.position();
989
1056
  if (nlines > n) this.emit.message(
990
- new UnnecessaryNewlineMessage(start, end - start)
1057
+ new UnnecessaryNewlineMessage(this.#locFrom(start, end))
991
1058
  );
992
1059
  }
993
1060
  DOCUMENT() {
@@ -1007,6 +1074,8 @@ var Parser = class {
1007
1074
  this.MODIFIER(5 /* SystemModifier */);
1008
1075
  return;
1009
1076
  }
1077
+ const short = this.cxt.config.blockShorthands.find((x) => this.scanner.accept(x.name));
1078
+ if (short) return this.SHORTHAND(7 /* BlockModifier */, short);
1010
1079
  this.MAYBE_GROUPED_PARAGRAPH();
1011
1080
  }
1012
1081
  MODIFIER(type) {
@@ -1027,71 +1096,29 @@ var Parser = class {
1027
1096
  name += this.scanner.acceptChar();
1028
1097
  }
1029
1098
  this.emit.message(
1030
- new UnknownModifierMessage(posStart, this.scanner.position() - posStart, name)
1099
+ new UnknownModifierMessage(this.#locFrom(posStart), name)
1031
1100
  );
1032
1101
  }
1033
1102
  const args = this.ARGUMENTS();
1034
1103
  debug.trace(`PARSE ${NodeType[type]}:`, mod.name);
1035
1104
  const endsign = this.scanner.accept(MODIFIER_END_SIGN);
1036
- const flagMarker = has(mod.flags, 2 /* Marker */);
1037
- const isMarker = flagMarker || endsign;
1105
+ const flagMarker = mod.slotType == 2 /* None */;
1038
1106
  if (!this.scanner.accept(MODIFIER_CLOSE_SIGN))
1039
- this.emit.message(new ExpectedMessage(
1040
- this.scanner.position(),
1041
- MODIFIER_CLOSE_SIGN
1042
- ));
1107
+ this.emit.message(
1108
+ new ExpectedMessage(this.#loc(), MODIFIER_CLOSE_SIGN)
1109
+ );
1043
1110
  const headEnd = this.scanner.position();
1044
1111
  const node = {
1045
1112
  type,
1046
1113
  mod,
1047
- head: { start: posStart, end: headEnd },
1114
+ head: this.#locFrom(posStart, headEnd),
1115
+ location: this.#locFrom(posStart, headEnd),
1048
1116
  arguments: args,
1049
- start: posStart,
1050
- end: headEnd,
1051
1117
  content: [],
1052
1118
  expansion: void 0
1053
1119
  };
1054
- this.#expandArguments(node);
1055
- const immediate = this.delayDepth == 0;
1056
- if (node.mod.beforeParseContent)
1057
- this.emit.message(...node.mod.beforeParseContent(node, this.cxt, immediate));
1058
- if (node.mod.delayContentExpansion) this.delayDepth++;
1059
- let ok = true;
1060
- if (isMarker) {
1061
- if (type === 6 /* InlineModifier */) this.emit.addInlineNode(node);
1062
- else this.emit.addBlockNode(node);
1063
- } else if (type == 6 /* InlineModifier */) {
1064
- this.emit.startInline(node);
1065
- const entity = has(mod.flags, 1 /* Preformatted */) ? this.PREFORMATTED_INLINE_ENTITY.bind(this) : this.INLINE_ENTITY.bind(this);
1066
- while (true) {
1067
- if (this.scanner.accept(MODIFIER_INLINE_END_TAG)) break;
1068
- if (this.scanner.isEOF() || !(ok = entity())) {
1069
- this.emit.message(new UnclosedInlineModifierMessage(
1070
- this.scanner.position(),
1071
- mod.name
1072
- ));
1073
- break;
1074
- }
1075
- }
1076
- this.emit.endInline();
1077
- } else {
1078
- this.emit.startBlock(node);
1079
- this.WARN_IF_MORE_NEWLINES_THAN(1);
1080
- if (!this.scanner.isEOF()) {
1081
- if (has(mod.flags, 1 /* Preformatted */))
1082
- this.PRE_PARAGRAPH();
1083
- else
1084
- this.BLOCK_ENTITY();
1085
- }
1086
- this.emit.endBlock();
1087
- }
1088
- const last = node.content.at(-1);
1089
- node.actualEnd = last?.actualEnd ?? last?.end;
1090
- if (node.mod.delayContentExpansion) this.delayDepth--;
1091
- if (node.mod.afterParseContent)
1092
- this.emit.message(...node.mod.afterParseContent(node, this.cxt, immediate));
1093
- this.#expand(node);
1094
- return ok;
1120
+ const isMarker = flagMarker || endsign;
1121
+ return this.MODIFIER_BODY(type, node, MODIFIER_INLINE_END_TAG, isMarker);
1095
1122
  }
1096
1123
  // also handles "grouped" (delimited) pre-paragraphs
1097
1124
  PRE_PARAGRAPH() {
@@ -1110,10 +1137,9 @@ var Parser = class {
1110
1137
  white += char;
1111
1138
  if (grouped && this.scanner.accept(GROUP_END) || !grouped && this.scanner.accept("\n")) break;
1112
1139
  if (this.scanner.isEOF()) {
1113
- if (grouped) this.emit.message(new ExpectedMessage(
1114
- this.scanner.position(),
1115
- GROUP_END
1116
- ));
1140
+ if (grouped) this.emit.message(
1141
+ new ExpectedMessage(this.#loc(), GROUP_END)
1142
+ );
1117
1143
  break;
1118
1144
  }
1119
1145
  string += white;
@@ -1124,8 +1150,7 @@ var Parser = class {
1124
1150
  }
1125
1151
  const node = {
1126
1152
  type: 2 /* Preformatted */,
1127
- start: posStart,
1128
- end: this.scanner.position(),
1153
+ location: this.#locFrom(posStart),
1129
1154
  content: {
1130
1155
  start: posContentStart,
1131
1156
  end: posContentEnd,
@@ -1148,54 +1173,128 @@ var Parser = class {
1148
1173
  this.BLOCK_ENTITY();
1149
1174
  this.WARN_IF_MORE_NEWLINES_THAN(1);
1150
1175
  }
1151
- this.emit.message(new ExpectedMessage(
1152
- this.scanner.position(),
1153
- GROUP_END
1154
- ));
1176
+ this.emit.message(
1177
+ new ExpectedMessage(this.#loc(), GROUP_END)
1178
+ );
1155
1179
  } else {
1156
1180
  this.PARAGRAPH();
1157
1181
  }
1158
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
+ }
1159
1192
  PARAGRAPH() {
1160
1193
  assert(!this.scanner.isEOF());
1161
1194
  const node = {
1162
1195
  type: 1 /* Paragraph */,
1163
- start: this.scanner.position(),
1164
- end: -1,
1196
+ location: this.#loc(),
1165
1197
  content: []
1166
1198
  };
1167
- debug.trace("PARSE para");
1168
1199
  this.emit.startInline(node);
1169
1200
  while (!this.scanner.isEOF() && this.INLINE_ENTITY()) {
1170
1201
  }
1171
1202
  this.emit.endInline();
1172
1203
  const last = node.content.at(-1);
1173
- node.actualEnd = last?.actualEnd ?? last?.end;
1174
- debug.trace("PARSE para end");
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;
1175
1278
  }
1176
1279
  // returns false if breaking out of paragraph
1177
1280
  INLINE_ENTITY() {
1178
1281
  assert(!this.scanner.isEOF());
1179
- if (this.scanner.peek(MODIFIER_BLOCK_OPEN)) {
1180
- this.emit.message(new NewBlockShouldBeOnNewlineMessage(this.scanner.position()));
1181
- return false;
1182
- }
1183
- if (this.scanner.peek(MODIFIER_INLINE_OPEN)) {
1282
+ if (this.scanner.peek(MODIFIER_INLINE_OPEN))
1184
1283
  return this.MODIFIER(6 /* InlineModifier */);
1185
- }
1186
- if (this.scanner.peek(MODIFIER_SYSTEM_OPEN)) {
1284
+ if (this.scanner.peek(MODIFIER_SYSTEM_OPEN))
1187
1285
  return false;
1188
- }
1286
+ const short = this.cxt.config.inlineShorthands.find((x) => this.scanner.accept(x.name));
1287
+ if (short) return this.SHORTHAND(6 /* InlineModifier */, short);
1189
1288
  if (this.scanner.accept("\\")) {
1190
1289
  if (this.scanner.isEOF()) {
1191
1290
  this.emit.addString("\\");
1192
1291
  return true;
1193
1292
  }
1293
+ const start = this.scanner.position();
1194
1294
  const node = {
1195
1295
  type: 4 /* Escaped */,
1196
- start: this.scanner.position() - 1,
1197
1296
  content: this.scanner.acceptChar(),
1198
- end: this.scanner.position()
1297
+ location: this.#locFrom(start - 1)
1199
1298
  };
1200
1299
  this.emit.addInlineNode(node);
1201
1300
  return true;
@@ -1206,9 +1305,8 @@ var Parser = class {
1206
1305
  PREFORMATTED_INLINE_ENTITY() {
1207
1306
  assert(!this.scanner.isEOF());
1208
1307
  if (this.scanner.accept("\n")) {
1209
- while (this.scanner.acceptWhitespaceChar() !== null) {
1210
- }
1211
- 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;
1212
1310
  if (this.scanner.accept("\n")) {
1213
1311
  this.WARN_IF_MORE_NEWLINES_THAN(0);
1214
1312
  return false;
@@ -1219,7 +1317,8 @@ var Parser = class {
1219
1317
  this.emit.addString(this.scanner.acceptChar());
1220
1318
  return true;
1221
1319
  }
1222
- ARGUMENT_CONTENT(end) {
1320
+ // returns argument and isOk
1321
+ ARGUMENT_CONTENT(end = void 0, close = [MODIFIER_END_SIGN, MODIFIER_CLOSE_SIGN]) {
1223
1322
  let ok = true;
1224
1323
  const content = [];
1225
1324
  const posStart = this.scanner.position();
@@ -1228,25 +1327,22 @@ var Parser = class {
1228
1327
  const last = content.at(-1);
1229
1328
  if (last?.type == 3 /* Text */) {
1230
1329
  last.content += s;
1231
- last.end += s.length;
1330
+ last.location.end += s.length;
1232
1331
  } else {
1233
1332
  const end2 = this.scanner.position();
1234
1333
  content.push({
1235
1334
  type: 3 /* Text */,
1236
- end: end2,
1237
- start: end2 - s.length,
1335
+ location: this.#locFrom(end2 - s.length),
1238
1336
  content: s
1239
1337
  });
1240
1338
  }
1241
1339
  };
1242
1340
  while (true) {
1243
- if (end !== void 0 && this.scanner.accept(end))
1341
+ if (end && this.scanner.accept(end))
1244
1342
  break;
1245
- if (this.scanner.accept(":")) {
1246
- ok = end === void 0;
1343
+ if (end === void 0 && this.scanner.accept(":"))
1247
1344
  break;
1248
- }
1249
- 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()) {
1250
1346
  ok = false;
1251
1347
  break;
1252
1348
  }
@@ -1260,8 +1356,7 @@ var Parser = class {
1260
1356
  content.push({
1261
1357
  type: 4 /* Escaped */,
1262
1358
  content: this.scanner.acceptChar(),
1263
- start: posEnd - 1,
1264
- end: posEnd + 1
1359
+ location: this.#locFrom(posEnd - 1)
1265
1360
  });
1266
1361
  continue;
1267
1362
  }
@@ -1276,11 +1371,10 @@ var Parser = class {
1276
1371
  type: 8 /* Interpolation */,
1277
1372
  definition: result,
1278
1373
  argument: inner,
1279
- start: beforeInterp,
1280
- end: posEnd
1374
+ location: this.#locFrom(beforeInterp)
1281
1375
  });
1282
1376
  if (!ok2) {
1283
- this.emit.message(new ExpectedMessage(posEnd, result.postfix));
1377
+ this.emit.message(new ExpectedMessage(this.#loc(), result.postfix));
1284
1378
  ok = false;
1285
1379
  break;
1286
1380
  }
@@ -1290,8 +1384,7 @@ var Parser = class {
1290
1384
  }
1291
1385
  }
1292
1386
  return [{
1293
- start: posStart,
1294
- end: posEnd,
1387
+ location: this.#locFrom(posStart, posEnd),
1295
1388
  content
1296
1389
  }, ok];
1297
1390
  }
@@ -1312,24 +1405,171 @@ var Parser = class {
1312
1405
  return list;
1313
1406
  }
1314
1407
  };
1315
- function parse(scanner, config) {
1316
- return new Parser(scanner, config).parse();
1408
+ function parse(scanner, cxt) {
1409
+ return new Parser(scanner, cxt).parse();
1317
1410
  }
1318
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
+
1319
1476
  // src/modifier-helper.ts
1320
1477
  function checkArgumentLength(node, min, max = min) {
1321
1478
  if (min !== void 0 && node.arguments.length < min || max !== void 0 && node.arguments.length > max) {
1322
- 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)];
1323
1484
  }
1324
1485
  return null;
1325
1486
  }
1326
1487
  function checkArguments(node, min, max = min) {
1327
1488
  const arg = node.arguments.find((x) => x.expansion === void 0);
1328
1489
  if (arg !== void 0) {
1329
- return [new CannotExpandArgumentMessage(arg.start, arg.end - arg.start)];
1490
+ return [new CannotExpandArgumentMessage(arg.location)];
1330
1491
  }
1331
1492
  return checkArgumentLength(node, min, max);
1332
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
+ }
1333
1573
 
1334
1574
  // src/builtin/internal.ts
1335
1575
  var builtins = Symbol();
@@ -1337,358 +1577,706 @@ function initParseContext(cxt) {
1337
1577
  cxt.init(builtins, {
1338
1578
  blockSlotDelayedStack: [],
1339
1579
  inlineSlotDelayedStack: [],
1340
- blockSlotData: [],
1341
- inlineSlotData: [],
1342
- notationStack: []
1580
+ blockInstantiationData: [],
1581
+ inlineInstantiationData: [],
1582
+ modules: /* @__PURE__ */ new Map(),
1583
+ usedModules: /* @__PURE__ */ new Set(),
1584
+ insideModule: void 0
1343
1585
  });
1344
1586
  }
1345
- function customModifier(type, name, argNames, slotName, content) {
1346
- debug.info(`registered custom ${type} modifier:`, name);
1347
- debug.info("args:", argNames, `with ${slotName == "" ? "no slot name" : "slot name: " + slotName}`);
1348
- debug.trace(() => "content is\n" + debugPrintNodes(content));
1349
- 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);
1350
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;
1351
1596
  mod.delayContentExpansion = true;
1352
1597
  mod.prepareExpand = (node, cxt) => {
1353
- let check = checkArguments(node, argNames.length);
1598
+ let check = checkArguments(node, signature.args.length);
1354
1599
  if (check) return check;
1355
1600
  node.state = {
1356
1601
  ok: true,
1357
- 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]))
1358
1603
  };
1359
1604
  return [];
1360
1605
  };
1361
- mod.expand = (node, cxt) => {
1606
+ mod.expand = (node) => {
1362
1607
  if (!node.state?.ok) return [];
1363
- const contentClone = cloneNodes(content);
1608
+ const contentClone = cloneNodes(content, { newLocation: node.location });
1364
1609
  return contentClone;
1365
1610
  };
1366
1611
  mod.beforeProcessExpansion = (node, cxt) => {
1367
1612
  if (!node.state?.ok) return [];
1368
1613
  const store = cxt.get(builtins);
1369
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1370
- data.push([slotName, {
1614
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1615
+ data.push({
1616
+ slotName: signature.slotName,
1371
1617
  mod,
1372
1618
  args: node.state.args,
1373
1619
  slotContent: node.content
1374
- }]);
1620
+ });
1375
1621
  debug.trace(
1376
- `pushed ${type} slot data for`,
1622
+ `pushed ${NodeType[type]} slot data for`,
1377
1623
  name,
1378
- slotName == "" ? "(unnamed)" : `= ${slotName}`
1624
+ signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1379
1625
  );
1380
1626
  return [];
1381
1627
  };
1382
1628
  mod.afterProcessExpansion = (node, cxt) => {
1383
- if (!node.state?.ok) return [];
1629
+ if (!node.state?.ok || signature.slotName === void 0) return [];
1384
1630
  const store = cxt.get(builtins);
1385
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1631
+ const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1386
1632
  const pop = data.pop();
1387
- assert(pop !== void 0 && pop[0] == slotName);
1633
+ assert(pop !== void 0);
1388
1634
  debug.trace(
1389
- `popped ${type} slot data for`,
1635
+ `popped ${NodeType[type]} slot data for`,
1390
1636
  name,
1391
- slotName == "" ? "(unnamed)" : `= ${slotName}`
1637
+ signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1392
1638
  );
1393
1639
  return [];
1394
1640
  };
1395
1641
  return mod;
1396
1642
  }
1397
-
1398
- // src/builtin/define-block.ts
1399
- var DefineBlockMod = new SystemModifierDefinition("define-block", 0 /* Normal */, {
1400
- // .define-block:name:args...[:(slot-id)]
1401
- delayContentExpansion: true,
1402
- alwaysTryExpand: true,
1403
- beforeParseContent(node, cxt) {
1404
- const check = checkArgumentLength(node, 1, Infinity);
1405
- if (check) return check;
1406
- const msgs = [];
1407
- const name = node.arguments[0];
1408
- const nameValue = name.expansion;
1409
- let slotName = "";
1410
- if (node.arguments.length > 1) {
1411
- const last = node.arguments.at(-1);
1412
- if (last.expansion)
1413
- slotName = /^\(.+\)$/.test(last.expansion) ? last.expansion.substring(1, last.expansion.length - 1) : "";
1414
- else msgs.push(
1415
- new InvalidArgumentMessage(last.start, last.end - last.start)
1416
- );
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);
1417
1664
  }
1418
- const args = node.arguments.slice(1, slotName !== "" ? node.arguments.length - 1 : void 0).map((x) => {
1419
- if (!x.expansion) msgs.push(
1420
- new InvalidArgumentMessage(x.start, x.end - x.start)
1421
- );
1422
- return x.expansion ?? "";
1423
- });
1424
- node.state = { name: nameValue, slotName, args, msgs };
1425
- const store = cxt.get(builtins);
1426
- store.blockSlotDelayedStack.push(node.state.slotName);
1427
- debug.trace("entering block definition:", node.state.name);
1428
- return [];
1429
- },
1430
- afterParseContent(node, cxt) {
1431
- if (!node.state) return [];
1432
- const store = cxt.get(builtins);
1433
- assert(store.blockSlotDelayedStack.pop() == node.state.slotName);
1434
- debug.trace("leaving block definition", node.state.name);
1435
- return [];
1436
- },
1437
- prepareExpand(node, cxt, immediate) {
1438
- if (!immediate || !node.state) return [];
1439
- const arg = node.arguments[0];
1440
- if (!node.state.name)
1441
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1442
- if (cxt.config.blockModifiers.has(node.state.name))
1443
- return [new NameAlreadyDefinedMessage(
1444
- arg.start,
1445
- arg.end - arg.start,
1446
- node.state.name
1447
- )];
1448
- return [];
1449
- },
1450
- expand(node, cxt, immediate) {
1451
- if (!immediate) return void 0;
1452
- if (node.state?.name) {
1453
- if (cxt.config.blockModifiers.has(node.state.name))
1454
- cxt.config.blockModifiers.remove(node.state.name);
1455
- cxt.config.blockModifiers.add(
1456
- customModifier(
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(
1457
1738
  7 /* BlockModifier */,
1458
1739
  node.state.name,
1459
- node.state.args,
1460
- node.state.slotName,
1740
+ node.state.signature,
1461
1741
  node.content
1462
- )
1463
- );
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 [];
1464
1796
  }
1465
- return [];
1466
1797
  }
1467
- });
1798
+ );
1468
1799
 
1469
- // src/builtin/define-inline.ts
1470
- var DefineInlineMod = new SystemModifierDefinition("define-inline", 0 /* Normal */, {
1471
- // .define-inline name:args...[:(slot-id)]
1472
- delayContentExpansion: true,
1473
- alwaysTryExpand: true,
1474
- beforeParseContent(node, cxt) {
1475
- const check = checkArgumentLength(node, 1, Infinity);
1476
- if (check) return check;
1477
- const msgs = [];
1478
- const name = node.arguments[0];
1479
- const nameValue = name.expansion;
1480
- if (nameValue && cxt.config.inlineModifiers.has(nameValue))
1481
- msgs.push(new NameAlreadyDefinedMessage(
1482
- node.start,
1483
- name.end - name.start,
1484
- nameValue
1485
- ));
1486
- let slotName = "";
1487
- if (node.arguments.length > 1) {
1488
- const last = node.arguments.at(-1);
1489
- if (last.expansion)
1490
- slotName = /^\(.+\)$/.test(last.expansion) ? last.expansion.substring(1, last.expansion.length - 1) : "";
1491
- else msgs.push(
1492
- new InvalidArgumentMessage(last.start, last.end - last.start)
1493
- );
1494
- }
1495
- const args = node.arguments.slice(1, slotName !== "" ? node.arguments.length - 1 : void 0).map((x) => {
1496
- if (!x.expansion) msgs.push(
1497
- new InvalidArgumentMessage(x.start, x.end - x.start)
1498
- );
1499
- return x.expansion ?? "";
1500
- });
1501
- node.state = { name: nameValue, slotName, args, msgs };
1502
- const store = cxt.get(builtins);
1503
- store.inlineSlotDelayedStack.push(node.state.slotName);
1504
- debug.trace("entering inline definition:", node.state.name);
1505
- return [];
1506
- },
1507
- afterParseContent(node, cxt) {
1508
- if (!node.state) return [];
1509
- const store = cxt.get(builtins);
1510
- assert(store.inlineSlotDelayedStack.pop() == node.state.slotName);
1511
- debug.trace("leaving inline definition", node.state.name);
1512
- return [];
1513
- },
1514
- prepareExpand(node, cxt, immediate) {
1515
- if (!immediate || !node.state) return [];
1516
- const arg = node.arguments[0];
1517
- if (!node.state.name)
1518
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1519
- const msgs = [];
1520
- if (cxt.config.inlineModifiers.has(node.state.name))
1521
- msgs.push(new NameAlreadyDefinedMessage(
1522
- arg.start,
1523
- arg.end - arg.start,
1524
- node.state.name
1525
- ));
1526
- let lastIsParagraph = false;
1527
- let concat = [];
1528
- for (const n of node.content) {
1529
- switch (n.type) {
1530
- case 1 /* Paragraph */:
1531
- if (!lastIsParagraph) {
1532
- lastIsParagraph = true;
1533
- concat.push(...n.content);
1534
- continue;
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++;
1535
1830
  }
1536
- case 2 /* Preformatted */:
1537
- case 7 /* BlockModifier */:
1538
- msgs.push(new InlineDefinitonInvalidEntityMessage(n.start, n.end - n.start));
1539
- break;
1540
- case 5 /* SystemModifier */:
1541
- lastIsParagraph = false;
1542
- concat.push(n);
1543
- break;
1544
- default:
1545
- debug.never(n);
1831
+ } else msgs.push(
1832
+ new ArgumentCountMismatchMessage(node.location)
1833
+ );
1546
1834
  }
1835
+ break;
1547
1836
  }
1548
- node.state.definition = concat;
1549
- return msgs;
1550
- },
1551
- expand(node, cxt, immediate) {
1552
- if (!immediate) return void 0;
1553
- if (node.state?.name) {
1554
- if (cxt.config.inlineModifiers.has(node.state.name))
1555
- cxt.config.inlineModifiers.remove(node.state.name);
1556
- cxt.config.inlineModifiers.add(
1557
- customModifier(
1558
- 6 /* InlineModifier */,
1559
- node.state.name,
1560
- node.state.args,
1561
- node.state.slotName,
1562
- node.state.definition
1563
- )
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)")
1861
+ );
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 [];
1868
+ }
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
1564
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 [];
1565
1926
  }
1566
- return [];
1567
1927
  }
1568
- });
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
1942
+ );
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
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 [];
1987
+ }
1988
+ }
1989
+ );
1569
1990
 
1570
- // src/builtin/pushpop.ts
1571
- var PushNotationMod = new SystemModifierDefinition(
1572
- "push-notation",
1573
- 2 /* Marker */,
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 */,
1574
2050
  {
1575
- expand(_, cxt) {
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 [];
1576
2080
  const data = cxt.get(builtins);
1577
- data.notationStack.push({
1578
- blocks: cxt.config.blockModifiers.toArray(),
1579
- inlines: cxt.config.inlineModifiers.toArray()
1580
- });
2081
+ data.insideModule = void 0;
2082
+ data.modules.set(
2083
+ node.state.name,
2084
+ diffDef(getDefs(cxt), node.state.defs)
2085
+ );
2086
+ applyDefs(cxt, node.state.defs);
2087
+ debug.trace("exiting defs for module", node.state.name);
1581
2088
  return [];
1582
2089
  }
1583
2090
  }
1584
2091
  );
1585
- var PopNotationMod = new SystemModifierDefinition(
1586
- "pop-notation",
1587
- 2 /* Marker */,
2092
+ var UseSystemMod = new SystemModifierDefinition(
2093
+ "use",
2094
+ 2 /* None */,
1588
2095
  {
1589
2096
  prepareExpand(node, cxt) {
2097
+ const check = checkArguments(node, 1);
2098
+ if (check) return check;
1590
2099
  const data = cxt.get(builtins);
1591
- const result = data.notationStack.pop();
1592
- if (!result) return [
1593
- new CannotPopNotationMessage(node.start, node.end - node.start)
1594
- ];
1595
- cxt.config.blockModifiers = new NameManager(result.blocks);
1596
- cxt.config.inlineModifiers = new NameManager(result.inlines);
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)];
1597
2109
  return [];
1598
2110
  },
1599
- expand() {
2111
+ expand(node, cxt) {
2112
+ if (node.state)
2113
+ applyDefs(cxt, node.state);
1600
2114
  return [];
1601
2115
  }
1602
2116
  }
1603
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;
2146
+ }
2147
+ }
2148
+ );
1604
2149
 
1605
2150
  // src/builtin/slot.ts
1606
- function slotModifier(type) {
1607
- 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 */);
1608
2153
  const isInline = type == 6 /* InlineModifier */;
1609
2154
  mod.alwaysTryExpand = true;
1610
2155
  mod.prepareExpand = (node, cxt, immediate) => {
1611
2156
  if (node.state) return [];
1612
- const check = checkArgumentLength(node, 0, 1);
1613
- 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) {
1614
2168
  node.state = { ok: false };
1615
2169
  return check;
1616
2170
  }
1617
- const store = cxt.get(builtins);
1618
- const data = isInline ? store.inlineSlotData : store.blockSlotData;
1619
- let id = "";
1620
- if (node.arguments.length == 1) {
1621
- const arg = node.arguments[0];
1622
- 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) {
1623
2176
  node.state = { ok: false };
1624
- 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;
1625
2191
  }
1626
- id = arg.expansion;
1627
- }
1628
- if (data.length == 0) {
1629
2192
  if (immediate) {
1630
2193
  node.state = { ok: false };
1631
- return [new SlotUsedOutsideDefinitionMessage(node.start, node.head.end - node.start)];
2194
+ const arg = node.arguments[0];
2195
+ return [new InvalidArgumentMessage(arg.location, id)];
1632
2196
  }
1633
- return [];
1634
- }
1635
- const stack = isInline ? store.inlineSlotDelayedStack : store.blockSlotDelayedStack;
1636
- if (stack.includes(id)) {
1637
- debug.trace("delaying", id == "" ? "unnamed slot" : "slot: " + id);
1638
- return [];
1639
- }
1640
- if (node.arguments.length == 0) {
1641
- node.state = { ok: true, data: data.at(-1), index: data.length - 1 };
1642
- return [];
1643
- }
1644
- for (let i = data.length - 1; i >= 0; i--) if (data[i][0] == id) {
1645
- node.state = { ok: true, data: data[i], index: i };
1646
- return [];
1647
- }
1648
- if (immediate) {
1649
- node.state = { ok: false };
1650
- const arg = node.arguments[0];
1651
- 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;
1652
2208
  }
2209
+ if (msgs) return msgs;
1653
2210
  return [];
1654
2211
  };
1655
2212
  mod.expand = (node, cxt) => {
1656
2213
  if (!node.state) return void 0;
1657
2214
  if (!node.state.ok) return [];
1658
- 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;
1659
2229
  };
1660
2230
  mod.beforeProcessExpansion = (node, cxt) => {
1661
2231
  if (!node.state?.ok) return [];
1662
2232
  const store = cxt.get(builtins);
1663
- debug.trace("temporarily removed slot data for", node.state.data[1].mod.name);
1664
- 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;
1665
2235
  data.splice(node.state.index, 1);
1666
2236
  return [];
1667
2237
  };
1668
2238
  mod.afterProcessExpansion = (node, cxt) => {
1669
2239
  if (!node.state?.ok) return [];
1670
2240
  const store = cxt.get(builtins);
1671
- debug.trace("reinstated slot data for", node.state.data[1].mod.name);
1672
- 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;
1673
2243
  data.splice(node.state.index, 0, node.state.data);
1674
2244
  return [];
1675
2245
  };
1676
2246
  return mod;
1677
2247
  }
1678
- var SlotBlockMod = slotModifier(7 /* BlockModifier */);
1679
- 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
+ );
1680
2264
 
1681
2265
  // src/builtin/var.ts
1682
2266
  function resolveId(id, cxt) {
1683
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
+ }
1684
2272
  let value = void 0;
1685
- for (let i = store.inlineSlotData.length - 1; i >= 0; i--) {
1686
- const [_, data] = store.inlineSlotData[i];
2273
+ for (let i = store.inlineInstantiationData.length - 1; i >= 0; i--) {
2274
+ const data = store.inlineInstantiationData[i];
1687
2275
  if ((value = data.args.get(id)) !== void 0)
1688
2276
  break;
1689
2277
  }
1690
- for (let i = store.blockSlotData.length - 1; i >= 0; i--) {
1691
- const [_, data] = store.blockSlotData[i];
2278
+ for (let i = store.blockInstantiationData.length - 1; i >= 0; i--) {
2279
+ const data = store.blockInstantiationData[i];
1692
2280
  if ((value = data.args.get(id)) !== void 0)
1693
2281
  break;
1694
2282
  }
@@ -1696,53 +2284,62 @@ function resolveId(id, cxt) {
1696
2284
  value = cxt.variables.get(id);
1697
2285
  return value;
1698
2286
  }
1699
- var GetVarInlineMod = new InlineModifierDefinition("$", 2 /* Marker */, {
1700
- // .$:id
1701
- prepareExpand(node, cxt) {
1702
- const check = checkArguments(node, 1);
1703
- if (check) return check;
1704
- const arg = node.arguments[0];
1705
- const id = arg.expansion;
1706
- if (id == "")
1707
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
1708
- const value = resolveId(id, cxt);
1709
- if (value === void 0)
1710
- return [new UndefinedVariableMessage(arg.start, arg.end - arg.start, id)];
1711
- node.state = { value };
1712
- return [];
1713
- },
1714
- expand(node, cxt) {
1715
- if (!node.state) return [];
1716
- 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
+ }
1717
2311
  }
1718
- });
1719
- var PrintInlineMod = new InlineModifierDefinition("print", 2 /* Marker */, {
1720
- // .print:args...
1721
- prepareExpand(node) {
1722
- const check = checkArguments(node);
1723
- if (check) return check;
1724
- node.state = { value: node.arguments.map((x) => x.expansion).join("") };
1725
- return [];
1726
- },
1727
- expand(node) {
1728
- if (!node.state) return [];
1729
- return [{ type: 3 /* Text */, content: node.state.value, start: -1, end: -1 }];
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
+ }
1730
2328
  }
1731
- });
2329
+ );
1732
2330
  var GetVarInterpolator = new ArgumentInterpolatorDefinition(
1733
2331
  "$(",
1734
2332
  ")",
1735
2333
  {
1736
2334
  alwaysTryExpand: true,
1737
- expand(content, cxt, immediate) {
2335
+ expand(content, cxt) {
1738
2336
  const result = resolveId(content, cxt);
1739
- if (result === void 0) debug.trace("var interp failed:", content);
1740
- else debug.trace(`$(${content}) --> ${result}`);
2337
+ if (result !== void 0) debug.trace(`$(${content}) --> ${result}`);
1741
2338
  return result;
1742
2339
  }
1743
2340
  }
1744
2341
  );
1745
- var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
2342
+ var VarMod = new SystemModifierDefinition("var", 2 /* None */, {
1746
2343
  // .var id:value
1747
2344
  prepareExpand(node, cxt) {
1748
2345
  const check = checkArguments(node, 2);
@@ -1750,7 +2347,7 @@ var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
1750
2347
  const arg = node.arguments[0];
1751
2348
  const id = arg.expansion;
1752
2349
  if (id == "")
1753
- return [new InvalidArgumentMessage(arg.start, arg.end - arg.start)];
2350
+ return [new InvalidArgumentMessage(arg.location)];
1754
2351
  node.state = {
1755
2352
  id,
1756
2353
  value: node.arguments[1].expansion
@@ -1767,13 +2364,576 @@ var VarMod = new SystemModifierDefinition("var", 2 /* Marker */, {
1767
2364
  });
1768
2365
 
1769
2366
  // src/builtin/builtin.ts
1770
- var basic = new Configuration();
1771
- basic.initializers = [initParseContext];
1772
- basic.systemModifiers.add(DefineBlockMod, DefineInlineMod, VarMod, PushNotationMod, PopNotationMod);
1773
- basic.blockModifiers.add(SlotBlockMod);
1774
- basic.inlineModifiers.add(SlotInlineMod, GetVarInlineMod, PrintInlineMod);
1775
- basic.argumentInterpolators.add(GetVarInterpolator);
1776
- 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;
1777
2937
 
1778
2938
  // src/index.ts
1779
2939
  function setDebugLevel(level) {
@@ -1786,14 +2946,20 @@ function setDebugLevel(level) {
1786
2946
  BuiltinConfiguration,
1787
2947
  Configuration,
1788
2948
  DebugLevel,
2949
+ DefaultConfiguration,
1789
2950
  Document,
2951
+ HTMLRenderConfiguration,
2952
+ HTMLRenderState,
1790
2953
  InlineModifierDefinition,
1791
2954
  MessageSeverity,
1792
- ModifierFlags,
2955
+ ModifierSlotType,
1793
2956
  NodeType,
1794
2957
  ParseContext,
2958
+ RenderConfiguration,
2959
+ RenderContext,
1795
2960
  SimpleScanner,
1796
2961
  SystemModifierDefinition,
2962
+ debugPrint,
1797
2963
  messages,
1798
2964
  parse,
1799
2965
  setDebugLevel