@the_dissidents/libemmm 0.0.5 → 0.0.7

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.
Files changed (125) hide show
  1. package/README.md +28 -15
  2. package/dist/index.d.mts +75 -21
  3. package/dist/index.d.ts +75 -21
  4. package/dist/index.js +259 -78
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +257 -78
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +1 -1
  9. package/dist/src/builtin/builtin.d.ts +0 -2
  10. package/dist/src/builtin/builtin.js +0 -18
  11. package/dist/src/builtin/builtin.js.map +0 -1
  12. package/dist/src/builtin/define-modifier.d.ts +0 -12
  13. package/dist/src/builtin/define-modifier.js +0 -129
  14. package/dist/src/builtin/define-modifier.js.map +0 -1
  15. package/dist/src/builtin/define-shorthand.d.ts +0 -14
  16. package/dist/src/builtin/define-shorthand.js +0 -178
  17. package/dist/src/builtin/define-shorthand.js.map +0 -1
  18. package/dist/src/builtin/internal.d.ts +0 -41
  19. package/dist/src/builtin/internal.js +0 -106
  20. package/dist/src/builtin/internal.js.map +0 -1
  21. package/dist/src/builtin/module.d.ts +0 -16
  22. package/dist/src/builtin/module.js +0 -156
  23. package/dist/src/builtin/module.js.map +0 -1
  24. package/dist/src/builtin/slot.d.ts +0 -7
  25. package/dist/src/builtin/slot.js +0 -136
  26. package/dist/src/builtin/slot.js.map +0 -1
  27. package/dist/src/builtin/var.d.ts +0 -12
  28. package/dist/src/builtin/var.js +0 -103
  29. package/dist/src/builtin/var.js.map +0 -1
  30. package/dist/src/debug-print.d.ts +0 -14
  31. package/dist/src/debug-print.js +0 -113
  32. package/dist/src/debug-print.js.map +0 -1
  33. package/dist/src/debug.d.ts +0 -15
  34. package/dist/src/debug.js +0 -47
  35. package/dist/src/debug.js.map +0 -1
  36. package/dist/src/default/bullets.d.ts +0 -4
  37. package/dist/src/default/bullets.js +0 -39
  38. package/dist/src/default/bullets.js.map +0 -1
  39. package/dist/src/default/code.d.ts +0 -6
  40. package/dist/src/default/code.js +0 -13
  41. package/dist/src/default/code.js.map +0 -1
  42. package/dist/src/default/default.d.ts +0 -2
  43. package/dist/src/default/default.js +0 -20
  44. package/dist/src/default/default.js.map +0 -1
  45. package/dist/src/default/headings.d.ts +0 -20
  46. package/dist/src/default/headings.js +0 -125
  47. package/dist/src/default/headings.js.map +0 -1
  48. package/dist/src/default/html-renderer.d.ts +0 -26
  49. package/dist/src/default/html-renderer.js +0 -108
  50. package/dist/src/default/html-renderer.js.map +0 -1
  51. package/dist/src/default/inline-styles.d.ts +0 -4
  52. package/dist/src/default/inline-styles.js +0 -24
  53. package/dist/src/default/inline-styles.js.map +0 -1
  54. package/dist/src/default/misc.d.ts +0 -6
  55. package/dist/src/default/misc.js +0 -112
  56. package/dist/src/default/misc.js.map +0 -1
  57. package/dist/src/default/notes.d.ts +0 -28
  58. package/dist/src/default/notes.js +0 -109
  59. package/dist/src/default/notes.js.map +0 -1
  60. package/dist/src/default/quotes.d.ts +0 -4
  61. package/dist/src/default/quotes.js +0 -36
  62. package/dist/src/default/quotes.js.map +0 -1
  63. package/dist/src/default/vars.d.ts +0 -2
  64. package/dist/src/default/vars.js +0 -39
  65. package/dist/src/default/vars.js.map +0 -1
  66. package/dist/src/index.d.ts +0 -13
  67. package/dist/src/index.js +0 -58
  68. package/dist/src/index.js.map +0 -1
  69. package/dist/src/interface.d.ts +0 -174
  70. package/dist/src/interface.js +0 -93
  71. package/dist/src/interface.js.map +0 -1
  72. package/dist/src/messages.d.ts +0 -165
  73. package/dist/src/messages.js +0 -279
  74. package/dist/src/messages.js.map +0 -1
  75. package/dist/src/modifier-helper.d.ts +0 -6
  76. package/dist/src/modifier-helper.js +0 -113
  77. package/dist/src/modifier-helper.js.map +0 -1
  78. package/dist/src/parser-config.d.ts +0 -44
  79. package/dist/src/parser-config.js +0 -67
  80. package/dist/src/parser-config.js.map +0 -1
  81. package/dist/src/parser.d.ts +0 -3
  82. package/dist/src/parser.js +0 -652
  83. package/dist/src/parser.js.map +0 -1
  84. package/dist/src/renderer.d.ts +0 -49
  85. package/dist/src/renderer.js +0 -81
  86. package/dist/src/renderer.js.map +0 -1
  87. package/dist/src/scanner.d.ts +0 -22
  88. package/dist/src/scanner.js +0 -50
  89. package/dist/src/scanner.js.map +0 -1
  90. package/dist/src/temp.d.ts +0 -1
  91. package/dist/src/temp.js +0 -108
  92. package/dist/src/temp.js.map +0 -1
  93. package/dist/src/typing-helper.d.ts +0 -7
  94. package/dist/src/typing-helper.js +0 -3
  95. package/dist/src/typing-helper.js.map +0 -1
  96. package/dist/src/util.d.ts +0 -29
  97. package/dist/src/util.js +0 -177
  98. package/dist/src/util.js.map +0 -1
  99. package/dist/tests/advanced_syntax.test.d.ts +0 -1
  100. package/dist/tests/advanced_syntax.test.js +0 -180
  101. package/dist/tests/advanced_syntax.test.js.map +0 -1
  102. package/dist/tests/basic_syntax.test.d.ts +0 -1
  103. package/dist/tests/basic_syntax.test.js +0 -431
  104. package/dist/tests/basic_syntax.test.js.map +0 -1
  105. package/dist/tests/default/headings.test.d.ts +0 -1
  106. package/dist/tests/default/headings.test.js +0 -90
  107. package/dist/tests/default/headings.test.js.map +0 -1
  108. package/dist/tests/define_block.test.d.ts +0 -1
  109. package/dist/tests/define_block.test.js +0 -209
  110. package/dist/tests/define_block.test.js.map +0 -1
  111. package/dist/tests/define_inline.test.d.ts +0 -1
  112. package/dist/tests/define_inline.test.js +0 -289
  113. package/dist/tests/define_inline.test.js.map +0 -1
  114. package/dist/tests/modules.test.d.ts +0 -1
  115. package/dist/tests/modules.test.js +0 -137
  116. package/dist/tests/modules.test.js.map +0 -1
  117. package/dist/tests/shorthands.test.d.ts +0 -1
  118. package/dist/tests/shorthands.test.js +0 -79
  119. package/dist/tests/shorthands.test.js.map +0 -1
  120. package/dist/tsup.config.d.ts +0 -2
  121. package/dist/tsup.config.js +0 -12
  122. package/dist/tsup.config.js.map +0 -1
  123. package/dist/vitest.config.d.ts +0 -2
  124. package/dist/vitest.config.js +0 -17
  125. package/dist/vitest.config.js.map +0 -1
package/dist/index.js CHANGED
@@ -37,8 +37,10 @@ __export(index_exports, {
37
37
  RenderConfiguration: () => RenderConfiguration,
38
38
  RenderContext: () => RenderContext,
39
39
  SimpleScanner: () => SimpleScanner,
40
+ StringSource: () => StringSource,
40
41
  SystemModifierDefinition: () => SystemModifierDefinition,
41
42
  debugPrint: () => debugPrint,
43
+ emmmVersion: () => emmmVersion,
42
44
  messages: () => messages_exports,
43
45
  parse: () => parse,
44
46
  setDebugLevel: () => setDebugLevel
@@ -78,22 +80,38 @@ var ModifierBase = class {
78
80
  }
79
81
  roleHint;
80
82
  /**
81
- * If true, any modifier encountered in the content of it will *not* be expanded, *unless* that modifier is `alwaysTryExpand`.
83
+ * If true, any modifier encountered inside it will *not* be expanded *during parse-content*,
84
+ * *unless* that modifier is `alwaysTryExpand`. In the vast majority of cases, you shouldn't
85
+ * be using this.
82
86
  */
83
87
  delayContentExpansion = false;
84
88
  /**
85
- * If true, such a modifier will always be expanded whenever it is encountered, *even if* contained in a modifier with `delayContentExpansion`.
89
+ * If true, such a modifier will always be expanded whenever it is encountered, *even if*
90
+ * contained in a modifier with `delayContentExpansion`. In the vast majority of cases,
91
+ * you shouldn't be using this.
86
92
  */
87
93
  alwaysTryExpand = false;
88
- /** Called before the modifier's content is parsed. */
94
+ /** Called before the modifier's content is parsed.
95
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
96
+ */
89
97
  beforeParseContent;
90
- /** Called after the modifier's content is parsed. */
98
+ /** Called after the modifier's content is parsed.
99
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
100
+ */
91
101
  afterParseContent;
92
- /** Called before reparsing of the expansion. */
102
+ /** Called before reparsing of the expansion.
103
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.*/
93
104
  beforeProcessExpansion;
94
- /** Called before reparsing of the expansion. */
105
+ /** Called before reparsing of the expansion.
106
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.*/
95
107
  afterProcessExpansion;
108
+ /**
109
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
110
+ */
96
111
  prepareExpand;
112
+ /**
113
+ * @param immediate False when the node is inside a `delayContentExpansion` modifier, but it is `alwaysTryExpand`; otherwise true.
114
+ */
97
115
  expand;
98
116
  };
99
117
  var BlockModifierDefinition = class extends ModifierBase {
@@ -169,14 +187,6 @@ function assert(x) {
169
187
  throw error;
170
188
  }
171
189
  }
172
- function linePositions(src) {
173
- let result = [0];
174
- [...src].forEach((x, i) => {
175
- if (x == "\n") result.push(i + 1);
176
- });
177
- result.push(Infinity);
178
- return result;
179
- }
180
190
  var cloneArgument = (arg, options) => ({
181
191
  location: clonePosition(arg.location, options),
182
192
  content: arg.content.map((ent) => {
@@ -305,12 +315,52 @@ var debug = {
305
315
  }
306
316
  };
307
317
 
318
+ // src/source.ts
319
+ var StringSource = class {
320
+ constructor(d, src) {
321
+ this.src = src;
322
+ this.name = d.name;
323
+ this.lineMap = [0];
324
+ [...src].forEach((x, i) => {
325
+ if (x == "\n") this.lineMap.push(i + 1);
326
+ });
327
+ this.nLines = this.lineMap.length;
328
+ this.lineMap.push(Infinity);
329
+ }
330
+ name;
331
+ nLines;
332
+ lineMap;
333
+ getRowCol(pos) {
334
+ let line = -1, linepos = 0;
335
+ for (let i = 1; i < this.lineMap.length; i++) {
336
+ if (this.lineMap[i] > pos) {
337
+ line = i - 1;
338
+ linepos = this.lineMap[i - 1];
339
+ break;
340
+ }
341
+ }
342
+ return [line, pos - linepos];
343
+ }
344
+ getLineStart(n) {
345
+ assert(n >= 0);
346
+ if (n >= this.lineMap.length) return Infinity;
347
+ return this.lineMap[n];
348
+ }
349
+ getLine(n) {
350
+ const start = this.getLineStart(n);
351
+ const end = this.getLineStart(n + 1);
352
+ if (start === Infinity) return void 0;
353
+ return this.src.substring(start, end - 1);
354
+ }
355
+ };
356
+
308
357
  // src/scanner.ts
309
358
  var SimpleScanner = class {
310
- constructor(src, source = { name: "<input>" }) {
359
+ constructor(src, sourceDesc = { name: "<input>" }) {
311
360
  this.src = src;
312
- this.source = source;
361
+ this.source = new StringSource(sourceDesc, src);
313
362
  }
363
+ source;
314
364
  pos = 0;
315
365
  position() {
316
366
  return this.pos;
@@ -352,7 +402,8 @@ var debugPrint = {
352
402
  blockShorthand: (x) => x.name + x.parts.map((x2, i) => ` .. <arg${i}> .. ${x2}`).join("") + (x.mod.slotType == 2 /* None */ ? "" : ` .. <slot> .. ${x.postfix ?? "<no postfix>"}`),
353
403
  argument: (arg) => arg.content.map(debugPrintArgEntity).join(""),
354
404
  node: (...nodes) => nodes.map((x) => debugPrintNode(x)).join("\n"),
355
- message: (m, source, descriptor) => debugPrintMsg(m, descriptor, source),
405
+ message: debugPrintMsg,
406
+ range: debugPrintRange,
356
407
  document: debugDumpDocument
357
408
  };
358
409
  function debugPrintArgEntity(node) {
@@ -422,38 +473,46 @@ ${prefix}<expansion />`;
422
473
  }
423
474
  return result;
424
475
  }
425
- function debugPrintMsg(m, descriptor, source) {
426
- let pos = (pos2) => `@${pos2}`;
427
- if (source) {
428
- const lines = linePositions(source);
429
- pos = (pos2) => {
430
- let line = -1, linepos = 0;
431
- for (let i = 1; i < lines.length; i++) {
432
- if (lines[i] > pos2) {
433
- line = i;
434
- linepos = lines[i - 1];
435
- break;
436
- }
437
- }
438
- return `l${line}c${pos2 - linepos + 1}`;
439
- };
476
+ function debugPrintRange(loc, context = 1) {
477
+ const isSingleCharacter = loc.start == loc.end;
478
+ let [sr, sc] = loc.source.getRowCol(loc.start);
479
+ let [er, ec] = loc.source.getRowCol(loc.actualEnd ?? loc.end);
480
+ const rowWidth = Math.max((sr + 1).toString().length, (er + 1).toString().length);
481
+ const startLine = Math.max(0, sr - context);
482
+ const endLine = Math.min(loc.source.nLines - 1, er + context);
483
+ let lines = [];
484
+ for (let i = startLine; i <= endLine; i++) {
485
+ const line = loc.source.getLine(i);
486
+ lines.push((i + 1).toString().padStart(rowWidth) + " | " + line);
487
+ if (i >= sr && i <= er) {
488
+ const startPos = i == sr ? sc : 0;
489
+ const endPos = i == er ? ec : line.length;
490
+ lines.push(
491
+ " ".repeat(rowWidth) + " | " + " ".repeat(startPos) + (isSingleCharacter ? "^" : "~".repeat(endPos - startPos + 1))
492
+ );
493
+ }
440
494
  }
495
+ return lines.join("\n");
496
+ }
497
+ function debugPrintMsg(m) {
498
+ const poss = (loc2) => {
499
+ const [r1, c1] = loc2.source.getRowCol(loc2.start);
500
+ if (loc2.start == loc2.end) return `l${r1 + 1}c${c1 + 1}`;
501
+ const [r2, c2] = loc2.source.getRowCol(loc2.end);
502
+ return `l${r1 + 1}c${c1 + 1}-l${r2 + 1}c${c2 + 1}`;
503
+ };
441
504
  let loc = m.location;
442
- let result = `at ${pos(loc.start)}-${pos(loc.end)}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
443
- if (descriptor && m.location.source !== descriptor) {
444
- result += `
445
- warning: source descriptor mismatch: ${m.location.source.name}`;
446
- }
505
+ let result = `at ${poss(loc)}: ${MessageSeverity[m.severity]}[${m.code}]: ${m.info}`;
447
506
  while (loc = loc.original) {
448
507
  let d = loc.source !== m.location.source ? `(in ${loc.source.name}) ` : "";
449
508
  result += `
450
- ---> original at: ${d}${pos(loc.start)}-${pos(loc.end)}`;
509
+ ---> original at: ${d}${poss(loc)}`;
451
510
  }
452
511
  return result;
453
512
  }
454
- function debugDumpDocument(doc, source) {
513
+ function debugDumpDocument(doc) {
455
514
  let root = debugPrint.node(...doc.root.content);
456
- let msgs = doc.messages.map((x) => debugPrintMsg(x, doc.root.source, source)).join("\n");
515
+ let msgs = doc.messages.map((x) => debugPrintRange(x.location) + "\n" + debugPrintMsg(x)).join("\n");
457
516
  if (msgs.length > 0) msgs += "\n";
458
517
  return `Document: ${doc.root.source.name}
459
518
  ${msgs}${root}`;
@@ -465,7 +524,6 @@ __export(messages_exports, {
465
524
  ArgumentCountMismatchMessage: () => ArgumentCountMismatchMessage,
466
525
  CannotExpandArgumentMessage: () => CannotExpandArgumentMessage,
467
526
  CannotUseModuleInSelfMessage: () => CannotUseModuleInSelfMessage,
468
- ContentShouldBeOnNewlineMessage: () => ContentShouldBeOnNewlineMessage,
469
527
  EitherNormalOrPreMessage: () => EitherNormalOrPreMessage,
470
528
  EntityNotAllowedMessage: () => EntityNotAllowedMessage,
471
529
  ExpectedMessage: () => ExpectedMessage,
@@ -478,6 +536,7 @@ __export(messages_exports, {
478
536
  OverwriteDefinitionsMessage: () => OverwriteDefinitionsMessage,
479
537
  OverwriteSpecialVariableMessage: () => OverwriteSpecialVariableMessage,
480
538
  ReachedRecursionLimitMessage: () => ReachedRecursionLimitMessage,
539
+ ShouldBeOnNewlineMessage: () => ShouldBeOnNewlineMessage,
481
540
  SlotUsedOutsideDefinitionMessage: () => SlotUsedOutsideDefinitionMessage,
482
541
  UnclosedInlineModifierMessage: () => UnclosedInlineModifierMessage,
483
542
  UndefinedVariableMessage: () => UndefinedVariableMessage,
@@ -544,7 +603,7 @@ var UnknownModifierMessage = class {
544
603
  code = 2;
545
604
  severity = 2 /* Error */;
546
605
  get info() {
547
- return `unknown modifier '${this.what}'; did you forget to escape it?`;
606
+ return `unknown modifier '${this.what}'`;
548
607
  }
549
608
  // get fixes(): readonly FixSuggestion[] {
550
609
  // let [start, end] = [this.start, this.end];
@@ -714,13 +773,13 @@ var NewBlockShouldBeOnNewlineMessage = class extends AddThingMessage {
714
773
  );
715
774
  }
716
775
  };
717
- var ContentShouldBeOnNewlineMessage = class extends AddThingMessage {
776
+ var ShouldBeOnNewlineMessage = class extends AddThingMessage {
718
777
  constructor(location) {
719
778
  super(
720
779
  3,
721
780
  1 /* Warning */,
722
781
  location,
723
- "the content should begin in a new line to avoid confusion"
782
+ "the following should begin in a new line to avoid confusion"
724
783
  );
725
784
  }
726
785
  };
@@ -805,6 +864,41 @@ var Document = class _Document {
805
864
  );
806
865
  return doc;
807
866
  }
867
+ /**
868
+ * Performs a depth-first walk of the node tree.
869
+ */
870
+ walk(callback) {
871
+ let nodes = this.root.content;
872
+ let node;
873
+ while (node = nodes.shift()) {
874
+ const result = callback(node);
875
+ if (result == "break") break;
876
+ if (result == "skip") continue;
877
+ if ("arguments" in node)
878
+ nodes.push(...node.arguments.flatMap((x) => x.content));
879
+ if ("content" in node && Array.isArray(node.content))
880
+ nodes.push(...node.content);
881
+ }
882
+ }
883
+ /**
884
+ * Gets all nodes that covers the given position, from outermost to innermost (essentially a path).
885
+ */
886
+ resolvePosition(pos) {
887
+ const result = [];
888
+ let nodes = this.root.content;
889
+ let node;
890
+ while (node = nodes.shift()) {
891
+ if (node.location.start <= pos && (node.location.actualEnd ?? node.location.end) >= pos) {
892
+ result.push(node);
893
+ nodes = [];
894
+ if ("arguments" in node)
895
+ nodes.push(...node.arguments.flatMap((x) => x.content));
896
+ if ("content" in node && Array.isArray(node.content))
897
+ nodes.push(...node.content);
898
+ }
899
+ }
900
+ return result;
901
+ }
808
902
  };
809
903
  var Configuration = class _Configuration {
810
904
  initializers = [];
@@ -1061,7 +1155,7 @@ var Parser = class {
1061
1155
  SHOULD_BE_A_NEWLINE() {
1062
1156
  this.WHITESPACES();
1063
1157
  if (!this.scanner.accept("\n")) this.emit.message(
1064
- new ContentShouldBeOnNewlineMessage(this.#loc())
1158
+ new ShouldBeOnNewlineMessage(this.#loc())
1065
1159
  );
1066
1160
  }
1067
1161
  // TODO: this is awkward and doesn't emit messages in the most appropriate way
@@ -1151,14 +1245,28 @@ var Parser = class {
1151
1245
  if (grouped) this.SHOULD_BE_A_NEWLINE();
1152
1246
  const posContentStart = this.scanner.position();
1153
1247
  let posContentEnd = this.scanner.position();
1248
+ let paragraphEnd = void 0;
1154
1249
  let string = "";
1155
1250
  while (!this.scanner.isEOF()) {
1156
1251
  if (this.scanner.accept("\n")) {
1157
1252
  let white = "\n";
1158
- let char = "";
1253
+ let char;
1159
1254
  while ((char = this.scanner.acceptWhitespaceChar()) !== null)
1160
1255
  white += char;
1161
- if (grouped && this.scanner.accept(GROUP_END) || !grouped && this.scanner.accept("\n")) break;
1256
+ if (grouped && this.scanner.accept(GROUP_END)) {
1257
+ paragraphEnd = this.scanner.position();
1258
+ if (!this.scanner.isEOF()) {
1259
+ this.SHOULD_BE_A_NEWLINE();
1260
+ this.WARN_IF_MORE_NEWLINES_THAN(1);
1261
+ }
1262
+ break;
1263
+ }
1264
+ if (!grouped && this.scanner.accept("\n")) {
1265
+ paragraphEnd = this.scanner.position() - 1;
1266
+ if (!this.scanner.isEOF())
1267
+ this.WARN_IF_MORE_NEWLINES_THAN(0);
1268
+ break;
1269
+ }
1162
1270
  if (this.scanner.isEOF()) {
1163
1271
  if (grouped) this.emit.message(
1164
1272
  new ExpectedMessage(this.#loc(), GROUP_END)
@@ -1173,7 +1281,7 @@ var Parser = class {
1173
1281
  }
1174
1282
  const node = {
1175
1283
  type: 2 /* Preformatted */,
1176
- location: this.#locFrom(posStart),
1284
+ location: this.#locFrom(posStart, paragraphEnd ?? posContentEnd),
1177
1285
  content: {
1178
1286
  start: posContentStart,
1179
1287
  end: posContentEnd,
@@ -1190,6 +1298,10 @@ var Parser = class {
1190
1298
  this.WARN_IF_MORE_NEWLINES_THAN(1);
1191
1299
  while (!this.scanner.isEOF()) {
1192
1300
  if (this.scanner.accept(GROUP_END)) {
1301
+ if (!this.scanner.isEOF()) {
1302
+ this.SHOULD_BE_A_NEWLINE();
1303
+ this.WARN_IF_MORE_NEWLINES_THAN(1);
1304
+ }
1193
1305
  this.groupDepth--;
1194
1306
  return;
1195
1307
  }
@@ -1260,6 +1372,10 @@ var Parser = class {
1260
1372
  if (node.mod.delayContentExpansion) this.delayDepth++;
1261
1373
  let ok = true;
1262
1374
  if (isMarker) {
1375
+ if (!this.scanner.isEOF() && type == 7 /* BlockModifier */) {
1376
+ this.SHOULD_BE_A_NEWLINE();
1377
+ this.WARN_IF_MORE_NEWLINES_THAN(1);
1378
+ }
1263
1379
  if (type === 6 /* InlineModifier */) this.emit.addInlineNode(node);
1264
1380
  else this.emit.addBlockNode(node);
1265
1381
  } else if (type == 6 /* InlineModifier */) {
@@ -1306,6 +1422,10 @@ var Parser = class {
1306
1422
  return this.MODIFIER(6 /* InlineModifier */);
1307
1423
  if (this.scanner.peek(MODIFIER_SYSTEM_OPEN))
1308
1424
  return false;
1425
+ if (this.scanner.peek(MODIFIER_BLOCK_OPEN)) {
1426
+ this.SHOULD_BE_A_NEWLINE();
1427
+ return false;
1428
+ }
1309
1429
  const short = this.cxt.config.inlineShorthands.find((x) => this.scanner.accept(x.name));
1310
1430
  if (short) return this.SHORTHAND(6 /* InlineModifier */, short);
1311
1431
  if (this.scanner.accept("\\")) {
@@ -1540,28 +1660,33 @@ function onlyPermitPlaintextParagraph(node) {
1540
1660
  }
1541
1661
  return result;
1542
1662
  }
1663
+ function checkContent(ents) {
1664
+ if (ents.length == 0) return "";
1665
+ else if (ents.length > 1) {
1666
+ let last = ents.at(-1).location;
1667
+ return [new MultipleBlocksNotPermittedMessage({
1668
+ source: last.source,
1669
+ start: ents[1].location.start,
1670
+ end: last.actualEnd ?? last.end
1671
+ })];
1672
+ }
1673
+ return check(ents[0]);
1674
+ }
1543
1675
  function check(ent) {
1544
1676
  if (ent.type == 7 /* BlockModifier */) {
1545
1677
  if (!ent.expansion) return [new EntityNotAllowedMessage(
1546
1678
  ent.location,
1547
1679
  "it does not expand to plain text"
1548
1680
  )];
1549
- if (ent.expansion.length == 0) return "";
1550
- else if (ent.expansion.length > 1) {
1551
- let last = ent.expansion.at(-1).location;
1552
- return [new MultipleBlocksNotPermittedMessage({
1553
- source: last.source,
1554
- start: ent.expansion[1].location.start,
1555
- end: last.actualEnd ?? last.end
1556
- })];
1557
- }
1558
- return check(ent.expansion[0]);
1681
+ return checkContent(ent.expansion);
1682
+ } else if (ent.type == 2 /* Preformatted */) {
1683
+ return ent.content.text;
1559
1684
  } else if (ent.type !== 1 /* Paragraph */) {
1560
1685
  return [new OnlySimpleParagraphsPermittedMessage(ent.location)];
1561
1686
  }
1562
1687
  return checkInline(ent.content);
1563
1688
  }
1564
- return check(node);
1689
+ return checkContent(node.content);
1565
1690
  }
1566
1691
  function onlyPermitSimpleParagraphs(node) {
1567
1692
  function check(nodes) {
@@ -1641,24 +1766,20 @@ function customModifier(type, name, signature, content) {
1641
1766
  args: node.state.args,
1642
1767
  slotContent: node.content
1643
1768
  });
1769
+ debug.trace(`pushed ${NodeType[type]} slot data for`, name);
1644
1770
  debug.trace(
1645
- `pushed ${NodeType[type]} slot data for`,
1646
- name,
1647
- signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1771
+ `... slotName:`,
1772
+ signature.slotName === "" ? "<unnamed>" : signature.slotName === void 0 ? "<no slot>" : `'${signature.slotName}'`
1648
1773
  );
1774
+ debug.trace(`... args:`, "{" + [...node.state.args].map(([a, b]) => `${a} => ${b}`).join(", ") + "}");
1649
1775
  return [];
1650
1776
  };
1651
1777
  mod.afterProcessExpansion = (node, cxt) => {
1652
- if (!node.state?.ok || signature.slotName === void 0) return [];
1778
+ if (!node.state?.ok) return [];
1653
1779
  const store = cxt.get(builtins);
1654
1780
  const data = isInline ? store.inlineInstantiationData : store.blockInstantiationData;
1655
- const pop = data.pop();
1656
- assert(pop !== void 0);
1657
- debug.trace(
1658
- `popped ${NodeType[type]} slot data for`,
1659
- name,
1660
- signature.slotName == "" ? "(unnamed)" : `= ${signature.slotName}`
1661
- );
1781
+ data.pop();
1782
+ debug.trace(`popped ${NodeType[type]} slot data for`, name);
1662
1783
  return [];
1663
1784
  };
1664
1785
  return mod;
@@ -2011,6 +2132,17 @@ var DefineInlineShorthandMod = new SystemModifierDefinition(
2011
2132
  }
2012
2133
  );
2013
2134
 
2135
+ // src/builtin/misc.ts
2136
+ var RawBlockMod = new BlockModifierDefinition(
2137
+ "raw",
2138
+ 1 /* Preformatted */,
2139
+ {
2140
+ expand(node) {
2141
+ return node.content;
2142
+ }
2143
+ }
2144
+ );
2145
+
2014
2146
  // src/builtin/module.ts
2015
2147
  function getDefs(cxt) {
2016
2148
  const data = cxt.get(builtins);
@@ -2307,6 +2439,48 @@ function resolveId(id, cxt) {
2307
2439
  value = cxt.variables.get(id);
2308
2440
  return value;
2309
2441
  }
2442
+ var ifdefBlock = (name, x) => new BlockModifierDefinition(
2443
+ name,
2444
+ 0 /* Normal */,
2445
+ {
2446
+ prepareExpand(node, cxt) {
2447
+ const check = checkArguments(node, 1);
2448
+ if (check) return check;
2449
+ const arg = node.arguments[0];
2450
+ const id = arg.expansion;
2451
+ if (id == "") return [new InvalidArgumentMessage(arg.location)];
2452
+ const value = resolveId(id, cxt);
2453
+ node.state = value !== void 0;
2454
+ return [];
2455
+ },
2456
+ expand(node) {
2457
+ return node.state == x ? node.content : [];
2458
+ }
2459
+ }
2460
+ );
2461
+ var ifdefInline = (name, x) => new InlineModifierDefinition(
2462
+ name,
2463
+ 0 /* Normal */,
2464
+ {
2465
+ prepareExpand(node, cxt) {
2466
+ const check = checkArguments(node, 1);
2467
+ if (check) return check;
2468
+ const arg = node.arguments[0];
2469
+ const id = arg.expansion;
2470
+ if (id == "") return [new InvalidArgumentMessage(arg.location)];
2471
+ const value = resolveId(id, cxt);
2472
+ node.state = value !== void 0;
2473
+ return [];
2474
+ },
2475
+ expand(node) {
2476
+ return node.state == x ? node.content : [];
2477
+ }
2478
+ }
2479
+ );
2480
+ var IfdefBlockMod = ifdefBlock("ifdef", true);
2481
+ var IfndefBlockMod = ifdefBlock("ifndef", false);
2482
+ var IfdefInlineMod = ifdefInline("ifdef", true);
2483
+ var IfndefInlineMod = ifdefInline("ifndef", false);
2310
2484
  var GetVarInlineMod = new InlineModifierDefinition(
2311
2485
  "$",
2312
2486
  2 /* None */,
@@ -2402,14 +2576,19 @@ builtin.blockModifiers.add(
2402
2576
  PreSlotBlockMod,
2403
2577
  InjectPreSlotBlockMod,
2404
2578
  ModuleMod,
2405
- UseBlockMod
2579
+ UseBlockMod,
2580
+ IfdefBlockMod,
2581
+ IfndefBlockMod,
2582
+ RawBlockMod
2406
2583
  );
2407
2584
  builtin.inlineModifiers.add(
2408
2585
  SlotInlineMod,
2409
2586
  PreSlotInlineMod,
2410
2587
  InjectPreSlotInlineMod,
2411
2588
  GetVarInlineMod,
2412
- PrintInlineMod
2589
+ PrintInlineMod,
2590
+ IfdefInlineMod,
2591
+ IfndefInlineMod
2413
2592
  );
2414
2593
  builtin.argumentInterpolators.add(GetVarInterpolator);
2415
2594
  var BuiltinConfiguration = Object.freeze(builtin);
@@ -2482,9 +2661,8 @@ var headingBlock = new BlockModifierDefinition(
2482
2661
  "heading",
2483
2662
  0 /* Normal */,
2484
2663
  {
2485
- delayContentExpansion: true,
2486
2664
  roleHint: "heading",
2487
- beforeParseContent(node, cxt) {
2665
+ prepareExpand(node, cxt) {
2488
2666
  let msgs = checkArguments(node, 0, 1);
2489
2667
  if (msgs) return msgs;
2490
2668
  msgs = onlyPermitSingleBlock(node);
@@ -2512,7 +2690,7 @@ var implicitHeadingBlock = new BlockModifierDefinition(
2512
2690
  2 /* None */,
2513
2691
  {
2514
2692
  roleHint: "heading",
2515
- beforeParseContent(node, cxt) {
2693
+ prepareExpand(node, cxt) {
2516
2694
  let msgs = checkArguments(node, 0, 1);
2517
2695
  if (msgs) return msgs;
2518
2696
  node.state = {
@@ -2539,9 +2717,8 @@ var numberedHeadingBlock = new BlockModifierDefinition(
2539
2717
  "numbered-heading",
2540
2718
  0 /* Normal */,
2541
2719
  {
2542
- delayContentExpansion: true,
2543
2720
  roleHint: "heading",
2544
- beforeParseContent(node, cxt) {
2721
+ prepareExpand(node, cxt) {
2545
2722
  let msgs = checkArguments(node, 1);
2546
2723
  if (msgs) return msgs;
2547
2724
  msgs = onlyPermitSingleBlock(node);
@@ -2886,7 +3063,7 @@ var MiscBlockRenderersHTML = [
2886
3063
  [styleBlock, (node, cxt) => {
2887
3064
  if (node.state === void 0)
2888
3065
  return cxt.state.invalidBlock(node, "bad format");
2889
- return `<div class="${node.state}" style="display:contents">${cxt.state.render(node.content, cxt)}</div>`;
3066
+ return `<div class="emmmstyle-${node.state}" style="display:contents">${cxt.state.render(node.content, cxt)}</div>`;
2890
3067
  }],
2891
3068
  [breakBlock, () => {
2892
3069
  return `<hr>`;
@@ -2925,6 +3102,7 @@ function createWrapper(name, varname) {
2925
3102
  if (previous)
2926
3103
  msgs = [new OverwriteSpecialVariableMessage(node.head, varname, previous)];
2927
3104
  cxt.variables.set(varname, result);
3105
+ debug.trace(varname, "->", result);
2928
3106
  return msgs ?? [];
2929
3107
  }
2930
3108
  });
@@ -3060,6 +3238,7 @@ htmlConfig.addInlineRenderer(
3060
3238
  var HTMLRenderConfiguration = htmlConfig;
3061
3239
 
3062
3240
  // src/index.ts
3241
+ var emmmVersion = "0.0.6";
3063
3242
  function setDebugLevel(level) {
3064
3243
  debug.level = level;
3065
3244
  }
@@ -3082,8 +3261,10 @@ function setDebugLevel(level) {
3082
3261
  RenderConfiguration,
3083
3262
  RenderContext,
3084
3263
  SimpleScanner,
3264
+ StringSource,
3085
3265
  SystemModifierDefinition,
3086
3266
  debugPrint,
3267
+ emmmVersion,
3087
3268
  messages,
3088
3269
  parse,
3089
3270
  setDebugLevel