@aurodesignsystem-dev/auro-formkit 0.0.0-pr1625.1 → 0.0.0-pr1627.0

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 (63) hide show
  1. package/components/bibtemplate/dist/index.js +9 -7
  2. package/components/bibtemplate/dist/registered.js +9 -7
  3. package/components/checkbox/demo/customize.min.js +8 -4
  4. package/components/checkbox/demo/demo-support.min.js +1303 -643
  5. package/components/checkbox/demo/getting-started.min.js +8 -4
  6. package/components/checkbox/demo/index.min.js +8 -4
  7. package/components/checkbox/dist/index.js +7 -3
  8. package/components/checkbox/dist/registered.js +7 -3
  9. package/components/combobox/demo/customize.min.js +392 -179
  10. package/components/combobox/demo/demo-support.min.js +1303 -643
  11. package/components/combobox/demo/getting-started.min.js +392 -179
  12. package/components/combobox/demo/index.min.js +392 -179
  13. package/components/combobox/dist/index.js +389 -176
  14. package/components/combobox/dist/registered.js +389 -176
  15. package/components/counter/demo/api.md +0 -1
  16. package/components/counter/demo/customize.md +4 -4
  17. package/components/counter/demo/customize.min.js +341 -182
  18. package/components/counter/demo/demo-support.min.js +1303 -643
  19. package/components/counter/demo/getting-started.min.js +341 -182
  20. package/components/counter/demo/index.min.js +341 -182
  21. package/components/counter/dist/auro-counter-group.d.ts +0 -7
  22. package/components/counter/dist/index.js +339 -180
  23. package/components/counter/dist/registered.js +339 -180
  24. package/components/datepicker/demo/customize.min.js +425 -192
  25. package/components/datepicker/demo/demo-support.min.js +1303 -643
  26. package/components/datepicker/demo/getting-started.min.js +425 -192
  27. package/components/datepicker/demo/index.min.js +425 -192
  28. package/components/datepicker/dist/index.js +423 -190
  29. package/components/datepicker/dist/registered.js +423 -190
  30. package/components/dropdown/demo/customize.min.js +313 -154
  31. package/components/dropdown/demo/demo-support.min.js +1303 -643
  32. package/components/dropdown/demo/getting-started.min.js +375 -168
  33. package/components/dropdown/demo/index.min.js +313 -154
  34. package/components/dropdown/dist/index.js +311 -152
  35. package/components/dropdown/dist/registered.js +311 -152
  36. package/components/form/demo/customize.min.js +1568 -740
  37. package/components/form/demo/demo-support.min.js +1303 -643
  38. package/components/form/demo/getting-started.min.js +1568 -740
  39. package/components/form/demo/index.min.js +1568 -740
  40. package/components/form/demo/registerDemoDeps.min.js +1568 -740
  41. package/components/input/demo/customize.min.js +64 -16
  42. package/components/input/demo/demo-support.min.js +1303 -643
  43. package/components/input/demo/getting-started.min.js +64 -16
  44. package/components/input/demo/index.min.js +64 -16
  45. package/components/input/dist/auro-input.d.ts +14 -0
  46. package/components/input/dist/index.js +62 -14
  47. package/components/input/dist/registered.js +62 -14
  48. package/components/menu/demo/demo-support.min.js +1303 -643
  49. package/components/menu/demo/index.min.js +1 -1
  50. package/components/radio/demo/customize.min.js +8 -4
  51. package/components/radio/demo/demo-support.min.js +1303 -643
  52. package/components/radio/demo/getting-started.min.js +8 -4
  53. package/components/radio/demo/index.min.js +8 -4
  54. package/components/radio/dist/index.js +7 -3
  55. package/components/radio/dist/registered.js +7 -3
  56. package/components/select/demo/customize.min.js +331 -166
  57. package/components/select/demo/demo-support.min.js +1303 -643
  58. package/components/select/demo/getting-started.min.js +331 -166
  59. package/components/select/demo/index.min.js +331 -166
  60. package/components/select/dist/index.js +329 -164
  61. package/components/select/dist/registered.js +329 -164
  62. package/custom-elements.json +1548 -1542
  63. package/package.json +56 -56
@@ -5749,7 +5749,7 @@ function normalizeUri(value) {
5749
5749
  */
5750
5750
 
5751
5751
 
5752
- // To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`.
5752
+ // To do: implement `spaceOrTabWithOptions` (`connect`, `content`).
5753
5753
 
5754
5754
  /**
5755
5755
  * Parse spaces and tabs.
@@ -5777,14 +5777,14 @@ function normalizeUri(value) {
5777
5777
  * @param {State} ok
5778
5778
  * State switched to when successful.
5779
5779
  * @param {TokenType} type
5780
- * Type (`' \t'`).
5780
+ * Type of the whole whitespace.
5781
5781
  * @param {number | undefined} [max=Infinity]
5782
5782
  * Max (exclusive).
5783
5783
  * @returns {State}
5784
5784
  * Start state.
5785
5785
  */
5786
5786
  function factorySpace(effects, ok, type, max) {
5787
- const limit = max ? max - 1 : Number.POSITIVE_INFINITY;
5787
+ const limit = max ? max - 1 : Infinity;
5788
5788
  let size = 0;
5789
5789
  return start;
5790
5790
 
@@ -5808,6 +5808,58 @@ function factorySpace(effects, ok, type, max) {
5808
5808
  }
5809
5809
  }
5810
5810
 
5811
+ /**
5812
+ * Parse spaces and tabs, with a required minimum and maximum, matching
5813
+ * `markdown-rs`’s `space_or_tab_min_max`.
5814
+ *
5815
+ * Unlike `factorySpace`, this can fail: `nok` is used when fewer than
5816
+ * `min` spaces or tabs are found.
5817
+ *
5818
+ * @param {Effects} effects
5819
+ * Context.
5820
+ * @param {State} ok
5821
+ * State switched to when successful.
5822
+ * @param {State} nok
5823
+ * State switched to when unsuccessful.
5824
+ * @param {TokenType} type
5825
+ * Type of the whole whitespace.
5826
+ * @param {number} min
5827
+ * Minimum allowed characters (inclusive).
5828
+ * @param {number} max
5829
+ * Maximum allowed characters (inclusive).
5830
+ * @returns {State}
5831
+ * Start state.
5832
+ */
5833
+ function factorySpaceMinMax(effects, ok, nok, type, min, max) {
5834
+ let size = 0;
5835
+ return start;
5836
+
5837
+ /** @type {State} */
5838
+ function start(code) {
5839
+ if (markdownSpace(code)) {
5840
+ effects.enter(type);
5841
+ return prefix(code);
5842
+ }
5843
+ return after(code);
5844
+ }
5845
+
5846
+ /** @type {State} */
5847
+ function prefix(code) {
5848
+ if (markdownSpace(code) && size < max) {
5849
+ effects.consume(code);
5850
+ size++;
5851
+ return prefix;
5852
+ }
5853
+ effects.exit(type);
5854
+ return after(code);
5855
+ }
5856
+
5857
+ /** @type {State} */
5858
+ function after(code) {
5859
+ return size >= min ? ok(code) : nok(code);
5860
+ }
5861
+ }
5862
+
5811
5863
  /**
5812
5864
  * @import {
5813
5865
  * InitialConstruct,
@@ -5886,6 +5938,232 @@ function initializeContent(effects) {
5886
5938
  }
5887
5939
  }
5888
5940
 
5941
+ /**
5942
+ * @import {Event} from 'micromark-util-types'
5943
+ */
5944
+
5945
+ /**
5946
+ * @typedef {[number, number, Array<Event>]} Change
5947
+ * @typedef {[number, number, number]} Jump
5948
+ */
5949
+
5950
+ /**
5951
+ * Tracks a bunch of edits.
5952
+ *
5953
+ * Port of `edit_map.rs` from `markdown-rs`:
5954
+ * <https://github.com/wooorm/markdown-rs/blob/1506572f/src/util/edit_map.rs>.
5955
+ *
5956
+ * Deal with several changes in events, batching them together.
5957
+ *
5958
+ * Preferably, changes should be kept to a minimum.
5959
+ * Sometimes, it’s needed to change the list of events, because parsing can be
5960
+ * messy, and it helps to expose a cleaner interface of events to the compiler
5961
+ * and other users.
5962
+ * It can also help to merge many adjacent similar events.
5963
+ * And, in other cases, it’s needed to parse subcontent: pass some events
5964
+ * through another tokenizer and inject the result.
5965
+ */
5966
+ let EditMap$1 = class EditMap {
5967
+ /**
5968
+ * Create a new edit map.
5969
+ *
5970
+ * @returns
5971
+ * New instance.
5972
+ */
5973
+ constructor() {
5974
+ /**
5975
+ * Changes by index, so `add` does not need to scan `map` (which is
5976
+ * quadratic for documents with many edits at different places).
5977
+ *
5978
+ * @type {Map<number, Change>}
5979
+ */
5980
+ this.index = new Map();
5981
+
5982
+ /**
5983
+ * Record of changes.
5984
+ *
5985
+ * @type {Array<Change>}
5986
+ */
5987
+ this.map = [];
5988
+ }
5989
+
5990
+ /**
5991
+ * Create an edit: a remove and/or add at a certain place.
5992
+ *
5993
+ * @param {number} index
5994
+ * Index at which to apply the edit.
5995
+ * @param {number} remove
5996
+ * Count of items to remove at the index.
5997
+ * @param {Array<Event>} add
5998
+ * Items to add at the index.
5999
+ * @returns {undefined}
6000
+ * Nothing.
6001
+ */
6002
+ add(index, remove, add) {
6003
+ addImplementation$1(this, index, remove, add, false);
6004
+ }
6005
+
6006
+ /**
6007
+ * Create an edit: but insert `add` before existing additions, instead of
6008
+ * after them.
6009
+ *
6010
+ * @param {number} index
6011
+ * Index at which to apply the edit.
6012
+ * @param {number} remove
6013
+ * Count of items to remove at the index.
6014
+ * @param {Array<Event>} add
6015
+ * Items to add at the index.
6016
+ * @returns {undefined}
6017
+ * Nothing.
6018
+ */
6019
+ addBefore(index, remove, add) {
6020
+ addImplementation$1(this, index, remove, add, true);
6021
+ }
6022
+
6023
+ /**
6024
+ * Done, change the events.
6025
+ *
6026
+ * @param {Array<Event>} events
6027
+ * List of events to apply the edits to.
6028
+ * @returns {undefined}
6029
+ * Nothing.
6030
+ */
6031
+ consume(events) {
6032
+ this.map.sort(function (a, b) {
6033
+ return a[0] - b[0];
6034
+ });
6035
+ if (this.map.length === 0) {
6036
+ return;
6037
+ }
6038
+
6039
+ // To do: if links are added in events, like they are in `markdown-rs`,
6040
+ // this is needed.
6041
+ // // Calculate jumps: where items in the current list move to.
6042
+ // /** @type {Array<Jump>} */
6043
+ // const jumps = []
6044
+ // let index = 0
6045
+ // let addAcc = 0
6046
+ // let removeAcc = 0
6047
+ // while (index < this.map.length) {
6048
+ // const [at, remove, add] = this.map[index]
6049
+ // removeAcc += remove
6050
+ // addAcc += add.length
6051
+ // jumps.push([at, removeAcc, addAcc])
6052
+ // index += 1
6053
+ // }
6054
+ //
6055
+ // shiftLinks(events, jumps)
6056
+
6057
+ let index = this.map.length;
6058
+ /** @type {Array<Array<Event>>} */
6059
+ const vecs = [];
6060
+ while (index > 0) {
6061
+ index -= 1;
6062
+ vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]);
6063
+
6064
+ // Truncate rest.
6065
+ events.length = this.map[index][0];
6066
+ }
6067
+ vecs.push(events.slice());
6068
+ events.length = 0;
6069
+ let slice = vecs.pop();
6070
+ while (slice) {
6071
+ for (const element of slice) {
6072
+ events.push(element);
6073
+ }
6074
+ slice = vecs.pop();
6075
+ }
6076
+
6077
+ // Truncate everything.
6078
+ this.map.length = 0;
6079
+ this.index.clear();
6080
+ }
6081
+ };
6082
+
6083
+ /**
6084
+ * Create an edit.
6085
+ *
6086
+ * @param {EditMap} editMap
6087
+ * Edit map to apply to.
6088
+ * @param {number} at
6089
+ * Index at which to apply the edit.
6090
+ * @param {number} remove
6091
+ * Count of items to remove at the index.
6092
+ * @param {Array<Event>} add
6093
+ * Items to add at the index.
6094
+ * @param {boolean} before
6095
+ * Insert `add` before existing additions at `at`, instead of after them.
6096
+ * @returns {undefined}
6097
+ * Nothing.
6098
+ */
6099
+ function addImplementation$1(editMap, at, remove, add, before) {
6100
+ if (remove === 0 && add.length === 0) {
6101
+ return;
6102
+ }
6103
+ const existing = editMap.index.get(at);
6104
+ if (existing) {
6105
+ existing[1] += remove;
6106
+ if (before) {
6107
+ add.push(...existing[2]);
6108
+ existing[2] = add;
6109
+ } else {
6110
+ existing[2].push(...add);
6111
+ }
6112
+ return;
6113
+ }
6114
+
6115
+ /** @type {Change} */
6116
+ const change = [at, remove, add];
6117
+ editMap.map.push(change);
6118
+ editMap.index.set(at, change);
6119
+ }
6120
+
6121
+ // /**
6122
+ // * Shift `previous` and `next` links according to `jumps`.
6123
+ // *
6124
+ // * This fixes links in case there are events removed or added between them.
6125
+ // *
6126
+ // * @param {Array<Event>} events
6127
+ // * @param {Array<Jump>} jumps
6128
+ // */
6129
+ // function shiftLinks(events, jumps) {
6130
+ // let jumpIndex = 0
6131
+ // let index = 0
6132
+ // let add = 0
6133
+ // let rm = 0
6134
+
6135
+ // while (index < events.length) {
6136
+ // const rmCurr = rm
6137
+
6138
+ // while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {
6139
+ // add = jumps[jumpIndex][2]
6140
+ // rm = jumps[jumpIndex][1]
6141
+ // jumpIndex += 1
6142
+ // }
6143
+
6144
+ // // Ignore items that will be removed.
6145
+ // if (rm > rmCurr) {
6146
+ // index += rm - rmCurr
6147
+ // } else {
6148
+ // // ?
6149
+ // // if let Some(link) = &events[index].link {
6150
+ // // if let Some(next) = link.next {
6151
+ // // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);
6152
+ // // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {
6153
+ // // add = jumps[jumpIndex].2;
6154
+ // // rm = jumps[jumpIndex].1;
6155
+ // // jumpIndex += 1;
6156
+ // // }
6157
+ // // events[index].link.as_mut().unwrap().next = Some(next + add - rm);
6158
+ // // index = next;
6159
+ // // continue;
6160
+ // // }
6161
+ // // }
6162
+ // index += 1
6163
+ // }
6164
+ // }
6165
+ // }
6166
+
5889
6167
  /**
5890
6168
  * @import {
5891
6169
  * Construct,
@@ -5988,12 +6266,12 @@ function initializeDocument(effects) {
5988
6266
  };
5989
6267
  index++;
5990
6268
  }
5991
-
6269
+ const editMap = new EditMap$1();
5992
6270
  // Inject the exits earlier (they’re still also at the end).
5993
- splice(self.events, indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits));
5994
-
6271
+ editMap.add(indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits));
5995
6272
  // Discard the duplicate exits.
5996
- self.events.length = index;
6273
+ editMap.add(indexBeforeExits, index - indexBeforeExits, []);
6274
+ editMap.consume(self.events);
5997
6275
  return checkNewContainers(code);
5998
6276
  }
5999
6277
  return start(code);
@@ -6036,7 +6314,9 @@ function initializeDocument(effects) {
6036
6314
 
6037
6315
  /** @type {State} */
6038
6316
  function thereIsANewContainer(code) {
6039
- if (childFlow) closeFlow();
6317
+ if (childFlow) {
6318
+ closeFlow();
6319
+ }
6040
6320
  exitContainers(continued);
6041
6321
  return documentContinued(code);
6042
6322
  }
@@ -6066,7 +6346,9 @@ function initializeDocument(effects) {
6066
6346
  /** @type {State} */
6067
6347
  function flowStart(code) {
6068
6348
  if (code === null) {
6069
- if (childFlow) closeFlow();
6349
+ if (childFlow) {
6350
+ closeFlow();
6351
+ }
6070
6352
  exitContainers(0);
6071
6353
  effects.consume(code);
6072
6354
  return;
@@ -6110,9 +6392,13 @@ function initializeDocument(effects) {
6110
6392
  */
6111
6393
  function writeToChild(token, endOfFile) {
6112
6394
  const stream = self.sliceStream(token);
6113
- if (endOfFile) stream.push(null);
6395
+ if (endOfFile) {
6396
+ stream.push(null);
6397
+ }
6114
6398
  token.previous = childToken;
6115
- if (childToken) childToken.next = token;
6399
+ if (childToken) {
6400
+ childToken.next = token;
6401
+ }
6116
6402
  childToken = token;
6117
6403
  childFlow.defineSkip(token.start);
6118
6404
  childFlow.write(stream);
@@ -6195,12 +6481,12 @@ function initializeDocument(effects) {
6195
6481
  };
6196
6482
  index++;
6197
6483
  }
6198
-
6484
+ const editMap = new EditMap$1();
6199
6485
  // Inject the exits earlier (they’re still also at the end).
6200
- splice(self.events, indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits));
6201
-
6486
+ editMap.add(indexBeforeFlow + 1, 0, self.events.slice(indexBeforeExits));
6202
6487
  // Discard the duplicate exits.
6203
- self.events.length = index;
6488
+ editMap.add(indexBeforeExits, index - indexBeforeExits, []);
6489
+ editMap.consume(self.events);
6204
6490
  }
6205
6491
  }
6206
6492
 
@@ -6316,7 +6602,7 @@ function resolveAll(constructs, events, context) {
6316
6602
  */
6317
6603
 
6318
6604
  /** @type {Construct} */
6319
- const attention = {
6605
+ const attention$2 = {
6320
6606
  name: 'attention',
6321
6607
  resolveAll: resolveAllAttention,
6322
6608
  tokenize: tokenizeAttention
@@ -6330,22 +6616,8 @@ const attention = {
6330
6616
  // eslint-disable-next-line complexity
6331
6617
  function resolveAllAttention(events, context) {
6332
6618
  let index = -1;
6333
- /** @type {number} */
6334
- let open;
6335
- /** @type {Token} */
6336
- let group;
6337
- /** @type {Token} */
6338
- let text;
6339
- /** @type {Token} */
6340
- let openingSequence;
6341
- /** @type {Token} */
6342
- let closingSequence;
6343
- /** @type {number} */
6344
- let use;
6345
6619
  /** @type {Array<Event>} */
6346
6620
  let nextEvents;
6347
- /** @type {number} */
6348
- let offset;
6349
6621
 
6350
6622
  // Walk through all events.
6351
6623
  //
@@ -6354,7 +6626,7 @@ function resolveAllAttention(events, context) {
6354
6626
  while (++index < events.length) {
6355
6627
  // Find a token that can close.
6356
6628
  if (events[index][0] === 'enter' && events[index][1].type === 'attentionSequence' && events[index][1]._close) {
6357
- open = index;
6629
+ let open = index;
6358
6630
 
6359
6631
  // Now walk back to find an opener.
6360
6632
  while (open--) {
@@ -6371,7 +6643,7 @@ function resolveAllAttention(events, context) {
6371
6643
  }
6372
6644
 
6373
6645
  // Number of markers to use from the sequence.
6374
- use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index][1].end.offset - events[index][1].start.offset > 1 ? 2 : 1;
6646
+ const use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index][1].end.offset - events[index][1].start.offset > 1 ? 2 : 1;
6375
6647
  const start = {
6376
6648
  ...events[open][1].end
6377
6649
  };
@@ -6380,21 +6652,21 @@ function resolveAllAttention(events, context) {
6380
6652
  };
6381
6653
  movePoint(start, -use);
6382
6654
  movePoint(end, use);
6383
- openingSequence = {
6655
+ const openingSequence = {
6384
6656
  type: use > 1 ? "strongSequence" : "emphasisSequence",
6385
6657
  start,
6386
6658
  end: {
6387
6659
  ...events[open][1].end
6388
6660
  }
6389
6661
  };
6390
- closingSequence = {
6662
+ const closingSequence = {
6391
6663
  type: use > 1 ? "strongSequence" : "emphasisSequence",
6392
6664
  start: {
6393
6665
  ...events[index][1].start
6394
6666
  },
6395
6667
  end
6396
6668
  };
6397
- text = {
6669
+ const text = {
6398
6670
  type: use > 1 ? "strongText" : "emphasisText",
6399
6671
  start: {
6400
6672
  ...events[open][1].end
@@ -6403,7 +6675,7 @@ function resolveAllAttention(events, context) {
6403
6675
  ...events[index][1].start
6404
6676
  }
6405
6677
  };
6406
- group = {
6678
+ const group = {
6407
6679
  type: use > 1 ? "strong" : "emphasis",
6408
6680
  start: {
6409
6681
  ...openingSequence.start
@@ -6436,12 +6708,13 @@ function resolveAllAttention(events, context) {
6436
6708
  // Closing.
6437
6709
  nextEvents = push(nextEvents, [['exit', text, context], ['enter', closingSequence, context], ['exit', closingSequence, context], ['exit', group, context]]);
6438
6710
 
6711
+ /** @type {number} */
6712
+ let offset = 0;
6713
+
6439
6714
  // If there are more markers in the closing, add them after.
6440
6715
  if (events[index][1].end.offset - events[index][1].start.offset) {
6441
6716
  offset = 2;
6442
6717
  nextEvents = push(nextEvents, [['enter', events[index][1], context], ['exit', events[index][1], context]]);
6443
- } else {
6444
- offset = 0;
6445
6718
  }
6446
6719
  splice(events, open - 1, index - open + 3, nextEvents);
6447
6720
  index = open + nextEvents.length - offset - 2;
@@ -6513,8 +6786,11 @@ function tokenizeAttention(effects, ok) {
6513
6786
 
6514
6787
  // Always populated by defaults.
6515
6788
 
6516
- const open = !after || after === 2 && before || attentionMarkers.includes(code);
6517
- const close = !before || before === 2 && after || attentionMarkers.includes(previous);
6789
+ // Note: `*` and `_` are in `attentionMarkers` through core.
6790
+ // They are excluded here as the loosening is meant for markers registered
6791
+ // by *other* constructs (such as GFM strikethrough’s `~`).
6792
+ const open = !after || after === 2 && before || attentionMarkers.includes(code) && code !== 42 && code !== 95;
6793
+ const close = !before || before === 2 && after || attentionMarkers.includes(previous) && previous !== 42 && previous !== 95;
6518
6794
  token._open = Boolean(marker === 42 ? open : open && (before || !close));
6519
6795
  token._close = Boolean(marker === 42 ? close : close && (after || !open));
6520
6796
  return ok(code);
@@ -7189,7 +7465,6 @@ function tokenizeCharacterReference(effects, ok, nok) {
7189
7465
 
7190
7466
  /**
7191
7467
  * @import {
7192
- * Code,
7193
7468
  * Construct,
7194
7469
  * State,
7195
7470
  * TokenizeContext,
@@ -7203,6 +7478,63 @@ const nonLazyContinuation = {
7203
7478
  tokenize: tokenizeNonLazyContinuation
7204
7479
  };
7205
7480
 
7481
+ /**
7482
+ * @this {TokenizeContext}
7483
+ * Context.
7484
+ * @type {Tokenizer}
7485
+ */
7486
+ function tokenizeNonLazyContinuation(effects, ok, nok) {
7487
+ const self = this;
7488
+ return start;
7489
+
7490
+ /**
7491
+ * At eol, before continuation.
7492
+ *
7493
+ * ```markdown
7494
+ * > | * ```js
7495
+ * ^
7496
+ * | b
7497
+ * ```
7498
+ *
7499
+ * @type {State}
7500
+ */
7501
+ function start(code) {
7502
+ if (code === null) {
7503
+ return nok(code);
7504
+ }
7505
+ effects.enter("lineEnding");
7506
+ effects.consume(code);
7507
+ effects.exit("lineEnding");
7508
+ return after;
7509
+ }
7510
+
7511
+ /**
7512
+ * A continuation.
7513
+ *
7514
+ * ```markdown
7515
+ * | * ```js
7516
+ * > | b
7517
+ * ^
7518
+ * ```
7519
+ *
7520
+ * @type {State}
7521
+ */
7522
+ function after(code) {
7523
+ return self.parser.lazy[self.now().line] ? nok(code) : ok(code);
7524
+ }
7525
+ }
7526
+
7527
+ /**
7528
+ * @import {
7529
+ * Code,
7530
+ * Construct,
7531
+ * State,
7532
+ * TokenizeContext,
7533
+ * Tokenizer
7534
+ * } from 'micromark-util-types'
7535
+ */
7536
+
7537
+
7206
7538
  /** @type {Construct} */
7207
7539
  const codeFenced = {
7208
7540
  concrete: true,
@@ -7612,40 +7944,6 @@ function tokenizeCodeFenced(effects, ok, nok) {
7612
7944
  }
7613
7945
  }
7614
7946
 
7615
- /**
7616
- * @this {TokenizeContext}
7617
- * Context.
7618
- * @type {Tokenizer}
7619
- */
7620
- function tokenizeNonLazyContinuation(effects, ok, nok) {
7621
- const self = this;
7622
- return start;
7623
-
7624
- /**
7625
- *
7626
- *
7627
- * @type {State}
7628
- */
7629
- function start(code) {
7630
- if (code === null) {
7631
- return nok(code);
7632
- }
7633
- effects.enter("lineEnding");
7634
- effects.consume(code);
7635
- effects.exit("lineEnding");
7636
- return lineStart;
7637
- }
7638
-
7639
- /**
7640
- *
7641
- *
7642
- * @type {State}
7643
- */
7644
- function lineStart(code) {
7645
- return self.parser.lazy[self.now().line] ? nok(code) : ok(code);
7646
- }
7647
- }
7648
-
7649
7947
  /**
7650
7948
  * @import {
7651
7949
  * Construct,
@@ -7673,7 +7971,6 @@ const furtherStart = {
7673
7971
  * @type {Tokenizer}
7674
7972
  */
7675
7973
  function tokenizeCodeIndented(effects, ok, nok) {
7676
- const self = this;
7677
7974
  return start;
7678
7975
 
7679
7976
  /**
@@ -7694,24 +7991,7 @@ function tokenizeCodeIndented(effects, ok, nok) {
7694
7991
  // To do: manually check if interrupting like `markdown-rs`.
7695
7992
 
7696
7993
  effects.enter("codeIndented");
7697
- // To do: use an improved `space_or_tab` function like `markdown-rs`,
7698
- // so that we can drop the next state.
7699
- return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code);
7700
- }
7701
-
7702
- /**
7703
- * At start, after 1 or 4 spaces.
7704
- *
7705
- * ```markdown
7706
- * > | aaa
7707
- * ^
7708
- * ```
7709
- *
7710
- * @type {State}
7711
- */
7712
- function afterPrefix(code) {
7713
- const tail = self.events[self.events.length - 1];
7714
- return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code) : nok(code);
7994
+ return factorySpaceMinMax(effects, atBreak, nok, "linePrefix", 4, 4)(code);
7715
7995
  }
7716
7996
 
7717
7997
  /**
@@ -7800,25 +8080,25 @@ function tokenizeFurtherStart(effects, ok, nok) {
7800
8080
  // To do: the code here in `micromark-js` is a bit different from
7801
8081
  // `markdown-rs` because there it can attempt spaces.
7802
8082
  // We can’t yet.
7803
- //
7804
- // To do: use an improved `space_or_tab` function like `markdown-rs`,
7805
- // so that we can drop the next state.
7806
- return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code);
8083
+ return factorySpaceMinMax(effects, ok, onNotEnoughPrefix, "linePrefix", 4, 4)(code);
7807
8084
  }
7808
8085
 
7809
8086
  /**
7810
- * At start, after 1 or 4 spaces.
8087
+ * After not enough of a prefix.
8088
+ *
8089
+ * A following line ending is another (potentially blank) line to try,
8090
+ * anything else means this isn’t a continuation.
7811
8091
  *
7812
8092
  * ```markdown
7813
8093
  * > | aaa
7814
- * ^
8094
+ *
8095
+ * | bbb
7815
8096
  * ```
7816
8097
  *
7817
8098
  * @type {State}
7818
8099
  */
7819
- function afterPrefix(code) {
7820
- const tail = self.events[self.events.length - 1];
7821
- return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok(code) : markdownLineEnding(code) ? furtherStart(code) : nok(code);
8100
+ function onNotEnoughPrefix(code) {
8101
+ return markdownLineEnding(code) ? furtherStart(code) : nok(code);
7822
8102
  }
7823
8103
  }
7824
8104
 
@@ -9565,10 +9845,6 @@ const headingAtx = {
9565
9845
  function resolveHeadingAtx(events, context) {
9566
9846
  let contentEnd = events.length - 2;
9567
9847
  let contentStart = 3;
9568
- /** @type {Token} */
9569
- let content;
9570
- /** @type {Token} */
9571
- let text;
9572
9848
 
9573
9849
  // Prefix whitespace, part of the opening.
9574
9850
  if (events[contentStart][1].type === "whitespace") {
@@ -9583,12 +9859,12 @@ function resolveHeadingAtx(events, context) {
9583
9859
  contentEnd -= contentStart + 1 === contentEnd ? 2 : 4;
9584
9860
  }
9585
9861
  if (contentEnd > contentStart) {
9586
- content = {
9862
+ const content = {
9587
9863
  type: "atxHeadingText",
9588
9864
  start: events[contentStart][1].start,
9589
9865
  end: events[contentEnd][1].end
9590
9866
  };
9591
- text = {
9867
+ const text = {
9592
9868
  type: "chunkText",
9593
9869
  start: events[contentStart][1].start,
9594
9870
  end: events[contentEnd][1].end,
@@ -9855,10 +10131,6 @@ const blankLineBefore = {
9855
10131
  partial: true,
9856
10132
  tokenize: tokenizeBlankLineBefore
9857
10133
  };
9858
- const nonLazyContinuationStart = {
9859
- partial: true,
9860
- tokenize: tokenizeNonLazyContinuationStart
9861
- };
9862
10134
 
9863
10135
  /** @type {Resolver} */
9864
10136
  function resolveToHtmlFlow(events) {
@@ -10437,7 +10709,7 @@ function tokenizeHtmlFlow(effects, ok, nok) {
10437
10709
  * @type {State}
10438
10710
  */
10439
10711
  function continuationStart(code) {
10440
- return effects.check(nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code);
10712
+ return effects.check(nonLazyContinuation, continuationStartNonLazy, continuationAfter)(code);
10441
10713
  }
10442
10714
 
10443
10715
  /**
@@ -10631,52 +10903,6 @@ function tokenizeHtmlFlow(effects, ok, nok) {
10631
10903
  }
10632
10904
  }
10633
10905
 
10634
- /**
10635
- * @this {TokenizeContext}
10636
- * Context.
10637
- * @type {Tokenizer}
10638
- */
10639
- function tokenizeNonLazyContinuationStart(effects, ok, nok) {
10640
- const self = this;
10641
- return start;
10642
-
10643
- /**
10644
- * At eol, before continuation.
10645
- *
10646
- * ```markdown
10647
- * > | * ```js
10648
- * ^
10649
- * | b
10650
- * ```
10651
- *
10652
- * @type {State}
10653
- */
10654
- function start(code) {
10655
- if (markdownLineEnding(code)) {
10656
- effects.enter("lineEnding");
10657
- effects.consume(code);
10658
- effects.exit("lineEnding");
10659
- return after;
10660
- }
10661
- return nok(code);
10662
- }
10663
-
10664
- /**
10665
- * A continuation.
10666
- *
10667
- * ```markdown
10668
- * | * ```js
10669
- * > | b
10670
- * ^
10671
- * ```
10672
- *
10673
- * @type {State}
10674
- */
10675
- function after(code) {
10676
- return self.parser.lazy[self.now().line] ? nok(code) : ok(code);
10677
- }
10678
- }
10679
-
10680
10906
  /**
10681
10907
  * @this {TokenizeContext}
10682
10908
  * Context.
@@ -11441,8 +11667,6 @@ function resolveAllLabelEnd(events) {
11441
11667
  function resolveToLabelEnd(events, context) {
11442
11668
  let index = events.length;
11443
11669
  let offset = 0;
11444
- /** @type {Token} */
11445
- let token;
11446
11670
  /** @type {number | undefined} */
11447
11671
  let open;
11448
11672
  /** @type {number | undefined} */
@@ -11452,7 +11676,7 @@ function resolveToLabelEnd(events, context) {
11452
11676
 
11453
11677
  // Find an opening.
11454
11678
  while (index--) {
11455
- token = events[index][1];
11679
+ const token = events[index][1];
11456
11680
  if (open) {
11457
11681
  // If we see another link, or inactive link label, we’ve been here before.
11458
11682
  if (token.type === "link" || token.type === "labelLink" && token._inactive) {
@@ -11535,18 +11759,18 @@ function resolveToLabelEnd(events, context) {
11535
11759
  */
11536
11760
  function tokenizeLabelEnd(effects, ok, nok) {
11537
11761
  const self = this;
11538
- let index = self.events.length;
11762
+ const labelStarts = self._labelStarts;
11539
11763
  /** @type {Token} */
11540
11764
  let labelStart;
11541
11765
  /** @type {boolean} */
11542
11766
  let defined;
11543
-
11544
- // Find an opening.
11545
- while (index--) {
11546
- if ((self.events[index][1].type === "labelImage" || self.events[index][1].type === "labelLink") && !self.events[index][1]._balanced) {
11547
- labelStart = self.events[index][1];
11548
- break;
11767
+ if (labelStarts) {
11768
+ // Discard ones that failed to close,
11769
+ // they’re not needed anymore.
11770
+ while (labelStarts.length > 0 && labelStarts[labelStarts.length - 1]._balanced) {
11771
+ labelStarts.pop();
11549
11772
  }
11773
+ labelStart = labelStarts[labelStarts.length - 1];
11550
11774
  }
11551
11775
  return start;
11552
11776
 
@@ -11665,6 +11889,9 @@ function tokenizeLabelEnd(effects, ok, nok) {
11665
11889
  */
11666
11890
  function labelEndOk(code) {
11667
11891
  // Note: `markdown-rs` does a bunch of stuff here.
11892
+ // This label start is now used up: discard it so it’s never found again.
11893
+
11894
+ labelStarts.pop();
11668
11895
  return ok(code);
11669
11896
  }
11670
11897
 
@@ -11938,6 +12165,7 @@ function tokenizeReferenceCollapsed(effects, ok, nok) {
11938
12165
  * @import {
11939
12166
  * Construct,
11940
12167
  * State,
12168
+ * Token,
11941
12169
  * TokenizeContext,
11942
12170
  * Tokenizer
11943
12171
  * } from 'micromark-util-types'
@@ -11958,6 +12186,8 @@ const labelStartImage = {
11958
12186
  */
11959
12187
  function tokenizeLabelStartImage(effects, ok, nok) {
11960
12188
  const self = this;
12189
+ /** @type {Token} */
12190
+ let labelImage;
11961
12191
  return start;
11962
12192
 
11963
12193
  /**
@@ -11993,7 +12223,7 @@ function tokenizeLabelStartImage(effects, ok, nok) {
11993
12223
  effects.enter("labelMarker");
11994
12224
  effects.consume(code);
11995
12225
  effects.exit("labelMarker");
11996
- effects.exit("labelImage");
12226
+ labelImage = effects.exit("labelImage");
11997
12227
  return after;
11998
12228
  }
11999
12229
  return nok(code);
@@ -12031,8 +12261,13 @@ function tokenizeLabelStartImage(effects, ok, nok) {
12031
12261
  // `micromark-extension-gfm-footnote`, but the `label-start-link`
12032
12262
  // behavior isn’t.
12033
12263
  // Hidden footnotes hook.
12034
- /* c8 ignore next 3 */
12035
- return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code);
12264
+ /* c8 ignore next 6 */
12265
+ if (code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs) {
12266
+ return nok(code);
12267
+ }
12268
+ self._labelStarts = self._labelStarts || [];
12269
+ self._labelStarts.push(labelImage);
12270
+ return ok(code);
12036
12271
  }
12037
12272
  }
12038
12273
 
@@ -12040,6 +12275,7 @@ function tokenizeLabelStartImage(effects, ok, nok) {
12040
12275
  * @import {
12041
12276
  * Construct,
12042
12277
  * State,
12278
+ * Token,
12043
12279
  * TokenizeContext,
12044
12280
  * Tokenizer
12045
12281
  * } from 'micromark-util-types'
@@ -12060,6 +12296,8 @@ const labelStartLink = {
12060
12296
  */
12061
12297
  function tokenizeLabelStartLink(effects, ok, nok) {
12062
12298
  const self = this;
12299
+ /** @type {Token} */
12300
+ let labelLink;
12063
12301
  return start;
12064
12302
 
12065
12303
  /**
@@ -12077,7 +12315,7 @@ function tokenizeLabelStartLink(effects, ok, nok) {
12077
12315
  effects.enter("labelMarker");
12078
12316
  effects.consume(code);
12079
12317
  effects.exit("labelMarker");
12080
- effects.exit("labelLink");
12318
+ labelLink = effects.exit("labelLink");
12081
12319
  return after;
12082
12320
  }
12083
12321
 
@@ -12086,8 +12324,13 @@ function tokenizeLabelStartLink(effects, ok, nok) {
12086
12324
  // To do: this isn’t needed in `micromark-extension-gfm-footnote`,
12087
12325
  // remove.
12088
12326
  // Hidden footnotes hook.
12089
- /* c8 ignore next 3 */
12090
- return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code);
12327
+ /* c8 ignore next 6 */
12328
+ if (code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs) {
12329
+ return nok(code);
12330
+ }
12331
+ self._labelStarts = self._labelStarts || [];
12332
+ self._labelStarts.push(labelLink);
12333
+ return ok(code);
12091
12334
  }
12092
12335
  }
12093
12336
 
@@ -12454,7 +12697,7 @@ const setextUnderline = {
12454
12697
 
12455
12698
  /** @type {Resolver} */
12456
12699
  function resolveToSetextUnderline(events, context) {
12457
- // To do: resolve like `markdown-rs`.
12700
+ const editMap = new EditMap$1();
12458
12701
  let index = events.length;
12459
12702
  /** @type {number | undefined} */
12460
12703
  let content;
@@ -12479,7 +12722,7 @@ function resolveToSetextUnderline(events, context) {
12479
12722
  else {
12480
12723
  if (events[index][1].type === "content") {
12481
12724
  // Remove the content end (if needed we’ll add it later)
12482
- events.splice(index, 1);
12725
+ editMap.add(index, 1, []);
12483
12726
  }
12484
12727
  if (!definition && events[index][1].type === "definition") {
12485
12728
  definition = index;
@@ -12502,8 +12745,8 @@ function resolveToSetextUnderline(events, context) {
12502
12745
  // If we have definitions in the content, we’ll keep on having content,
12503
12746
  // but we need move it.
12504
12747
  if (definition) {
12505
- events.splice(text, 0, ['enter', heading, context]);
12506
- events.splice(definition + 1, 0, ['exit', events[content][1], context]);
12748
+ editMap.add(text, 0, [['enter', heading, context]]);
12749
+ editMap.add(definition + 1, 0, [['exit', events[content][1], context]]);
12507
12750
  events[content][1].end = {
12508
12751
  ...events[definition][1].end
12509
12752
  };
@@ -12512,7 +12755,8 @@ function resolveToSetextUnderline(events, context) {
12512
12755
  }
12513
12756
 
12514
12757
  // Add the heading exit at the end.
12515
- events.push(['exit', heading, context]);
12758
+ editMap.add(events.length, 0, [['exit', heading, context]]);
12759
+ editMap.consume(events);
12516
12760
  return events;
12517
12761
  }
12518
12762
 
@@ -12818,6 +13062,7 @@ function createResolver(extraResolver) {
12818
13062
  * @type {Resolver}
12819
13063
  */
12820
13064
  function resolveAllLineSuffixes(events, context) {
13065
+ const editMap = new EditMap$1();
12821
13066
  let eventIndex = 0; // Skip first.
12822
13067
 
12823
13068
  while (++eventIndex <= events.length) {
@@ -12837,7 +13082,9 @@ function resolveAllLineSuffixes(events, context) {
12837
13082
  size++;
12838
13083
  bufferIndex--;
12839
13084
  }
12840
- if (bufferIndex) break;
13085
+ if (bufferIndex) {
13086
+ break;
13087
+ }
12841
13088
  bufferIndex = -1;
12842
13089
  }
12843
13090
  // Number
@@ -12875,13 +13122,13 @@ function resolveAllLineSuffixes(events, context) {
12875
13122
  if (data.start.offset === data.end.offset) {
12876
13123
  Object.assign(data, token);
12877
13124
  } else {
12878
- events.splice(eventIndex, 0, ['enter', token, context], ['exit', token, context]);
12879
- eventIndex += 2;
13125
+ editMap.add(eventIndex, 0, [['enter', token, context], ['exit', token, context]]);
12880
13126
  }
12881
13127
  }
12882
13128
  eventIndex++;
12883
13129
  }
12884
13130
  }
13131
+ editMap.consume(events);
12885
13132
  return events;
12886
13133
  }
12887
13134
 
@@ -12945,18 +13192,18 @@ const text$6 = {
12945
13192
  [-3]: lineEnding,
12946
13193
  [33]: labelStartImage,
12947
13194
  [38]: characterReference,
12948
- [42]: attention,
13195
+ [42]: attention$2,
12949
13196
  [60]: [autolink, htmlText],
12950
13197
  [91]: labelStartLink,
12951
13198
  [92]: [hardBreakEscape, characterEscape],
12952
13199
  [93]: labelEnd,
12953
- [95]: attention,
13200
+ [95]: attention$2,
12954
13201
  [96]: codeText
12955
13202
  };
12956
13203
 
12957
13204
  /** @satisfies {Extension['insideSpan']} */
12958
13205
  const insideSpan = {
12959
- null: [attention, resolver]
13206
+ null: [attention$2, resolver]
12960
13207
  };
12961
13208
 
12962
13209
  /** @satisfies {Extension['attentionMarkers']} */
@@ -13150,14 +13397,12 @@ function createTokenizer(parser, initialize, from) {
13150
13397
  * Nothing.
13151
13398
  */
13152
13399
  function main() {
13153
- /** @type {number} */
13154
- let chunkIndex;
13155
13400
  while (point._index < chunks.length) {
13156
13401
  const chunk = chunks[point._index];
13157
13402
 
13158
13403
  // If we’re in a buffer chunk, loop through it.
13159
13404
  if (typeof chunk === 'string') {
13160
- chunkIndex = point._index;
13405
+ const chunkIndex = point._index;
13161
13406
  if (point._bufferIndex < 0) {
13162
13407
  point._bufferIndex = 0;
13163
13408
  }
@@ -13513,38 +13758,42 @@ function serializeChunks(chunks, expandTabs) {
13513
13758
  let value;
13514
13759
  if (typeof chunk === 'string') {
13515
13760
  value = chunk;
13516
- } else switch (chunk) {
13517
- case -5:
13518
- {
13519
- value = "\r";
13520
- break;
13521
- }
13522
- case -4:
13523
- {
13524
- value = "\n";
13525
- break;
13526
- }
13527
- case -3:
13528
- {
13529
- value = "\r" + "\n";
13530
- break;
13531
- }
13532
- case -2:
13533
- {
13534
- value = expandTabs ? " " : "\t";
13535
- break;
13536
- }
13537
- case -1:
13538
- {
13539
- if (!expandTabs && atTab) continue;
13540
- value = " ";
13541
- break;
13542
- }
13543
- default:
13544
- {
13545
- // Currently only replacement character.
13546
- value = String.fromCharCode(chunk);
13547
- }
13761
+ } else {
13762
+ switch (chunk) {
13763
+ case -5:
13764
+ {
13765
+ value = "\r";
13766
+ break;
13767
+ }
13768
+ case -4:
13769
+ {
13770
+ value = "\n";
13771
+ break;
13772
+ }
13773
+ case -3:
13774
+ {
13775
+ value = "\r" + "\n";
13776
+ break;
13777
+ }
13778
+ case -2:
13779
+ {
13780
+ value = expandTabs ? " " : "\t";
13781
+ break;
13782
+ }
13783
+ case -1:
13784
+ {
13785
+ if (!expandTabs && atTab) {
13786
+ continue;
13787
+ }
13788
+ value = " ";
13789
+ break;
13790
+ }
13791
+ default:
13792
+ {
13793
+ // Currently only replacement character.
13794
+ value = String.fromCharCode(chunk);
13795
+ }
13796
+ }
13548
13797
  }
13549
13798
  atTab = chunk === -2;
13550
13799
  result.push(value);
@@ -13655,20 +13904,11 @@ function preprocess() {
13655
13904
  /** @type {Preprocessor} */
13656
13905
  // eslint-disable-next-line complexity
13657
13906
  function preprocessor(value, encoding, end) {
13907
+ value = buffer + (typeof value === 'string' ? value.toString() : new TextDecoder(encoding || undefined).decode(value));
13908
+
13658
13909
  /** @type {Array<Chunk>} */
13659
13910
  const chunks = [];
13660
- /** @type {RegExpMatchArray | null} */
13661
- let match;
13662
- /** @type {number} */
13663
- let next;
13664
- /** @type {number} */
13665
- let startPosition;
13666
- /** @type {number} */
13667
- let endPosition;
13668
- /** @type {Code} */
13669
- let code;
13670
- value = buffer + (typeof value === 'string' ? value.toString() : new TextDecoder(encoding || undefined).decode(value));
13671
- startPosition = 0;
13911
+ let startPosition = 0;
13672
13912
  buffer = '';
13673
13913
  if (start) {
13674
13914
  // To do: `markdown-rs` actually parses BOMs (byte order mark).
@@ -13679,9 +13919,9 @@ function preprocess() {
13679
13919
  }
13680
13920
  while (startPosition < value.length) {
13681
13921
  search$1.lastIndex = startPosition;
13682
- match = search$1.exec(value);
13683
- endPosition = match && match.index !== undefined ? match.index : value.length;
13684
- code = value.charCodeAt(endPosition);
13922
+ const match = search$1.exec(value);
13923
+ const endPosition = match && match.index !== undefined ? match.index : value.length;
13924
+ const code = value.charCodeAt(endPosition);
13685
13925
  if (!match) {
13686
13926
  buffer = value.slice(startPosition);
13687
13927
  break;
@@ -13707,9 +13947,11 @@ function preprocess() {
13707
13947
  }
13708
13948
  case 9:
13709
13949
  {
13710
- next = Math.ceil(column / 4) * 4;
13950
+ const next = Math.ceil(column / 4) * 4;
13711
13951
  chunks.push(-2);
13712
- while (column++ < next) chunks.push(-1);
13952
+ while (column++ < next) {
13953
+ chunks.push(-1);
13954
+ }
13713
13955
  break;
13714
13956
  }
13715
13957
  case 10:
@@ -13728,8 +13970,12 @@ function preprocess() {
13728
13970
  startPosition = endPosition + 1;
13729
13971
  }
13730
13972
  if (end) {
13731
- if (atCarriageReturn) chunks.push(-5);
13732
- if (buffer) chunks.push(buffer);
13973
+ if (atCarriageReturn) {
13974
+ chunks.push(-5);
13975
+ }
13976
+ if (buffer) {
13977
+ chunks.push(buffer);
13978
+ }
13733
13979
  chunks.push(null);
13734
13980
  }
13735
13981
  return chunks;
@@ -13862,6 +14108,8 @@ function fromMarkdown(value, encoding, options) {
13862
14108
  function compiler(options) {
13863
14109
  /** @type {Config} */
13864
14110
  const config = {
14111
+ afterExit: [],
14112
+ beforeEnter: [],
13865
14113
  transforms: [],
13866
14114
  canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'],
13867
14115
  enter: {
@@ -13977,7 +14225,8 @@ function compiler(options) {
13977
14225
  /** @type {Root} */
13978
14226
  let tree = {
13979
14227
  type: 'root',
13980
- children: []
14228
+ children: [],
14229
+ position: undefined
13981
14230
  };
13982
14231
  /** @type {Omit<CompileContext, 'sliceSerialize'>} */
13983
14232
  const context = {
@@ -13992,26 +14241,45 @@ function compiler(options) {
13992
14241
  };
13993
14242
  /** @type {Array<number>} */
13994
14243
  const listStack = [];
14244
+ /** @type {Array<Event>} */
14245
+ const prepared = [];
13995
14246
  let index = -1;
14247
+
14248
+ // Add `listItem` tokens and infer spread.
14249
+ // Each list is prepared while it is last in `prepared`, so nothing shifts.
13996
14250
  while (++index < events.length) {
13997
- // We preprocess lists to add `listItem` tokens, and to infer whether
13998
- // items the list itself are spread out.
14251
+ prepared.push(events[index]);
13999
14252
  if (events[index][1].type === "listOrdered" || events[index][1].type === "listUnordered") {
14000
14253
  if (events[index][0] === 'enter') {
14001
- listStack.push(index);
14254
+ listStack.push(prepared.length - 1);
14002
14255
  } else {
14003
14256
  const tail = listStack.pop();
14004
- index = prepareList(events, tail, index);
14257
+ prepareList(prepared, tail);
14005
14258
  }
14006
14259
  }
14007
14260
  }
14261
+ events = prepared;
14008
14262
  index = -1;
14009
14263
  while (++index < events.length) {
14010
14264
  const handler = config[events[index][0]];
14265
+ if (events[index][0] === 'enter' && config.beforeEnter.length > 0) {
14266
+ callListeners(config.beforeEnter, {
14267
+ ...context,
14268
+ sliceSerialize: events[index][2].sliceSerialize
14269
+ }, events[index][1]);
14270
+ }
14011
14271
  if (own$6.call(handler, events[index][1].type)) {
14012
- handler[events[index][1].type].call(Object.assign({
14272
+ // Note: spread first, V8 has optimizations for object shape cloning.
14273
+ handler[events[index][1].type].call({
14274
+ ...context,
14275
+ sliceSerialize: events[index][2].sliceSerialize
14276
+ }, events[index][1]);
14277
+ }
14278
+ if (events[index][0] === 'exit' && config.afterExit.length > 0) {
14279
+ callListeners(config.afterExit, {
14280
+ ...context,
14013
14281
  sliceSerialize: events[index][2].sliceSerialize
14014
- }, context), events[index][1]);
14282
+ }, events[index][1]);
14015
14283
  }
14016
14284
  }
14017
14285
 
@@ -14044,13 +14312,32 @@ function compiler(options) {
14044
14312
  return tree;
14045
14313
  }
14046
14314
 
14315
+ /**
14316
+ * @param {Array<Handle>} listeners
14317
+ * Listeners.
14318
+ * @param {CompileContext} context
14319
+ * Context.
14320
+ * @param {Token} token
14321
+ * Token.
14322
+ * @returns {undefined}
14323
+ * Nothing.
14324
+ */
14325
+ function callListeners(listeners, context, token) {
14326
+ let index = -1;
14327
+ while (++index < listeners.length) {
14328
+ listeners[index].call(context, token);
14329
+ }
14330
+ }
14331
+
14047
14332
  /**
14048
14333
  * @param {Array<Event>} events
14334
+ * Events, ending with the list to prepare.
14049
14335
  * @param {number} start
14050
- * @param {number} length
14051
- * @returns {number}
14336
+ * Index of the list enter.
14337
+ * @returns {undefined}
14052
14338
  */
14053
- function prepareList(events, start, length) {
14339
+ function prepareList(events, start) {
14340
+ const end = events.length - 1;
14054
14341
  let index = start - 1;
14055
14342
  let containerBalance = -1;
14056
14343
  let listSpread = false;
@@ -14062,7 +14349,14 @@ function compiler(options) {
14062
14349
  let firstBlankLineIndex;
14063
14350
  /** @type {boolean | undefined} */
14064
14351
  let atMarker;
14065
- while (++index <= length) {
14352
+ /**
14353
+ * `listItem` events to insert before the event at `at`, in walk order.
14354
+ * Merged in after the walk, as inserting while walking would shift the
14355
+ * rest of the list once per item.
14356
+ * @type {Array<{at: number, event: Event}>}
14357
+ */
14358
+ const insertions = [];
14359
+ while (++index <= end) {
14066
14360
  const event = events[index];
14067
14361
  switch (event[1].type) {
14068
14362
  case "listUnordered":
@@ -14126,9 +14420,10 @@ function compiler(options) {
14126
14420
 
14127
14421
  // Fix position.
14128
14422
  listItem.end = Object.assign({}, lineIndex ? events[lineIndex][1].start : event[1].end);
14129
- events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]);
14130
- index++;
14131
- length++;
14423
+ insertions.push({
14424
+ at: lineIndex || index,
14425
+ event: ['exit', listItem, event[2]]
14426
+ });
14132
14427
  }
14133
14428
 
14134
14429
  // Create a new list item.
@@ -14142,16 +14437,29 @@ function compiler(options) {
14142
14437
  end: undefined
14143
14438
  };
14144
14439
  listItem = item;
14145
- events.splice(index, 0, ['enter', item, event[2]]);
14146
- index++;
14147
- length++;
14440
+ insertions.push({
14441
+ at: index,
14442
+ event: ['enter', item, event[2]]
14443
+ });
14148
14444
  firstBlankLineIndex = undefined;
14149
14445
  atMarker = true;
14150
14446
  }
14151
14447
  }
14152
14448
  }
14449
+
14450
+ // The list is at the end of `events`: take it off, then push it back with
14451
+ // the insertions merged in.
14452
+ // Nothing follows the list, so nothing shifts.
14453
+ const listEvents = events.splice(start);
14454
+ let insertion = 0;
14455
+ index = -1;
14456
+ while (++index < listEvents.length) {
14457
+ while (insertion < insertions.length && insertions[insertion].at === start + index) {
14458
+ events.push(insertions[insertion++].event);
14459
+ }
14460
+ events.push(listEvents[index]);
14461
+ }
14153
14462
  events[start][1]._spread = listSpread;
14154
- return length;
14155
14463
  }
14156
14464
 
14157
14465
  /**
@@ -14238,7 +14546,8 @@ function compiler(options) {
14238
14546
  start: token.start,
14239
14547
  end: token.end
14240
14548
  }) + '): it’s not open');
14241
- } else if (open[0].type !== token.type) {
14549
+ }
14550
+ if (open[0].type !== token.type) {
14242
14551
  if (onExitError) {
14243
14552
  onExitError.call(this, token, open[0]);
14244
14553
  } else {
@@ -14707,11 +15016,18 @@ function compiler(options) {
14707
15016
  // Creaters.
14708
15017
  //
14709
15018
 
15019
+ // Each node factory pre-declares `position` as undefined as the trailing
15020
+ // property. enter() patches it to a real value, but the property already
15021
+ // exists, so V8 sees a single hidden class for each node type from
15022
+ // construction through the rest of the pipeline. Without the pre-declare,
15023
+ // each node took a hidden-class transition when enter() added position.
15024
+
14710
15025
  /** @returns {Blockquote} */
14711
15026
  function blockQuote() {
14712
15027
  return {
14713
15028
  type: 'blockquote',
14714
- children: []
15029
+ children: [],
15030
+ position: undefined
14715
15031
  };
14716
15032
  }
14717
15033
 
@@ -14721,7 +15037,8 @@ function compiler(options) {
14721
15037
  type: 'code',
14722
15038
  lang: null,
14723
15039
  meta: null,
14724
- value: ''
15040
+ value: '',
15041
+ position: undefined
14725
15042
  };
14726
15043
  }
14727
15044
 
@@ -14729,7 +15046,8 @@ function compiler(options) {
14729
15046
  function codeText() {
14730
15047
  return {
14731
15048
  type: 'inlineCode',
14732
- value: ''
15049
+ value: '',
15050
+ position: undefined
14733
15051
  };
14734
15052
  }
14735
15053
 
@@ -14740,7 +15058,8 @@ function compiler(options) {
14740
15058
  identifier: '',
14741
15059
  label: null,
14742
15060
  title: null,
14743
- url: ''
15061
+ url: '',
15062
+ position: undefined
14744
15063
  };
14745
15064
  }
14746
15065
 
@@ -14748,7 +15067,8 @@ function compiler(options) {
14748
15067
  function emphasis() {
14749
15068
  return {
14750
15069
  type: 'emphasis',
14751
- children: []
15070
+ children: [],
15071
+ position: undefined
14752
15072
  };
14753
15073
  }
14754
15074
 
@@ -14758,14 +15078,16 @@ function compiler(options) {
14758
15078
  type: 'heading',
14759
15079
  // @ts-expect-error `depth` will be set later.
14760
15080
  depth: 0,
14761
- children: []
15081
+ children: [],
15082
+ position: undefined
14762
15083
  };
14763
15084
  }
14764
15085
 
14765
15086
  /** @returns {Break} */
14766
15087
  function hardBreak() {
14767
15088
  return {
14768
- type: 'break'
15089
+ type: 'break',
15090
+ position: undefined
14769
15091
  };
14770
15092
  }
14771
15093
 
@@ -14773,7 +15095,8 @@ function compiler(options) {
14773
15095
  function html() {
14774
15096
  return {
14775
15097
  type: 'html',
14776
- value: ''
15098
+ value: '',
15099
+ position: undefined
14777
15100
  };
14778
15101
  }
14779
15102
 
@@ -14783,7 +15106,8 @@ function compiler(options) {
14783
15106
  type: 'image',
14784
15107
  title: null,
14785
15108
  url: '',
14786
- alt: null
15109
+ alt: null,
15110
+ position: undefined
14787
15111
  };
14788
15112
  }
14789
15113
 
@@ -14793,7 +15117,8 @@ function compiler(options) {
14793
15117
  type: 'link',
14794
15118
  title: null,
14795
15119
  url: '',
14796
- children: []
15120
+ children: [],
15121
+ position: undefined
14797
15122
  };
14798
15123
  }
14799
15124
 
@@ -14807,7 +15132,8 @@ function compiler(options) {
14807
15132
  ordered: token.type === 'listOrdered',
14808
15133
  start: null,
14809
15134
  spread: token._spread,
14810
- children: []
15135
+ children: [],
15136
+ position: undefined
14811
15137
  };
14812
15138
  }
14813
15139
 
@@ -14820,7 +15146,8 @@ function compiler(options) {
14820
15146
  type: 'listItem',
14821
15147
  spread: token._spread,
14822
15148
  checked: null,
14823
- children: []
15149
+ children: [],
15150
+ position: undefined
14824
15151
  };
14825
15152
  }
14826
15153
 
@@ -14828,7 +15155,8 @@ function compiler(options) {
14828
15155
  function paragraph() {
14829
15156
  return {
14830
15157
  type: 'paragraph',
14831
- children: []
15158
+ children: [],
15159
+ position: undefined
14832
15160
  };
14833
15161
  }
14834
15162
 
@@ -14836,7 +15164,8 @@ function compiler(options) {
14836
15164
  function strong() {
14837
15165
  return {
14838
15166
  type: 'strong',
14839
- children: []
15167
+ children: [],
15168
+ position: undefined
14840
15169
  };
14841
15170
  }
14842
15171
 
@@ -14844,14 +15173,16 @@ function compiler(options) {
14844
15173
  function text() {
14845
15174
  return {
14846
15175
  type: 'text',
14847
- value: ''
15176
+ value: '',
15177
+ position: undefined
14848
15178
  };
14849
15179
  }
14850
15180
 
14851
15181
  /** @returns {ThematicBreak} */
14852
15182
  function thematicBreak() {
14853
15183
  return {
14854
- type: 'thematicBreak'
15184
+ type: 'thematicBreak',
15185
+ position: undefined
14855
15186
  };
14856
15187
  }
14857
15188
  }
@@ -14916,6 +15247,15 @@ function extension(combined, extension) {
14916
15247
  }
14917
15248
  break;
14918
15249
  }
15250
+ case 'afterExit':
15251
+ case 'beforeEnter':
15252
+ {
15253
+ const right = extension[key];
15254
+ if (right) {
15255
+ combined[key].push(right);
15256
+ }
15257
+ break;
15258
+ }
14919
15259
  case 'enter':
14920
15260
  case 'exit':
14921
15261
  {
@@ -14941,12 +15281,11 @@ function defaultOnError(left, right) {
14941
15281
  start: right.start,
14942
15282
  end: right.end
14943
15283
  }) + ') is open');
14944
- } else {
14945
- throw new Error('Cannot close document, a token (`' + right.type + '`, ' + stringifyPosition({
14946
- start: right.start,
14947
- end: right.end
14948
- }) + ') is still open');
14949
15284
  }
15285
+ throw new Error('Cannot close document, a token (`' + right.type + '`, ' + stringifyPosition({
15286
+ start: right.start,
15287
+ end: right.end
15288
+ }) + ') is still open');
14950
15289
  }
14951
15290
 
14952
15291
  /**
@@ -15430,7 +15769,11 @@ function findAndReplace(tree, list, options) {
15430
15769
  visitParents(tree, 'text', visitor);
15431
15770
  }
15432
15771
 
15433
- /** @type {BuildVisitor<Root, 'text'>} */
15772
+ /**
15773
+ * Visit a text node, and handle it if it is not in an ignored parent.
15774
+ *
15775
+ * @type {BuildVisitor<Root, 'text'>}
15776
+ */
15434
15777
  function visitor(node, parents) {
15435
15778
  let index = -1;
15436
15779
  /** @type {Parents | undefined} */
@@ -15463,11 +15806,11 @@ function findAndReplace(tree, list, options) {
15463
15806
  * Handle a text node which is not in an ignored parent.
15464
15807
  *
15465
15808
  * @param {Text} node
15466
- * Text node.
15809
+ * Text node to search in.
15467
15810
  * @param {Array<Parents>} parents
15468
- * Parents.
15811
+ * Ancestors of `node`.
15469
15812
  * @returns {VisitorResult}
15470
- * Result.
15813
+ * Where to continue visiting.
15471
15814
  */
15472
15815
  function handler(node, parents) {
15473
15816
  const parent = parents[parents.length - 1];
@@ -15507,16 +15850,13 @@ function findAndReplace(tree, list, options) {
15507
15850
  find.lastIndex = position + 1;
15508
15851
  } else {
15509
15852
  if (start !== position) {
15510
- nodes.push({
15511
- type: 'text',
15512
- value: node.value.slice(start, position)
15513
- });
15853
+ add({type: 'text', value: node.value.slice(start, position)});
15514
15854
  }
15515
15855
 
15516
15856
  if (Array.isArray(value)) {
15517
- nodes.push(...value);
15857
+ for (const child of value) add(child);
15518
15858
  } else if (value) {
15519
- nodes.push(value);
15859
+ add(value);
15520
15860
  }
15521
15861
 
15522
15862
  start = position + match[0].length;
@@ -15532,7 +15872,7 @@ function findAndReplace(tree, list, options) {
15532
15872
 
15533
15873
  if (change) {
15534
15874
  if (start < node.value.length) {
15535
- nodes.push({type: 'text', value: node.value.slice(start)});
15875
+ add({type: 'text', value: node.value.slice(start)});
15536
15876
  }
15537
15877
 
15538
15878
  parent.children.splice(index, 1, ...nodes);
@@ -15541,6 +15881,24 @@ function findAndReplace(tree, list, options) {
15541
15881
  }
15542
15882
 
15543
15883
  return index + nodes.length
15884
+
15885
+ /**
15886
+ * Add a node.
15887
+ *
15888
+ * @param {PhrasingContent} child
15889
+ * Node to add.
15890
+ * @returns {undefined}
15891
+ * Nothing.
15892
+ */
15893
+ function add(child) {
15894
+ const previous = nodes[nodes.length - 1];
15895
+
15896
+ if (previous && previous.type === 'text' && child.type === 'text') {
15897
+ previous.value += child.value;
15898
+ } else {
15899
+ nodes.push(child);
15900
+ }
15901
+ }
15544
15902
  }
15545
15903
  }
15546
15904
 
@@ -15553,13 +15911,13 @@ function findAndReplace(tree, list, options) {
15553
15911
  * Clean pairs.
15554
15912
  */
15555
15913
  function toPairs(tupleOrList) {
15556
- /** @type {Pairs} */
15557
- const result = [];
15558
-
15559
15914
  if (!Array.isArray(tupleOrList)) {
15560
15915
  throw new TypeError('Expected find and replace tuple or list of tuples')
15561
15916
  }
15562
15917
 
15918
+ /** @type {Pairs} */
15919
+ const result = [];
15920
+
15563
15921
  /** @type {FindAndReplaceList} */
15564
15922
  // @ts-expect-error: correct.
15565
15923
  const list =
@@ -15581,9 +15939,9 @@ function toPairs(tupleOrList) {
15581
15939
  * Turn a find into an expression.
15582
15940
  *
15583
15941
  * @param {Find} find
15584
- * Find.
15942
+ * Pattern to find.
15585
15943
  * @returns {RegExp}
15586
- * Expression.
15944
+ * Global expression.
15587
15945
  */
15588
15946
  function toExpression(find) {
15589
15947
  return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find
@@ -15593,9 +15951,9 @@ function toExpression(find) {
15593
15951
  * Turn a replace into a function.
15594
15952
  *
15595
15953
  * @param {Replace} replace
15596
- * Replace.
15954
+ * Thing to replace with.
15597
15955
  * @returns {ReplaceFunction}
15598
- * Function.
15956
+ * Function that returns that thing.
15599
15957
  */
15600
15958
  function toFunction(replace) {
15601
15959
  return typeof replace === 'function'
@@ -16094,15 +16452,18 @@ function mapAll(line, index, blank) {
16094
16452
  }
16095
16453
 
16096
16454
  /**
16097
- * @typedef {import('mdast').Delete} Delete
16098
- *
16099
- * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext
16100
- * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension
16101
- * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle
16102
- *
16103
- * @typedef {import('mdast-util-to-markdown').ConstructName} ConstructName
16104
- * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle
16105
- * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension
16455
+ * @import {Delete} from 'mdast'
16456
+ * @import {
16457
+ * CompileContext,
16458
+ * Extension as FromMarkdownExtension,
16459
+ * Handle as FromMarkdownHandle
16460
+ * } from 'mdast-util-from-markdown'
16461
+ * @import {
16462
+ * Attention,
16463
+ * ConstructName,
16464
+ * Handle as ToMarkdownHandle,
16465
+ * Options as ToMarkdownExtension
16466
+ * } from 'mdast-util-to-markdown'
16106
16467
  */
16107
16468
 
16108
16469
  /**
@@ -16124,6 +16485,7 @@ const constructsWithoutStrikethrough = [
16124
16485
  'titleApostrophe'
16125
16486
  ];
16126
16487
 
16488
+ handleDelete.attention = attentionDelete;
16127
16489
  handleDelete.peek = peekDelete;
16128
16490
 
16129
16491
  /**
@@ -16150,26 +16512,30 @@ function gfmStrikethroughFromMarkdown() {
16150
16512
  */
16151
16513
  function gfmStrikethroughToMarkdown() {
16152
16514
  return {
16515
+ handlers: {delete: handleDelete},
16153
16516
  unsafe: [
16154
16517
  {
16155
16518
  character: '~',
16156
16519
  inConstruct: 'phrasing',
16157
16520
  notInConstruct: constructsWithoutStrikethrough
16158
16521
  }
16159
- ],
16160
- handlers: {delete: handleDelete}
16522
+ ]
16161
16523
  }
16162
16524
  }
16163
16525
 
16164
16526
  /**
16527
+ * Enter strikethrough.
16528
+ *
16165
16529
  * @this {CompileContext}
16166
16530
  * @type {FromMarkdownHandle}
16167
16531
  */
16168
16532
  function enterStrikethrough(token) {
16169
- this.enter({type: 'delete', children: []}, token);
16533
+ this.enter({type: 'delete', children: [], position: undefined}, token);
16170
16534
  }
16171
16535
 
16172
16536
  /**
16537
+ * Exit strikethrough.
16538
+ *
16173
16539
  * @this {CompileContext}
16174
16540
  * @type {FromMarkdownHandle}
16175
16541
  */
@@ -16178,24 +16544,43 @@ function exitStrikethrough(token) {
16178
16544
  }
16179
16545
 
16180
16546
  /**
16547
+ * Serialize a delete node.
16548
+ *
16181
16549
  * @type {ToMarkdownHandle}
16182
16550
  * @param {Delete} node
16551
+ * Node to serialize.
16183
16552
  */
16184
16553
  function handleDelete(node, _, state, info) {
16554
+ // To do: next major: empty this function, like emphasis and strong handlers,
16555
+ // this is no longer needed.
16185
16556
  const tracker = state.createTracker(info);
16557
+ const sequence = state.stack.includes('strikethrough') ? '~' : '~~';
16186
16558
  const exit = state.enter('strikethrough');
16187
- let value = tracker.move('~~');
16559
+ let value = tracker.move(sequence);
16188
16560
  value += state.containerPhrasing(node, {
16189
16561
  ...tracker.current(),
16190
16562
  before: value,
16191
16563
  after: '~'
16192
16564
  });
16193
- value += tracker.move('~~');
16565
+ value += tracker.move(sequence);
16194
16566
  exit();
16195
16567
  return value
16196
16568
  }
16197
16569
 
16198
- /** @type {ToMarkdownHandle} */
16570
+ /**
16571
+ * Serialize a delete node as attention.
16572
+ *
16573
+ * @type {Attention}
16574
+ */
16575
+ function attentionDelete() {
16576
+ return {construct: 'strikethrough', markers: ['~'], sizes: [2, 1]}
16577
+ }
16578
+
16579
+ /**
16580
+ * Peek the first character of a delete node.
16581
+ *
16582
+ * @type {ToMarkdownHandle}
16583
+ */
16199
16584
  function peekDelete() {
16200
16585
  return '~'
16201
16586
  }
@@ -16594,6 +16979,51 @@ function toAlignment(value) {
16594
16979
  : 0
16595
16980
  }
16596
16981
 
16982
+ /**
16983
+ * @typedef {import('mdast').Html} Html
16984
+ * @typedef {import('mdast').PhrasingContent} PhrasingContent
16985
+ */
16986
+
16987
+
16988
+ /**
16989
+ * Check if the given value is *phrasing content*.
16990
+ *
16991
+ * > 👉 **Note**: Excludes `html`, which can be both phrasing or flow.
16992
+ *
16993
+ * @param node
16994
+ * Thing to check, typically `Node`.
16995
+ * @returns
16996
+ * Whether `value` is phrasing content.
16997
+ */
16998
+
16999
+ const phrasing =
17000
+ /** @type {(node?: unknown) => node is Exclude<PhrasingContent, Html>} */
17001
+ (
17002
+ convert([
17003
+ 'break',
17004
+ 'delete',
17005
+ 'emphasis',
17006
+ // To do: next major: removed since footnotes were added to GFM.
17007
+ 'footnote',
17008
+ 'footnoteReference',
17009
+ 'image',
17010
+ 'imageReference',
17011
+ 'inlineCode',
17012
+ // Enabled by `mdast-util-math`:
17013
+ 'inlineMath',
17014
+ 'link',
17015
+ 'linkReference',
17016
+ // Enabled by `mdast-util-mdx`:
17017
+ 'mdxJsxTextElement',
17018
+ // Enabled by `mdast-util-mdx`:
17019
+ 'mdxTextExpression',
17020
+ 'strong',
17021
+ 'text',
17022
+ // Enabled by `mdast-util-directive`:
17023
+ 'textDirective'
17024
+ ])
17025
+ );
17026
+
16597
17027
  /**
16598
17028
  * @callback Handler
16599
17029
  * Handle a value, with a certain ID field set to a certain value.
@@ -16719,11 +17149,18 @@ function zwitch(key, options) {
16719
17149
  */
16720
17150
 
16721
17151
  /**
17152
+ * Serialize a blockquote node.
17153
+ *
16722
17154
  * @param {Blockquote} node
17155
+ * Node to serialize.
16723
17156
  * @param {Parents | undefined} _
17157
+ * Parent node.
16724
17158
  * @param {State} state
17159
+ * Info passed around.
16725
17160
  * @param {Info} info
17161
+ * Info on surrounding context.
16726
17162
  * @returns {string}
17163
+ * Serialized markdown.
16727
17164
  */
16728
17165
  function blockquote$1(node, _, state, info) {
16729
17166
  const exit = state.enter('blockquote');
@@ -16738,7 +17175,11 @@ function blockquote$1(node, _, state, info) {
16738
17175
  return value
16739
17176
  }
16740
17177
 
16741
- /** @type {Map} */
17178
+ /**
17179
+ * Indent lines w/ blockquote markers.
17180
+ *
17181
+ * @type {Map}
17182
+ */
16742
17183
  function map$1(line, _, blank) {
16743
17184
  return '>' + (blank ? '' : ' ') + line
16744
17185
  }
@@ -16748,9 +17189,14 @@ function map$1(line, _, blank) {
16748
17189
  */
16749
17190
 
16750
17191
  /**
17192
+ * Check if a pattern is in scope based on the current stack of constructs.
17193
+ *
16751
17194
  * @param {Array<ConstructName>} stack
17195
+ * Current stack of constructs.
16752
17196
  * @param {Unsafe} pattern
17197
+ * Pattern to check.
16753
17198
  * @returns {boolean}
17199
+ * Whether the pattern is in scope.
16754
17200
  */
16755
17201
  function patternInScope(stack, pattern) {
16756
17202
  return (
@@ -16760,10 +17206,16 @@ function patternInScope(stack, pattern) {
16760
17206
  }
16761
17207
 
16762
17208
  /**
17209
+ * Check if any of the constructs in the list are present in the stack.
17210
+ *
16763
17211
  * @param {Array<ConstructName>} stack
17212
+ * Current stack of constructs.
16764
17213
  * @param {Unsafe['inConstruct']} list
17214
+ * List of constructs to check for in the stack.
16765
17215
  * @param {boolean} none
17216
+ * Value to return if the list is empty or not provided.
16766
17217
  * @returns {boolean}
17218
+ * Whether any of the constructs in the list are present in the stack.
16767
17219
  */
16768
17220
  function listInScope(stack, list, none) {
16769
17221
  if (typeof list === 'string') {
@@ -16792,23 +17244,34 @@ function listInScope(stack, list, none) {
16792
17244
 
16793
17245
 
16794
17246
  /**
17247
+ * Serialize a break node.
17248
+ *
16795
17249
  * @param {Break} _
17250
+ * Node to serialize.
16796
17251
  * @param {Parents | undefined} _1
17252
+ * Parent node.
16797
17253
  * @param {State} state
17254
+ * Info passed around.
16798
17255
  * @param {Info} info
17256
+ * Info on surrounding context.
16799
17257
  * @returns {string}
17258
+ * Serialized markdown.
16800
17259
  */
16801
17260
  function hardBreak$1(_, _1, state, info) {
16802
17261
  let index = -1;
16803
17262
 
16804
17263
  while (++index < state.unsafe.length) {
16805
- // If we can’t put eols in this construct (setext headings, tables), use a
16806
- // space instead.
17264
+ const pattern = state.unsafe[index];
17265
+
17266
+ // If we can’t put unconditional eols in this construct (setext headings,
17267
+ // tables), use a space instead.
16807
17268
  if (
16808
- state.unsafe[index].character === '\n' &&
16809
- patternInScope(state.stack, state.unsafe[index])
17269
+ pattern.character === '\n' &&
17270
+ !pattern.before &&
17271
+ !pattern.after &&
17272
+ patternInScope(state.stack, pattern)
16810
17273
  ) {
16811
- return /[ \t]/.test(info.before) ? '' : ' '
17274
+ return /[\t ]/.test(info.before) ? '' : ' '
16812
17275
  }
16813
17276
  }
16814
17277
 
@@ -16858,20 +17321,25 @@ function longestStreak(value, substring) {
16858
17321
  */
16859
17322
 
16860
17323
  /**
17324
+ * Checks if a code block can be formatted as an indented code block.
17325
+ *
16861
17326
  * @param {Code} node
17327
+ * Node to check.
16862
17328
  * @param {State} state
17329
+ * Info passed around.
16863
17330
  * @returns {boolean}
17331
+ * Whether the code can be formatted as an indented code block.
16864
17332
  */
16865
17333
  function formatCodeAsIndented(node, state) {
16866
17334
  return Boolean(
16867
17335
  state.options.fences === false &&
16868
- node.value &&
16869
- // If there’s no info…
16870
- !node.lang &&
16871
- // And there’s a non-whitespace character…
16872
- /[^ \r\n]/.test(node.value) &&
16873
- // And the value doesn’t start or end in a blank…
16874
- !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value)
17336
+ node.value &&
17337
+ // If there’s no info…
17338
+ !node.lang &&
17339
+ // And there’s a non-whitespace character…
17340
+ /[^\n\r ]/.test(node.value) &&
17341
+ // And the value doesn’t start or end in a blank…
17342
+ !/^[\t ]*(?:[\n\r]|$)|(?:^|[\n\r])[\t ]*$/.test(node.value)
16875
17343
  )
16876
17344
  }
16877
17345
 
@@ -16880,8 +17348,12 @@ function formatCodeAsIndented(node, state) {
16880
17348
  */
16881
17349
 
16882
17350
  /**
17351
+ * Checks the preferred fence option.
17352
+ *
16883
17353
  * @param {State} state
17354
+ * Info passed around.
16884
17355
  * @returns {Exclude<Options['fence'], null | undefined>}
17356
+ * Preferred fence marker.
16885
17357
  */
16886
17358
  function checkFence(state) {
16887
17359
  const marker = state.options.fence || '`';
@@ -16904,16 +17376,22 @@ function checkFence(state) {
16904
17376
 
16905
17377
 
16906
17378
  /**
17379
+ * Serialize a code node.
17380
+ *
16907
17381
  * @param {Code} node
17382
+ * Node to serialize.
16908
17383
  * @param {Parents | undefined} _
17384
+ * Parent node.
16909
17385
  * @param {State} state
17386
+ * Info passed around.
16910
17387
  * @param {Info} info
17388
+ * Info on surrounding context.
16911
17389
  * @returns {string}
17390
+ * Serialized markdown.
16912
17391
  */
16913
17392
  function code$2(node, _, state, info) {
16914
17393
  const marker = checkFence(state);
16915
17394
  const raw = node.value || '';
16916
- const suffix = marker === '`' ? 'GraveAccent' : 'Tilde';
16917
17395
 
16918
17396
  if (formatCodeAsIndented(node, state)) {
16919
17397
  const exit = state.enter('codeIndented');
@@ -16925,6 +17403,7 @@ function code$2(node, _, state, info) {
16925
17403
  const tracker = state.createTracker(info);
16926
17404
  const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3));
16927
17405
  const exit = state.enter('codeFenced');
17406
+ const suffix = marker === '`' ? 'GraveAccent' : 'Tilde';
16928
17407
  let value = tracker.move(sequence);
16929
17408
 
16930
17409
  if (node.lang) {
@@ -16965,7 +17444,11 @@ function code$2(node, _, state, info) {
16965
17444
  return value
16966
17445
  }
16967
17446
 
16968
- /** @type {Map} */
17447
+ /**
17448
+ * Indent lines w/ code indent.
17449
+ *
17450
+ * @type {Map}
17451
+ */
16969
17452
  function map(line, _, blank) {
16970
17453
  return (blank ? '' : ' ') + line
16971
17454
  }
@@ -16975,8 +17458,12 @@ function map(line, _, blank) {
16975
17458
  */
16976
17459
 
16977
17460
  /**
17461
+ * Checks the preferred quote option.
17462
+ *
16978
17463
  * @param {State} state
17464
+ * Info passed around.
16979
17465
  * @returns {Exclude<Options['quote'], null | undefined>}
17466
+ * Preferred quote.
16980
17467
  */
16981
17468
  function checkQuote(state) {
16982
17469
  const marker = state.options.quote || '"';
@@ -16999,11 +17486,18 @@ function checkQuote(state) {
16999
17486
 
17000
17487
 
17001
17488
  /**
17489
+ * Serialize a definition node.
17490
+ *
17002
17491
  * @param {Definition} node
17492
+ * Node to serialize.
17003
17493
  * @param {Parents | undefined} _
17494
+ * Parent node.
17004
17495
  * @param {State} state
17496
+ * Info passed around.
17005
17497
  * @param {Info} info
17498
+ * Info on surrounding context.
17006
17499
  * @returns {string}
17500
+ * Serialized markdown.
17007
17501
  */
17008
17502
  function definition(node, _, state, info) {
17009
17503
  const quote = checkQuote(state);
@@ -17073,8 +17567,12 @@ function definition(node, _, state, info) {
17073
17567
  */
17074
17568
 
17075
17569
  /**
17570
+ * Checks the preferred emphasis option.
17571
+ *
17076
17572
  * @param {State} state
17573
+ * Info passed around.
17077
17574
  * @returns {Exclude<Options['emphasis'], null | undefined>}
17575
+ * Preferred emphasis marker.
17078
17576
  */
17079
17577
  function checkEmphasis(state) {
17080
17578
  const marker = state.options.emphasis || '*';
@@ -17091,166 +17589,84 @@ function checkEmphasis(state) {
17091
17589
  }
17092
17590
 
17093
17591
  /**
17094
- * Encode a code point as a character reference.
17095
- *
17096
- * @param {number} code
17097
- * Code point to encode.
17098
- * @returns {string}
17099
- * Encoded character reference.
17592
+ * @import {AttentionInfo, Info, State} from 'mdast-util-to-markdown'
17593
+ * @import {Emphasis, Parents} from 'mdast'
17100
17594
  */
17101
- function encodeCharacterReference(code) {
17102
- return '&#x' + code.toString(16).toUpperCase() + ';'
17103
- }
17104
17595
 
17105
- /**
17106
- * @import {EncodeSides} from '../types.js'
17107
- */
17108
17596
 
17597
+ emphasis$1.attention = attention$1;
17598
+ emphasis$1.peek = peek$1;
17109
17599
 
17110
17600
  /**
17111
- * Check whether to encode (as a character reference) the characters
17112
- * surrounding an attention run.
17113
- *
17114
- * Which characters are around an attention run influence whether it works or
17115
- * not.
17601
+ * Serialize an emphasis node.
17116
17602
  *
17117
- * See <https://github.com/orgs/syntax-tree/discussions/60> for more info.
17118
- * See this markdown in a particular renderer to see what works:
17603
+ * Attention is properly handled by `containerPhrasing`.
17119
17604
  *
17120
- * ```markdown
17121
- * | | A (letter inside) | B (punctuation inside) | C (whitespace inside) | D (nothing inside) |
17122
- * | ----------------------- | ----------------- | ---------------------- | --------------------- | ------------------ |
17123
- * | 1 (letter outside) | x*y*z | x*.*z | x* *z | x**z |
17124
- * | 2 (punctuation outside) | .*y*. | .*.*. | .* *. | .**. |
17125
- * | 3 (whitespace outside) | x *y* z | x *.* z | x * * z | x ** z |
17126
- * | 4 (nothing outside) | *x* | *.* | * * | ** |
17127
- * ```
17128
- *
17129
- * @param {number} outside
17130
- * Code point on the outer side of the run.
17131
- * @param {number} inside
17132
- * Code point on the inner side of the run.
17133
- * @param {'*' | '_'} marker
17134
- * Marker of the run.
17135
- * Underscores are handled more strictly (they form less often) than
17136
- * asterisks.
17137
- * @returns {EncodeSides}
17138
- * Whether to encode characters.
17139
- */
17140
- // Important: punctuation must never be encoded.
17141
- // Punctuation is solely used by markdown constructs.
17142
- // And by encoding itself.
17143
- // Encoding them will break constructs or double encode things.
17144
- function encodeInfo(outside, inside, marker) {
17145
- const outsideKind = classifyCharacter(outside);
17146
- const insideKind = classifyCharacter(inside);
17147
-
17148
- // Letter outside:
17149
- if (outsideKind === undefined) {
17150
- return insideKind === undefined
17151
- ? // Letter inside:
17152
- // we have to encode *both* letters for `_` as it is looser.
17153
- // it already forms for `*` (and GFMs `~`).
17154
- marker === '_'
17155
- ? {inside: true, outside: true}
17156
- : {inside: false, outside: false}
17157
- : insideKind === 1
17158
- ? // Whitespace inside: encode both (letter, whitespace).
17159
- {inside: true, outside: true}
17160
- : // Punctuation inside: encode outer (letter)
17161
- {inside: false, outside: true}
17162
- }
17163
-
17164
- // Whitespace outside:
17165
- if (outsideKind === 1) {
17166
- return insideKind === undefined
17167
- ? // Letter inside: already forms.
17168
- {inside: false, outside: false}
17169
- : insideKind === 1
17170
- ? // Whitespace inside: encode both (whitespace).
17171
- {inside: true, outside: true}
17172
- : // Punctuation inside: already forms.
17173
- {inside: false, outside: false}
17174
- }
17175
-
17176
- // Punctuation outside:
17177
- return insideKind === undefined
17178
- ? // Letter inside: already forms.
17179
- {inside: false, outside: false}
17180
- : insideKind === 1
17181
- ? // Whitespace inside: encode inner (whitespace).
17182
- {inside: true, outside: false}
17183
- : // Punctuation inside: already forms.
17184
- {inside: false, outside: false}
17185
- }
17186
-
17187
- /**
17188
- * @import {Info, State} from 'mdast-util-to-markdown'
17189
- * @import {Emphasis, Parents} from 'mdast'
17190
- */
17191
-
17192
-
17193
- emphasis$1.peek = emphasisPeek;
17194
-
17195
- /**
17196
17605
  * @param {Emphasis} node
17606
+ * Node to serialize.
17197
17607
  * @param {Parents | undefined} _
17608
+ * Parent node.
17198
17609
  * @param {State} state
17610
+ * Info passed around.
17199
17611
  * @param {Info} info
17612
+ * Info on surrounding context.
17200
17613
  * @returns {string}
17614
+ * Serialized markdown.
17201
17615
  */
17202
17616
  function emphasis$1(node, _, state, info) {
17203
- const marker = checkEmphasis(state);
17204
- const exit = state.enter('emphasis');
17205
- const tracker = state.createTracker(info);
17206
- const before = tracker.move(marker);
17207
-
17208
- let between = tracker.move(
17209
- state.containerPhrasing(node, {
17210
- after: marker,
17211
- before,
17212
- ...tracker.current()
17213
- })
17214
- );
17215
- const betweenHead = between.charCodeAt(0);
17216
- const open = encodeInfo(
17217
- info.before.charCodeAt(info.before.length - 1),
17218
- betweenHead,
17219
- marker
17220
- );
17221
-
17222
- if (open.inside) {
17223
- between = encodeCharacterReference(betweenHead) + between.slice(1);
17224
- }
17225
-
17226
- const betweenTail = between.charCodeAt(between.length - 1);
17227
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
17228
-
17229
- if (close.inside) {
17230
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
17231
- }
17232
-
17233
- const after = tracker.move(marker);
17234
-
17617
+ const exit = state.enter('phrasing');
17618
+ const value = state.containerPhrasing({type: 'root', children: [node]}, info);
17235
17619
  exit();
17620
+ return value
17621
+ }
17236
17622
 
17237
- state.attentionEncodeSurroundingInfo = {
17238
- after: close.outside,
17239
- before: open.outside
17240
- };
17241
- return before + between + after
17623
+ /**
17624
+ * Serialize an emphasis node as attention.
17625
+ *
17626
+ * @param {Emphasis} _
17627
+ * Node to serialize.
17628
+ * @param {State} state
17629
+ * Info passed around.
17630
+ * @returns {AttentionInfo}
17631
+ * Info on how to serialize the node.
17632
+ */
17633
+ function attention$1(_, state) {
17634
+ const marker = checkEmphasis(state);
17635
+ return {
17636
+ construct: 'emphasis',
17637
+ markers: marker === '*' ? ['*', '_'] : ['_', '*'],
17638
+ sizes: [1]
17639
+ }
17242
17640
  }
17243
17641
 
17244
17642
  /**
17643
+ * Peek at this node.
17644
+ *
17245
17645
  * @param {Emphasis} _
17646
+ * Node to serialize.
17246
17647
  * @param {Parents | undefined} _1
17648
+ * Parent node.
17247
17649
  * @param {State} state
17650
+ * Info passed around.
17248
17651
  * @returns {string}
17652
+ * Start of the serialized markdown.
17249
17653
  */
17250
- function emphasisPeek(_, _1, state) {
17654
+ function peek$1(_, _1, state) {
17251
17655
  return state.options.emphasis || '*'
17252
17656
  }
17253
17657
 
17658
+ /**
17659
+ * Encode a code point as a character reference.
17660
+ *
17661
+ * @param {number} code
17662
+ * Code point to encode.
17663
+ * @returns {string}
17664
+ * Encoded character reference.
17665
+ */
17666
+ function encodeCharacterReference(code) {
17667
+ return '&#x' + code.toString(16).toUpperCase() + ';'
17668
+ }
17669
+
17254
17670
  /**
17255
17671
  * @import {Node as UnistNode, Parent as UnistParent} from 'unist'
17256
17672
  * @import {VisitorResult} from 'unist-util-visit-parents'
@@ -17347,9 +17763,14 @@ function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
17347
17763
 
17348
17764
 
17349
17765
  /**
17766
+ * Checks if a heading can be formatted as a setext heading.
17767
+ *
17350
17768
  * @param {Heading} node
17769
+ * Node to check.
17351
17770
  * @param {State} state
17771
+ * Info passed around.
17352
17772
  * @returns {boolean}
17773
+ * Whether the heading can be formatted as a setext heading.
17353
17774
  */
17354
17775
  function formatHeadingAsSetext(node, state) {
17355
17776
  let literalWithBreak = false;
@@ -17368,8 +17789,8 @@ function formatHeadingAsSetext(node, state) {
17368
17789
 
17369
17790
  return Boolean(
17370
17791
  (!node.depth || node.depth < 3) &&
17371
- toString$1(node) &&
17372
- (state.options.setext || literalWithBreak)
17792
+ toString$1(node) &&
17793
+ (state.options.setext || literalWithBreak)
17373
17794
  )
17374
17795
  }
17375
17796
 
@@ -17380,11 +17801,18 @@ function formatHeadingAsSetext(node, state) {
17380
17801
 
17381
17802
 
17382
17803
  /**
17804
+ * Serialize a heading node.
17805
+ *
17383
17806
  * @param {Heading} node
17807
+ * Node to serialize.
17384
17808
  * @param {Parents | undefined} _
17809
+ * Parent node.
17385
17810
  * @param {State} state
17811
+ * Info passed around.
17386
17812
  * @param {Info} info
17813
+ * Info on surrounding context.
17387
17814
  * @returns {string}
17815
+ * Serialized markdown.
17388
17816
  */
17389
17817
  function heading$1(node, _, state, info) {
17390
17818
  const rank = Math.max(Math.min(6, node.depth || 1), 1);
@@ -17430,9 +17858,11 @@ function heading$1(node, _, state, info) {
17430
17858
  ...tracker.current()
17431
17859
  });
17432
17860
 
17433
- if (/^[\t ]/.test(value)) {
17861
+ const head = value.charCodeAt(0);
17862
+
17863
+ if (head === 9 /* `\t` */ || head === 32 /* ` ` */) {
17434
17864
  // To do: what effect has the character reference on tracking?
17435
- value = encodeCharacterReference(value.charCodeAt(0)) + value.slice(1);
17865
+ value = encodeCharacterReference(head) + value.slice(1);
17436
17866
  }
17437
17867
 
17438
17868
  value = value ? sequence + ' ' + value : sequence;
@@ -17454,15 +17884,22 @@ function heading$1(node, _, state, info) {
17454
17884
  html$5.peek = htmlPeek;
17455
17885
 
17456
17886
  /**
17887
+ * Serialize an HTML node.
17888
+ *
17457
17889
  * @param {Html} node
17890
+ * Node to serialize.
17458
17891
  * @returns {string}
17892
+ * Serialized markdown.
17459
17893
  */
17460
17894
  function html$5(node) {
17461
17895
  return node.value || ''
17462
17896
  }
17463
17897
 
17464
17898
  /**
17899
+ * Peek at this node.
17900
+ *
17465
17901
  * @returns {string}
17902
+ * Start of the serialized markdown.
17466
17903
  */
17467
17904
  function htmlPeek() {
17468
17905
  return '<'
@@ -17477,11 +17914,18 @@ function htmlPeek() {
17477
17914
  image$1.peek = imagePeek;
17478
17915
 
17479
17916
  /**
17917
+ * Serialize an image node.
17918
+ *
17480
17919
  * @param {Image} node
17920
+ * Node to serialize.
17481
17921
  * @param {Parents | undefined} _
17922
+ * Parent node.
17482
17923
  * @param {State} state
17924
+ * Info passed around.
17483
17925
  * @param {Info} info
17926
+ * Info on surrounding context.
17484
17927
  * @returns {string}
17928
+ * Serialized markdown.
17485
17929
  */
17486
17930
  function image$1(node, _, state, info) {
17487
17931
  const quote = checkQuote(state);
@@ -17544,7 +17988,10 @@ function image$1(node, _, state, info) {
17544
17988
  }
17545
17989
 
17546
17990
  /**
17991
+ * Peek at this node.
17992
+ *
17547
17993
  * @returns {string}
17994
+ * Start of the serialized markdown.
17548
17995
  */
17549
17996
  function imagePeek() {
17550
17997
  return '!'
@@ -17558,11 +18005,18 @@ function imagePeek() {
17558
18005
  imageReference$1.peek = imageReferencePeek;
17559
18006
 
17560
18007
  /**
18008
+ * Serialize an image reference node.
18009
+ *
17561
18010
  * @param {ImageReference} node
18011
+ * Node to serialize.
17562
18012
  * @param {Parents | undefined} _
18013
+ * Parent node.
17563
18014
  * @param {State} state
18015
+ * Info passed around.
17564
18016
  * @param {Info} info
18017
+ * Info on surrounding context.
17565
18018
  * @returns {string}
18019
+ * Serialized markdown.
17566
18020
  */
17567
18021
  function imageReference$1(node, _, state, info) {
17568
18022
  const type = node.referenceType;
@@ -17578,9 +18032,14 @@ function imageReference$1(node, _, state, info) {
17578
18032
  value += tracker.move(alt + '][');
17579
18033
 
17580
18034
  subexit();
17581
- // Hide the fact that we’re in phrasing, because escapes don’t work.
18035
+ // Hide that we’re in phrasing as things like attention or code cannot form
18036
+ // in references.
18037
+ // Character escapes and references *do* work.
18038
+ // It is important to know about other constructs, such as table cells.
17582
18039
  const stack = state.stack;
17583
- state.stack = [];
18040
+ state.stack = stack.filter(function (d) {
18041
+ return d !== 'phrasing'
18042
+ });
17584
18043
  subexit = state.enter('reference');
17585
18044
  // Note: for proper tracking, we should reset the output positions when we end
17586
18045
  // up making a `shortcut` reference, because then there is no brace output.
@@ -17608,7 +18067,10 @@ function imageReference$1(node, _, state, info) {
17608
18067
  }
17609
18068
 
17610
18069
  /**
18070
+ * Peek at this node.
18071
+ *
17611
18072
  * @returns {string}
18073
+ * Start of the serialized markdown.
17612
18074
  */
17613
18075
  function imageReferencePeek() {
17614
18076
  return '!'
@@ -17622,10 +18084,16 @@ function imageReferencePeek() {
17622
18084
  inlineCode$1.peek = inlineCodePeek;
17623
18085
 
17624
18086
  /**
18087
+ * Serialize an inline code node.
18088
+ *
17625
18089
  * @param {InlineCode} node
18090
+ * Node to serialize.
17626
18091
  * @param {Parents | undefined} _
18092
+ * Parent node.
17627
18093
  * @param {State} state
18094
+ * Info passed around.
17628
18095
  * @returns {string}
18096
+ * Serialized markdown.
17629
18097
  */
17630
18098
  function inlineCode$1(node, _, state) {
17631
18099
  let value = node.value || '';
@@ -17642,8 +18110,8 @@ function inlineCode$1(node, _, state) {
17642
18110
  // If this is not just spaces or eols (tabs don’t count), and either the
17643
18111
  // first or last character are a space, eol, or tick, then pad with spaces.
17644
18112
  if (
17645
- /[^ \r\n]/.test(value) &&
17646
- ((/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value)) || /^`|`$/.test(value))
18113
+ /[^\n\r ]/.test(value) &&
18114
+ ((/^[\n\r ]/.test(value) && /[\n\r ]$/.test(value)) || /^`|`$/.test(value))
17647
18115
  ) {
17648
18116
  value = ' ' + value + ' ';
17649
18117
  }
@@ -17658,14 +18126,15 @@ function inlineCode$1(node, _, state) {
17658
18126
  while (++index < state.unsafe.length) {
17659
18127
  const pattern = state.unsafe[index];
17660
18128
  const expression = state.compilePattern(pattern);
17661
- /** @type {RegExpExecArray | null} */
17662
- let match;
17663
18129
 
17664
18130
  // Only look for `atBreak`s.
17665
18131
  // Btw: note that `atBreak` patterns will always start the regex at LF or
17666
18132
  // CR.
17667
18133
  if (!pattern.atBreak) continue
17668
18134
 
18135
+ /** @type {RegExpExecArray | null} */
18136
+ let match;
18137
+
17669
18138
  while ((match = expression.exec(value))) {
17670
18139
  let position = match.index;
17671
18140
 
@@ -17685,7 +18154,10 @@ function inlineCode$1(node, _, state) {
17685
18154
  }
17686
18155
 
17687
18156
  /**
18157
+ * Peek at this node.
18158
+ *
17688
18159
  * @returns {string}
18160
+ * Start of the serialized markdown.
17689
18161
  */
17690
18162
  function inlineCodePeek() {
17691
18163
  return '`'
@@ -17698,30 +18170,35 @@ function inlineCodePeek() {
17698
18170
 
17699
18171
 
17700
18172
  /**
18173
+ * Checks if a link can be formatted as an autolink.
18174
+ *
17701
18175
  * @param {Link} node
18176
+ * Node to check.
17702
18177
  * @param {State} state
18178
+ * Info passed around.
17703
18179
  * @returns {boolean}
18180
+ * Whether the link can be formatted as an autolink.
17704
18181
  */
17705
18182
  function formatLinkAsAutolink(node, state) {
17706
18183
  const raw = toString$1(node);
17707
18184
 
17708
18185
  return Boolean(
17709
18186
  !state.options.resourceLink &&
17710
- // If there’s a url…
17711
- node.url &&
17712
- // And there’s a no title…
17713
- !node.title &&
17714
- // And the content of `node` is a single text node…
17715
- node.children &&
17716
- node.children.length === 1 &&
17717
- node.children[0].type === 'text' &&
17718
- // And if the url is the same as the content…
17719
- (raw === node.url || 'mailto:' + raw === node.url) &&
17720
- // And that starts w/ a protocol…
17721
- /^[a-z][a-z+.-]+:/i.test(node.url) &&
17722
- // And that doesn’t contain ASCII control codes (character escapes and
17723
- // references don’t work), space, or angle brackets…
17724
- !/[\0- <>\u007F]/.test(node.url)
18187
+ // If there’s a url…
18188
+ node.url &&
18189
+ // And there’s no title…
18190
+ !node.title &&
18191
+ // And the content of `node` is a single text node…
18192
+ node.children &&
18193
+ node.children.length === 1 &&
18194
+ node.children[0].type === 'text' &&
18195
+ // And if the url is the same as the content…
18196
+ (raw === node.url || 'mailto:' + raw === node.url) &&
18197
+ // And that starts w/ a protocol…
18198
+ /^[a-z][+\-.a-z]+:/i.test(node.url) &&
18199
+ // And that doesn’t contain ASCII control codes (character escapes and
18200
+ // references don’t work), space, or angle brackets…
18201
+ !/[\0- <>\u007F]/.test(node.url)
17725
18202
  )
17726
18203
  }
17727
18204
 
@@ -17735,26 +18212,35 @@ function formatLinkAsAutolink(node, state) {
17735
18212
  link$1.peek = linkPeek;
17736
18213
 
17737
18214
  /**
18215
+ * Serialize a link node.
18216
+ *
17738
18217
  * @param {Link} node
18218
+ * Node to serialize.
17739
18219
  * @param {Parents | undefined} _
18220
+ * Parent node.
17740
18221
  * @param {State} state
18222
+ * Info passed around.
17741
18223
  * @param {Info} info
18224
+ * Info on surrounding context.
17742
18225
  * @returns {string}
18226
+ * Serialized markdown.
17743
18227
  */
17744
18228
  function link$1(node, _, state, info) {
17745
18229
  const quote = checkQuote(state);
17746
18230
  const suffix = quote === '"' ? 'Quote' : 'Apostrophe';
17747
18231
  const tracker = state.createTracker(info);
17748
- /** @type {Exit} */
17749
- let exit;
17750
- /** @type {Exit} */
17751
- let subexit;
17752
18232
 
17753
18233
  if (formatLinkAsAutolink(node, state)) {
17754
- // Hide the fact that we’re in phrasing, because escapes don’t work.
18234
+ // Hide that we’re in phrasing as things like attention or code cannot form
18235
+ // in autolinks.
18236
+ // Character escapes also don’t work (nor character references),
18237
+ // but that is a different matter, which `safe.js` handles for `autolink`.
18238
+ // It is important to know about other constructs, such as table cells.
17755
18239
  const stack = state.stack;
17756
- state.stack = [];
17757
- exit = state.enter('autolink');
18240
+ state.stack = stack.filter(function (d) {
18241
+ return d !== 'phrasing'
18242
+ });
18243
+ const exit = state.enter('autolink');
17758
18244
  let value = tracker.move('<');
17759
18245
  value += tracker.move(
17760
18246
  state.containerPhrasing(node, {
@@ -17769,8 +18255,8 @@ function link$1(node, _, state, info) {
17769
18255
  return value
17770
18256
  }
17771
18257
 
17772
- exit = state.enter('link');
17773
- subexit = state.enter('label');
18258
+ const exit = state.enter('link');
18259
+ let subexit = state.enter('label');
17774
18260
  let value = tracker.move('[');
17775
18261
  value += tracker.move(
17776
18262
  state.containerPhrasing(node, {
@@ -17829,10 +18315,16 @@ function link$1(node, _, state, info) {
17829
18315
  }
17830
18316
 
17831
18317
  /**
18318
+ * Peek at this node.
18319
+ *
17832
18320
  * @param {Link} node
18321
+ * Node to peek at.
17833
18322
  * @param {Parents | undefined} _
18323
+ * Parent node.
17834
18324
  * @param {State} state
18325
+ * Info passed around.
17835
18326
  * @returns {string}
18327
+ * Start of the serialized markdown.
17836
18328
  */
17837
18329
  function linkPeek(node, _, state) {
17838
18330
  return formatLinkAsAutolink(node, state) ? '<' : '['
@@ -17846,11 +18338,18 @@ function linkPeek(node, _, state) {
17846
18338
  linkReference$1.peek = linkReferencePeek;
17847
18339
 
17848
18340
  /**
18341
+ * Serialize a link reference node.
18342
+ *
17849
18343
  * @param {LinkReference} node
18344
+ * Node to serialize.
17850
18345
  * @param {Parents | undefined} _
18346
+ * Parent node.
17851
18347
  * @param {State} state
18348
+ * Info passed around.
17852
18349
  * @param {Info} info
18350
+ * Info on surrounding context.
17853
18351
  * @returns {string}
18352
+ * Serialized markdown.
17854
18353
  */
17855
18354
  function linkReference$1(node, _, state, info) {
17856
18355
  const type = node.referenceType;
@@ -17866,9 +18365,14 @@ function linkReference$1(node, _, state, info) {
17866
18365
  value += tracker.move(text + '][');
17867
18366
 
17868
18367
  subexit();
17869
- // Hide the fact that we’re in phrasing, because escapes don’t work.
18368
+ // Hide that we’re in phrasing as things like attention or code cannot form
18369
+ // in references.
18370
+ // Character escapes and references *do* work.
18371
+ // It is important to know about other constructs, such as table cells.
17870
18372
  const stack = state.stack;
17871
- state.stack = [];
18373
+ state.stack = stack.filter(function (d) {
18374
+ return d !== 'phrasing'
18375
+ });
17872
18376
  subexit = state.enter('reference');
17873
18377
  // Note: for proper tracking, we should reset the output positions when we end
17874
18378
  // up making a `shortcut` reference, because then there is no brace output.
@@ -17896,7 +18400,10 @@ function linkReference$1(node, _, state, info) {
17896
18400
  }
17897
18401
 
17898
18402
  /**
18403
+ * Peek at this node.
18404
+ *
17899
18405
  * @returns {string}
18406
+ * Start of the serialized markdown.
17900
18407
  */
17901
18408
  function linkReferencePeek() {
17902
18409
  return '['
@@ -17907,8 +18414,12 @@ function linkReferencePeek() {
17907
18414
  */
17908
18415
 
17909
18416
  /**
18417
+ * Checks the preferred list bullet option.
18418
+ *
17910
18419
  * @param {State} state
18420
+ * Info passed around.
17911
18421
  * @returns {Exclude<Options['bullet'], null | undefined>}
18422
+ * Preferred list bullet.
17912
18423
  */
17913
18424
  function checkBullet(state) {
17914
18425
  const marker = state.options.bullet || '*';
@@ -17930,8 +18441,12 @@ function checkBullet(state) {
17930
18441
 
17931
18442
 
17932
18443
  /**
18444
+ * Checks the preferred alternate list bullet option.
18445
+ *
17933
18446
  * @param {State} state
18447
+ * Info passed around.
17934
18448
  * @returns {Exclude<Options['bullet'], null | undefined>}
18449
+ * Preferred alternate list bullet.
17935
18450
  */
17936
18451
  function checkBulletOther(state) {
17937
18452
  const bullet = checkBullet(state);
@@ -17967,8 +18482,12 @@ function checkBulletOther(state) {
17967
18482
  */
17968
18483
 
17969
18484
  /**
18485
+ * Checks the preferred ordered list bullet option.
18486
+ *
17970
18487
  * @param {State} state
18488
+ * Info passed around.
17971
18489
  * @returns {Exclude<Options['bulletOrdered'], null | undefined>}
18490
+ * Preferred ordered list bullet.
17972
18491
  */
17973
18492
  function checkBulletOrdered(state) {
17974
18493
  const marker = state.options.bulletOrdered || '.';
@@ -17989,8 +18508,12 @@ function checkBulletOrdered(state) {
17989
18508
  */
17990
18509
 
17991
18510
  /**
18511
+ * Checks the preferred rule option.
18512
+ *
17992
18513
  * @param {State} state
18514
+ * Info passed around.
17993
18515
  * @returns {Exclude<Options['rule'], null | undefined>}
18516
+ * Preferred rule marker.
17994
18517
  */
17995
18518
  function checkRule(state) {
17996
18519
  const marker = state.options.rule || '*';
@@ -18013,11 +18536,18 @@ function checkRule(state) {
18013
18536
 
18014
18537
 
18015
18538
  /**
18539
+ * Serialize a list node.
18540
+ *
18016
18541
  * @param {List} node
18542
+ * Node to serialize.
18017
18543
  * @param {Parents | undefined} parent
18544
+ * Parent node.
18018
18545
  * @param {State} state
18546
+ * Info passed around.
18019
18547
  * @param {Info} info
18548
+ * Info on surrounding context.
18020
18549
  * @returns {string}
18550
+ * Serialized markdown.
18021
18551
  */
18022
18552
  function list$1(node, parent, state, info) {
18023
18553
  const exit = state.enter('list');
@@ -18108,8 +18638,12 @@ function list$1(node, parent, state, info) {
18108
18638
  */
18109
18639
 
18110
18640
  /**
18641
+ * Checks the preferred list item indent option.
18642
+ *
18111
18643
  * @param {State} state
18644
+ * Info passed around.
18112
18645
  * @returns {Exclude<Options['listItemIndent'], null | undefined>}
18646
+ * Preferred list item indent.
18113
18647
  */
18114
18648
  function checkListItemIndent(state) {
18115
18649
  const style = state.options.listItemIndent || 'one';
@@ -18132,11 +18666,18 @@ function checkListItemIndent(state) {
18132
18666
 
18133
18667
 
18134
18668
  /**
18669
+ * Serialize a list item node.
18670
+ *
18135
18671
  * @param {ListItem} node
18672
+ * Node to serialize.
18136
18673
  * @param {Parents | undefined} parent
18674
+ * Parent node.
18137
18675
  * @param {State} state
18676
+ * Info passed around.
18138
18677
  * @param {Info} info
18678
+ * Info on surrounding context.
18139
18679
  * @returns {string}
18680
+ * Serialized markdown.
18140
18681
  */
18141
18682
  function listItem$1(node, parent, state, info) {
18142
18683
  const listItemIndent = checkListItemIndent(state);
@@ -18176,7 +18717,11 @@ function listItem$1(node, parent, state, info) {
18176
18717
 
18177
18718
  return value
18178
18719
 
18179
- /** @type {Map} */
18720
+ /**
18721
+ * Indent lines of the list item.
18722
+ *
18723
+ * @type {Map}
18724
+ */
18180
18725
  function map(line, index, blank) {
18181
18726
  if (index) {
18182
18727
  return (blank ? '' : ' '.repeat(size)) + line
@@ -18192,11 +18737,18 @@ function listItem$1(node, parent, state, info) {
18192
18737
  */
18193
18738
 
18194
18739
  /**
18740
+ * Serialize a paragraph node.
18741
+ *
18195
18742
  * @param {Paragraph} node
18743
+ * Node to serialize.
18196
18744
  * @param {Parents | undefined} _
18745
+ * Parent node.
18197
18746
  * @param {State} state
18747
+ * Info passed around.
18198
18748
  * @param {Info} info
18749
+ * Info on surrounding context.
18199
18750
  * @returns {string}
18751
+ * Serialized markdown.
18200
18752
  */
18201
18753
  function paragraph$1(node, _, state, info) {
18202
18754
  const exit = state.enter('paragraph');
@@ -18207,51 +18759,6 @@ function paragraph$1(node, _, state, info) {
18207
18759
  return value
18208
18760
  }
18209
18761
 
18210
- /**
18211
- * @typedef {import('mdast').Html} Html
18212
- * @typedef {import('mdast').PhrasingContent} PhrasingContent
18213
- */
18214
-
18215
-
18216
- /**
18217
- * Check if the given value is *phrasing content*.
18218
- *
18219
- * > 👉 **Note**: Excludes `html`, which can be both phrasing or flow.
18220
- *
18221
- * @param node
18222
- * Thing to check, typically `Node`.
18223
- * @returns
18224
- * Whether `value` is phrasing content.
18225
- */
18226
-
18227
- const phrasing =
18228
- /** @type {(node?: unknown) => node is Exclude<PhrasingContent, Html>} */
18229
- (
18230
- convert([
18231
- 'break',
18232
- 'delete',
18233
- 'emphasis',
18234
- // To do: next major: removed since footnotes were added to GFM.
18235
- 'footnote',
18236
- 'footnoteReference',
18237
- 'image',
18238
- 'imageReference',
18239
- 'inlineCode',
18240
- // Enabled by `mdast-util-math`:
18241
- 'inlineMath',
18242
- 'link',
18243
- 'linkReference',
18244
- // Enabled by `mdast-util-mdx`:
18245
- 'mdxJsxTextElement',
18246
- // Enabled by `mdast-util-mdx`:
18247
- 'mdxTextExpression',
18248
- 'strong',
18249
- 'text',
18250
- // Enabled by `mdast-util-directive`:
18251
- 'textDirective'
18252
- ])
18253
- );
18254
-
18255
18762
  /**
18256
18763
  * @import {Info, State} from 'mdast-util-to-markdown'
18257
18764
  * @import {Parents, Root} from 'mdast'
@@ -18259,11 +18766,18 @@ const phrasing =
18259
18766
 
18260
18767
 
18261
18768
  /**
18769
+ * Serialize a root node.
18770
+ *
18262
18771
  * @param {Root} node
18772
+ * Node to serialize.
18263
18773
  * @param {Parents | undefined} _
18774
+ * Parent node.
18264
18775
  * @param {State} state
18776
+ * Info passed around.
18265
18777
  * @param {Info} info
18778
+ * Info on surrounding context.
18266
18779
  * @returns {string}
18780
+ * Serialized markdown.
18267
18781
  */
18268
18782
  function root$4(node, _, state, info) {
18269
18783
  // Note: `html` nodes are ambiguous.
@@ -18271,8 +18785,12 @@ function root$4(node, _, state, info) {
18271
18785
  return phrasing(d)
18272
18786
  });
18273
18787
 
18274
- const container = hasPhrasing ? state.containerPhrasing : state.containerFlow;
18275
- return container.call(state, node, info)
18788
+ if (!hasPhrasing) return state.containerFlow(node, info)
18789
+
18790
+ const exit = state.enter('phrasing');
18791
+ const value = state.containerPhrasing(node, info);
18792
+ exit();
18793
+ return value
18276
18794
  }
18277
18795
 
18278
18796
  /**
@@ -18280,8 +18798,12 @@ function root$4(node, _, state, info) {
18280
18798
  */
18281
18799
 
18282
18800
  /**
18801
+ * Checks the preferred strong option.
18802
+ *
18283
18803
  * @param {State} state
18804
+ * Info passed around.
18284
18805
  * @returns {Exclude<Options['strong'], null | undefined>}
18806
+ * Preferred strong marker.
18285
18807
  */
18286
18808
  function checkStrong(state) {
18287
18809
  const marker = state.options.strong || '*';
@@ -18298,69 +18820,69 @@ function checkStrong(state) {
18298
18820
  }
18299
18821
 
18300
18822
  /**
18301
- * @import {Info, State} from 'mdast-util-to-markdown'
18823
+ * @import {AttentionInfo, Info, State} from 'mdast-util-to-markdown'
18302
18824
  * @import {Parents, Strong} from 'mdast'
18303
18825
  */
18304
18826
 
18305
18827
 
18306
- strong$1.peek = strongPeek;
18828
+ strong$1.attention = attention;
18829
+ strong$1.peek = peek;
18307
18830
 
18308
18831
  /**
18832
+ * Serialize a strong node.
18833
+ *
18834
+ * Attention is properly handled by `containerPhrasing`.
18835
+ *
18309
18836
  * @param {Strong} node
18837
+ * Node to serialize.
18310
18838
  * @param {Parents | undefined} _
18839
+ * Parent node.
18311
18840
  * @param {State} state
18841
+ * Info passed around.
18312
18842
  * @param {Info} info
18843
+ * Info on surrounding context.
18313
18844
  * @returns {string}
18845
+ * Serialized markdown.
18314
18846
  */
18315
18847
  function strong$1(node, _, state, info) {
18316
- const marker = checkStrong(state);
18317
- const exit = state.enter('strong');
18318
- const tracker = state.createTracker(info);
18319
- const before = tracker.move(marker + marker);
18320
-
18321
- let between = tracker.move(
18322
- state.containerPhrasing(node, {
18323
- after: marker,
18324
- before,
18325
- ...tracker.current()
18326
- })
18327
- );
18328
- const betweenHead = between.charCodeAt(0);
18329
- const open = encodeInfo(
18330
- info.before.charCodeAt(info.before.length - 1),
18331
- betweenHead,
18332
- marker
18333
- );
18334
-
18335
- if (open.inside) {
18336
- between = encodeCharacterReference(betweenHead) + between.slice(1);
18337
- }
18338
-
18339
- const betweenTail = between.charCodeAt(between.length - 1);
18340
- const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);
18341
-
18342
- if (close.inside) {
18343
- between = between.slice(0, -1) + encodeCharacterReference(betweenTail);
18344
- }
18345
-
18346
- const after = tracker.move(marker + marker);
18347
-
18848
+ const exit = state.enter('phrasing');
18849
+ const value = state.containerPhrasing({type: 'root', children: [node]}, info);
18348
18850
  exit();
18851
+ return value
18852
+ }
18349
18853
 
18350
- state.attentionEncodeSurroundingInfo = {
18351
- after: close.outside,
18352
- before: open.outside
18353
- };
18354
- return before + between + after
18854
+ /**
18855
+ * Serialize a strong node as attention.
18856
+ *
18857
+ * @param {Strong} _
18858
+ * Node to serialize.
18859
+ * @param {State} state
18860
+ * Info passed around.
18861
+ * @returns {AttentionInfo}
18862
+ * Info on how to serialize the node.
18863
+ */
18864
+ function attention(_, state) {
18865
+ const marker = checkStrong(state);
18866
+ return {
18867
+ construct: 'strong',
18868
+ markers: marker === '*' ? ['*', '_'] : ['_', '*'],
18869
+ sizes: [2]
18870
+ }
18355
18871
  }
18356
18872
 
18357
18873
  /**
18874
+ * Peek at this node.
18875
+ *
18358
18876
  * @param {Strong} _
18877
+ * Node to serialize.
18359
18878
  * @param {Parents | undefined} _1
18879
+ * Parent node.
18360
18880
  * @param {State} state
18881
+ * Info passed around.
18361
18882
  * @returns {string}
18883
+ * Start of the serialized markdown.
18362
18884
  */
18363
- function strongPeek(_, _1, state) {
18885
+ function peek(_, _1, state) {
18364
18886
  return state.options.strong || '*'
18365
18887
  }
18366
18888
 
@@ -18370,14 +18892,29 @@ function strongPeek(_, _1, state) {
18370
18892
  */
18371
18893
 
18372
18894
  /**
18895
+ * Serialize a text node.
18896
+ *
18373
18897
  * @param {Text} node
18374
- * @param {Parents | undefined} _
18898
+ * Node to serialize.
18899
+ * @param {Parents | undefined} parent
18900
+ * Parent node.
18375
18901
  * @param {State} state
18902
+ * Info passed around.
18376
18903
  * @param {Info} info
18904
+ * Info on surrounding context.
18377
18905
  * @returns {string}
18906
+ * Serialized markdown.
18378
18907
  */
18379
- function text$5(node, _, state, info) {
18380
- return state.safe(node.value, info)
18908
+ function text$5(node, parent, state, info) {
18909
+ /* c8 ignore next -- parent always passed */
18910
+ const siblings = parent ? parent.children : [];
18911
+ const index = siblings.indexOf(node);
18912
+
18913
+ return state.safe(node.value, {
18914
+ ...info,
18915
+ afterNode: siblings[index + 1],
18916
+ beforeNode: siblings[index - 1]
18917
+ })
18381
18918
  }
18382
18919
 
18383
18920
  /**
@@ -18385,8 +18922,12 @@ function text$5(node, _, state, info) {
18385
18922
  */
18386
18923
 
18387
18924
  /**
18925
+ * Checks the preferred rule repetition option.
18926
+ *
18388
18927
  * @param {State} state
18928
+ * Info passed around.
18389
18929
  * @returns {Exclude<Options['ruleRepetition'], null | undefined>}
18930
+ * Preferred rule repetition.
18390
18931
  */
18391
18932
  function checkRuleRepetition(state) {
18392
18933
  const repetition = state.options.ruleRepetition || 3;
@@ -18409,10 +18950,16 @@ function checkRuleRepetition(state) {
18409
18950
 
18410
18951
 
18411
18952
  /**
18953
+ * Serialize a thematic break node.
18954
+ *
18412
18955
  * @param {ThematicBreak} _
18956
+ * Node to serialize.
18413
18957
  * @param {Parents | undefined} _1
18958
+ * Parent node.
18414
18959
  * @param {State} state
18960
+ * Info passed around.
18415
18961
  * @returns {string}
18962
+ * Serialized markdown.
18416
18963
  */
18417
18964
  function thematicBreak$1(_, _1, state) {
18418
18965
  const value = (
@@ -20429,15 +20976,27 @@ class EditMap {
20429
20976
  * @type {Array<Change>}
20430
20977
  */
20431
20978
  this.map = [];
20979
+
20980
+ /**
20981
+ * Changes by index, so `add` does not scan `map` (quadratic on
20982
+ * table-heavy documents).
20983
+ *
20984
+ * @type {Map<number, Change>}
20985
+ */
20986
+ this.index = new Map();
20432
20987
  }
20433
20988
 
20434
20989
  /**
20435
20990
  * Create an edit: a remove and/or add at a certain place.
20436
20991
  *
20437
20992
  * @param {number} index
20993
+ * Index at which to apply the edit.
20438
20994
  * @param {number} remove
20995
+ * Count of items to remove at the index.
20439
20996
  * @param {Array<Event>} add
20997
+ * Items to add at the index.
20440
20998
  * @returns {undefined}
20999
+ * Nothing.
20441
21000
  */
20442
21001
  add(index, remove, add) {
20443
21002
  addImplementation(this, index, remove, add);
@@ -20460,7 +21019,9 @@ class EditMap {
20460
21019
  * Done, change the events.
20461
21020
  *
20462
21021
  * @param {Array<Event>} events
21022
+ * List of events to apply the edits to.
20463
21023
  * @returns {undefined}
21024
+ * Nothing.
20464
21025
  */
20465
21026
  consume(events) {
20466
21027
  this.map.sort(function (a, b) {
@@ -20512,6 +21073,7 @@ class EditMap {
20512
21073
 
20513
21074
  // Truncate everything.
20514
21075
  this.map.length = 0;
21076
+ this.index.clear();
20515
21077
  }
20516
21078
  }
20517
21079
 
@@ -20519,35 +21081,40 @@ class EditMap {
20519
21081
  * Create an edit.
20520
21082
  *
20521
21083
  * @param {EditMap} editMap
21084
+ * Edit map to apply to.
20522
21085
  * @param {number} at
21086
+ * Index at which to apply the edit.
20523
21087
  * @param {number} remove
21088
+ * Count of items to remove at the index.
20524
21089
  * @param {Array<Event>} add
21090
+ * Items to add at the index.
20525
21091
  * @returns {undefined}
21092
+ * Nothing.
20526
21093
  */
20527
21094
  function addImplementation(editMap, at, remove, add) {
20528
- let index = 0;
20529
-
20530
21095
  /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */
20531
21096
  if (remove === 0 && add.length === 0) {
20532
21097
  return;
20533
21098
  }
20534
- while (index < editMap.map.length) {
20535
- if (editMap.map[index][0] === at) {
20536
- editMap.map[index][1] += remove;
21099
+ const existing = editMap.index.get(at);
21100
+ if (existing) {
21101
+ existing[1] += remove;
20537
21102
 
20538
- // To do: before not used by tables, use when moving to micromark.
20539
- // if (before) {
20540
- // add.push(...editMap.map[index][2])
20541
- // editMap.map[index][2] = add
20542
- // } else {
20543
- editMap.map[index][2].push(...add);
20544
- // }
21103
+ // To do: before not used by tables, use when moving to micromark.
21104
+ // if (before) {
21105
+ // add.push(...existing[2])
21106
+ // existing[2] = add
21107
+ // } else {
21108
+ existing[2].push(...add);
21109
+ // }
20545
21110
 
20546
- return;
20547
- }
20548
- index += 1;
21111
+ return;
20549
21112
  }
20550
- editMap.map.push([at, remove, add]);
21113
+
21114
+ /** @type {Change} */
21115
+ const change = [at, remove, add];
21116
+ editMap.map.push(change);
21117
+ editMap.index.set(at, change);
20551
21118
  }
20552
21119
 
20553
21120
  // /**
@@ -20674,6 +21241,8 @@ function gfmTable() {
20674
21241
  }
20675
21242
 
20676
21243
  /**
21244
+ * Tokenizer for GFM tables.
21245
+ *
20677
21246
  * @this {TokenizeContext}
20678
21247
  * @type {Tokenizer}
20679
21248
  */
@@ -20704,10 +21273,16 @@ function tokenizeTable(effects, ok, nok) {
20704
21273
  function start(code) {
20705
21274
  let index = self.events.length - 1;
20706
21275
  while (index > -1) {
20707
- const type = self.events[index][1].type;
21276
+ const {
21277
+ type
21278
+ } = self.events[index][1];
20708
21279
  if (type === "lineEnding" ||
20709
21280
  // Note: markdown-rs uses `whitespace` instead of `linePrefix`
20710
- type === "linePrefix") index--;else break;
21281
+ type === "linePrefix") {
21282
+ index--;
21283
+ } else {
21284
+ break;
21285
+ }
20711
21286
  }
20712
21287
  const tail = index > -1 ? self.events[index][1].type : null;
20713
21288
  const next = tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore;
@@ -21327,12 +21902,19 @@ function resolveTable(events, context) {
21327
21902
  * Generate a cell.
21328
21903
  *
21329
21904
  * @param {EditMap} map
21905
+ * Edit map to apply to.
21330
21906
  * @param {Readonly<TokenizeContext>} context
21907
+ * Tokenize context.
21331
21908
  * @param {Readonly<Range>} range
21909
+ * Range of the cell within events.
21332
21910
  * @param {RowKind} rowKind
21911
+ * Type of row.
21333
21912
  * @param {number | undefined} rowEnd
21913
+ * Index of the end of the row, if known.
21334
21914
  * @param {Token | undefined} previousCell
21915
+ * Previous cell token, if any.
21335
21916
  * @returns {Token | undefined}
21917
+ * Current cell token after flushing, if any.
21336
21918
  */
21337
21919
  // eslint-disable-next-line max-params
21338
21920
  function flushCell(map, context, range, rowKind, rowEnd, previousCell) {
@@ -21427,10 +22009,17 @@ function flushCell(map, context, range, rowKind, rowEnd, previousCell) {
21427
22009
  * Generate table end (and table body end).
21428
22010
  *
21429
22011
  * @param {Readonly<EditMap>} map
22012
+ * Edit map to apply to.
21430
22013
  * @param {Readonly<TokenizeContext>} context
22014
+ * Tokenize context.
21431
22015
  * @param {number} index
22016
+ * Index within the events where the table end should be inserted.
21432
22017
  * @param {Token} table
22018
+ * Table token.
21433
22019
  * @param {Token | undefined} tableBody
22020
+ * Table body token, if any.
22021
+ * @returns {undefined}
22022
+ * Nothing.
21434
22023
  */
21435
22024
  // eslint-disable-next-line max-params
21436
22025
  function flushTableEnd(map, context, index, table, tableBody) {
@@ -21447,9 +22036,14 @@ function flushTableEnd(map, context, index, table, tableBody) {
21447
22036
  }
21448
22037
 
21449
22038
  /**
22039
+ * Get the point (start or end) for a given event in the list of events.
22040
+ *
21450
22041
  * @param {Readonly<Array<Event>>} events
22042
+ * List of events.
21451
22043
  * @param {number} index
22044
+ * Index of the event to get the point for.
21452
22045
  * @returns {Readonly<Point>}
22046
+ * Start point for enter and end point for exit.
21453
22047
  */
21454
22048
  function getPoint(events, index) {
21455
22049
  const event = events[index];
@@ -22884,6 +23478,7 @@ const ERROR = 7;
22884
23478
  const BIGINT = 8;
22885
23479
  // export const SYMBOL = 9;
22886
23480
 
23481
+ const { defineProperty } = Object;
22887
23482
  const env = typeof self === 'object' ? self : globalThis;
22888
23483
 
22889
23484
  const guard = (name, init) => {
@@ -22922,8 +23517,16 @@ const deserializer = ($, _) => {
22922
23517
  }
22923
23518
  case OBJECT: {
22924
23519
  const object = as({}, index);
22925
- for (const [key, index] of value)
22926
- object[unpair(key)] = unpair(index);
23520
+ for (const [key, index] of value) {
23521
+ const k = unpair(key), value = unpair(index);
23522
+ if (k === '__proto__') defineProperty(object, k, {
23523
+ value,
23524
+ configurable: true,
23525
+ enumerable: true,
23526
+ writable: true
23527
+ });
23528
+ else object[k] = value;
23529
+ }
22927
23530
  return object;
22928
23531
  }
22929
23532
  case DATE:
@@ -22946,7 +23549,12 @@ const deserializer = ($, _) => {
22946
23549
  }
22947
23550
  case ERROR: {
22948
23551
  const {name, message} = value;
22949
- return as(guard(name, message), index);
23552
+ return as(
23553
+ typeof env[name] === 'function' ?
23554
+ guard(name, message) :
23555
+ new Error(message),
23556
+ index
23557
+ );
22950
23558
  }
22951
23559
  case BIGINT:
22952
23560
  return as(BigInt(value), index);
@@ -22958,6 +23566,7 @@ const deserializer = ($, _) => {
22958
23566
  const { buffer } = new Uint8Array(value);
22959
23567
  return as(new DataView(buffer), value);
22960
23568
  }
23569
+ case '-0': return -0;
22961
23570
  }
22962
23571
  return as(guard(type, value), index);
22963
23572
  };
@@ -22979,7 +23588,7 @@ const deserialize = serialized => deserializer(new Map, serialized)(0);
22979
23588
  const EMPTY = '';
22980
23589
 
22981
23590
  const {toString} = {};
22982
- const {keys} = Object;
23591
+ const {keys, is} = Object;
22983
23592
 
22984
23593
  const typeOf = value => {
22985
23594
  const type = typeof value;
@@ -23007,8 +23616,8 @@ const typeOf = value => {
23007
23616
  if (asString.includes('Array'))
23008
23617
  return [ARRAY, asString];
23009
23618
 
23010
- if (asString.includes('Error'))
23011
- return [ERROR, asString];
23619
+ if (value instanceof Error)
23620
+ return [ERROR, value.name || 'Error'];
23012
23621
 
23013
23622
  return [OBJECT, asString];
23014
23623
  };
@@ -23039,6 +23648,10 @@ const serializer = (strict, json, $, _) => {
23039
23648
  TYPE = BIGINT;
23040
23649
  entry = value.toString();
23041
23650
  break;
23651
+ case 'number':
23652
+ if (!value && is(value, -0))
23653
+ return _.push(['-0']) - 1;
23654
+ break;
23042
23655
  case 'function':
23043
23656
  case 'symbol':
23044
23657
  if (strict)
@@ -23092,7 +23705,7 @@ const serializer = (strict, json, $, _) => {
23092
23705
  return index;
23093
23706
  }
23094
23707
  case DATE:
23095
- return as([TYPE, value.toISOString()], value);
23708
+ return as([TYPE, isNaN(value.getTime()) ? EMPTY : value.toISOString()], value);
23096
23709
  case REGEXP: {
23097
23710
  const {source, flags} = value;
23098
23711
  return as([TYPE, {source, flags}], value);
@@ -24247,6 +24860,7 @@ const html$3 = create({
24247
24860
  allowFullScreen: boolean,
24248
24861
  allowPaymentRequest: boolean,
24249
24862
  allowUserMedia: boolean,
24863
+ alpha: boolean,
24250
24864
  alt: null,
24251
24865
  as: null,
24252
24866
  async: boolean,
@@ -24260,8 +24874,12 @@ const html$3 = create({
24260
24874
  checked: boolean,
24261
24875
  cite: null,
24262
24876
  className: spaceSeparated,
24877
+ closedBy: null,
24878
+ colorSpace: null,
24263
24879
  cols: number,
24264
- colSpan: null,
24880
+ colSpan: number,
24881
+ command: null,
24882
+ commandFor: null,
24265
24883
  content: null,
24266
24884
  contentEditable: booleanish,
24267
24885
  controls: boolean,
@@ -24441,8 +25059,10 @@ const html$3 = create({
24441
25059
  seamless: boolean,
24442
25060
  selected: boolean,
24443
25061
  shadowRootClonable: boolean,
25062
+ shadowRootCustomElementRegistry: boolean,
24444
25063
  shadowRootDelegatesFocus: boolean,
24445
25064
  shadowRootMode: null,
25065
+ shadowRootSerializable: boolean,
24446
25066
  shape: null,
24447
25067
  size: number,
24448
25068
  sizes: null,
@@ -24528,8 +25148,11 @@ const html$3 = create({
24528
25148
  allowTransparency: null,
24529
25149
  autoCorrect: null,
24530
25150
  autoSave: null,
25151
+ credentialless: boolean,
24531
25152
  disablePictureInPicture: boolean,
24532
25153
  disableRemotePlayback: boolean,
25154
+ exportParts: commaSeparated,
25155
+ part: spaceSeparated,
24533
25156
  prefix: null,
24534
25157
  property: null,
24535
25158
  results: number,
@@ -24582,6 +25205,7 @@ const svg$1 = create({
24582
25205
  markerEnd: 'marker-end',
24583
25206
  markerMid: 'marker-mid',
24584
25207
  markerStart: 'marker-start',
25208
+ maskType: 'mask-type',
24585
25209
  navDown: 'nav-down',
24586
25210
  navDownLeft: 'nav-down-left',
24587
25211
  navDownRight: 'nav-down-right',
@@ -24849,6 +25473,7 @@ const svg$1 = create({
24849
25473
  markerWidth: null,
24850
25474
  mask: null,
24851
25475
  maskContentUnits: null,
25476
+ maskType: null,
24852
25477
  maskUnits: null,
24853
25478
  mathematical: null,
24854
25479
  max: null,
@@ -36695,11 +37320,7 @@ function cPlusPlus(hljs) {
36695
37320
  _hint: FUNCTION_HINTS },
36696
37321
  begin: regex.concat(
36697
37322
  /\b/,
36698
- /(?!decltype)/,
36699
- /(?!if)/,
36700
- /(?!for)/,
36701
- /(?!switch)/,
36702
- /(?!while)/,
37323
+ `(?!${RESERVED_KEYWORDS.join('|')})`,
36703
37324
  hljs.IDENT_RE,
36704
37325
  regex.lookahead(/(<[^<>]+>|)\s*\(/))
36705
37326
  };
@@ -38442,11 +39063,7 @@ function cpp(hljs) {
38442
39063
  _hint: FUNCTION_HINTS },
38443
39064
  begin: regex.concat(
38444
39065
  /\b/,
38445
- /(?!decltype)/,
38446
- /(?!if)/,
38447
- /(?!for)/,
38448
- /(?!switch)/,
38449
- /(?!while)/,
39066
+ `(?!${RESERVED_KEYWORDS.join('|')})`,
38450
39067
  hljs.IDENT_RE,
38451
39068
  regex.lookahead(/(<[^<>]+>|)\s*\(/))
38452
39069
  };
@@ -38787,7 +39404,7 @@ function csharp(hljs) {
38787
39404
  variants: [
38788
39405
  { begin: '\\b(0b[01\']+)' },
38789
39406
  { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B)' },
38790
- { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
39407
+ { begin: '(-?)(\\b0[xX][a-fA-F0-9\'_]+|(\\b[\\d\'_]+(\\.[\\d\'_]*)?|\\.[\\d\'_]+)([eE][-+]?[\\d\'_]+)?)' }
38791
39408
  ],
38792
39409
  relevance: 0
38793
39410
  };
@@ -39041,6 +39658,10 @@ const MODES$2 = (hljs) => {
39041
39658
  scope: 'number',
39042
39659
  begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/
39043
39660
  },
39661
+ UNICODE_RANGE: {
39662
+ scope: 'number',
39663
+ begin: /\b[Uu]\+[0-9A-Fa-f][0-9A-Fa-f?]{0,4}(-[0-9A-Fa-f][0-9A-Fa-f]{0,4})?/
39664
+ },
39044
39665
  FUNCTION_DISPATCH: {
39045
39666
  className: "built_in",
39046
39667
  begin: /[\w-]+(?=\()/
@@ -39809,6 +40430,7 @@ const ATTRIBUTES$2 = [
39809
40430
  'transition-timing-function',
39810
40431
  'translate',
39811
40432
  'unicode-bidi',
40433
+ 'unicode-range',
39812
40434
  'user-modify',
39813
40435
  'user-select',
39814
40436
  'vector-effect',
@@ -39915,9 +40537,10 @@ function css(hljs) {
39915
40537
  modes.HEXCOLOR,
39916
40538
  modes.IMPORTANT,
39917
40539
  modes.CSS_NUMBER_MODE,
40540
+ modes.UNICODE_RANGE,
39918
40541
  ...STRINGS,
39919
40542
  // needed to highlight these as strings and to avoid issues with
39920
- // illegal characters that might be inside urls that would tigger the
40543
+ // illegal characters that might be inside urls that would trigger the
39921
40544
  // languages illegal stack
39922
40545
  {
39923
40546
  begin: /(url|data-uri)\(/,
@@ -39997,7 +40620,10 @@ function diff(hljs) {
39997
40620
  className: 'meta',
39998
40621
  relevance: 10,
39999
40622
  match: regex.either(
40000
- /^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,
40623
+ /^@@ +-\d+,\d+ +\+\d+,\d+ +@@/, // @@ -1,2 +1,2 @@
40624
+ /^@@ +-\d+ +\+\d+,\d+ +@@/, // @@ -1 +1,2 @@
40625
+ /^@@ +-\d+,\d+ +\+\d+ +@@/, // @@ -1,2 +1 @@
40626
+ /^@@ +-\d+ +\+\d+ +@@/, // @@ -1 +1 @@
40001
40627
  /^\*\*\* +\d+,\d+ +\*\*\*\*$/,
40002
40628
  /^--- +\d+,\d+ +----$/
40003
40629
  )
@@ -40682,6 +41308,7 @@ function java(hljs) {
40682
41308
  }
40683
41309
 
40684
41310
  const IDENT_RE$1 = '[A-Za-z$_][0-9A-Za-z$_]*';
41311
+
40685
41312
  const KEYWORDS$1 = [
40686
41313
  "as", // for exports
40687
41314
  "in",
@@ -41229,7 +41856,8 @@ function javascript$1(hljs) {
41229
41856
  noneOf([
41230
41857
  ...BUILT_IN_GLOBALS$1,
41231
41858
  "super",
41232
- "import"
41859
+ "import",
41860
+ "await",
41233
41861
  ].map(x => `${x}\\s*\\(`)),
41234
41862
  IDENT_RE$1$1, regex.lookahead(/\s*\(/)),
41235
41863
  className: "title.function",
@@ -41298,7 +41926,7 @@ function javascript$1(hljs) {
41298
41926
  keywords: KEYWORDS$1$1,
41299
41927
  // this will be extended by TypeScript
41300
41928
  exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
41301
- illegal: /#(?![$_A-z])/,
41929
+ illegal: /#(?![$_A-Za-z])/,
41302
41930
  contains: [
41303
41931
  hljs.SHEBANG({
41304
41932
  label: "shebang",
@@ -41449,18 +42077,26 @@ function javascript$1(hljs) {
41449
42077
  };
41450
42078
  }
41451
42079
 
42080
+ const EXTENDED_NUMBER_RE = '([-+]?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)|NaN|[-+]?Infinity'; // 0x..., 0..., decimal, float
42081
+
42082
+ const EXTENDED_NUMBER_MODE = {
42083
+ scope: 'number',
42084
+ match: EXTENDED_NUMBER_RE,
42085
+ relevance: 0
42086
+ };
42087
+
41452
42088
  /*
41453
42089
  Language: JSON
41454
42090
  Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format.
41455
- Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
41456
- Website: http://www.json.org
42091
+ Websites: http://www.json.org, https://www.json5.org
41457
42092
  Category: common, protocols, web
41458
42093
  */
41459
42094
 
42095
+
41460
42096
  function json(hljs) {
41461
42097
  const ATTRIBUTE = {
41462
42098
  className: 'attr',
41463
- begin: /"(\\.|[^\\"\r\n])*"(?=\s*:)/,
42099
+ begin: /(("(\\.|[^\\"\r\n])*")|('(\\.|[^\\'\r\n])*'))(?=\s*:)/,
41464
42100
  relevance: 1.01
41465
42101
  };
41466
42102
  const PUNCTUATION = {
@@ -41485,16 +42121,17 @@ function json(hljs) {
41485
42121
 
41486
42122
  return {
41487
42123
  name: 'JSON',
41488
- aliases: ['jsonc'],
42124
+ aliases: ['jsonc', 'json5'],
41489
42125
  keywords:{
41490
42126
  literal: LITERALS,
41491
42127
  },
41492
42128
  contains: [
41493
42129
  ATTRIBUTE,
41494
42130
  PUNCTUATION,
42131
+ hljs.APOS_STRING_MODE,
41495
42132
  hljs.QUOTE_STRING_MODE,
41496
42133
  LITERALS_MODE,
41497
- hljs.C_NUMBER_MODE,
42134
+ EXTENDED_NUMBER_MODE,
41498
42135
  hljs.C_LINE_COMMENT_MODE,
41499
42136
  hljs.C_BLOCK_COMMENT_MODE
41500
42137
  ],
@@ -41798,6 +42435,10 @@ const MODES$1 = (hljs) => {
41798
42435
  scope: 'number',
41799
42436
  begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/
41800
42437
  },
42438
+ UNICODE_RANGE: {
42439
+ scope: 'number',
42440
+ begin: /\b[Uu]\+[0-9A-Fa-f][0-9A-Fa-f?]{0,4}(-[0-9A-Fa-f][0-9A-Fa-f]{0,4})?/
42441
+ },
41801
42442
  FUNCTION_DISPATCH: {
41802
42443
  className: "built_in",
41803
42444
  begin: /[\w-]+(?=\()/
@@ -42566,6 +43207,7 @@ const ATTRIBUTES$1 = [
42566
43207
  'transition-timing-function',
42567
43208
  'translate',
42568
43209
  'unicode-bidi',
43210
+ 'unicode-range',
42569
43211
  'user-modify',
42570
43212
  'user-select',
42571
43213
  'vector-effect',
@@ -42670,6 +43312,7 @@ function less(hljs) {
42670
43312
  excludeEnd: true
42671
43313
  }
42672
43314
  },
43315
+ modes.UNICODE_RANGE,
42673
43316
  modes.HEXCOLOR,
42674
43317
  PARENS_MODE,
42675
43318
  IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
@@ -42780,7 +43423,7 @@ function less(hljs) {
42780
43423
  MIXIN_GUARD_MODE,
42781
43424
  IDENT_MODE('keyword', 'all\\b'),
42782
43425
  IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'), // otherwise it’s identified as tag
42783
-
43426
+
42784
43427
  {
42785
43428
  begin: '\\b(' + TAGS$1.join('|') + ')\\b',
42786
43429
  className: 'selector-tag'
@@ -44422,6 +45065,8 @@ function php(hljs) {
44422
45065
  VARIABLE,
44423
45066
  LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
44424
45067
  hljs.C_BLOCK_COMMENT_MODE,
45068
+ hljs.C_LINE_COMMENT_MODE,
45069
+ hljs.HASH_COMMENT_MODE,
44425
45070
  STRING,
44426
45071
  NUMBER,
44427
45072
  CONSTRUCTOR_CALL,
@@ -44446,6 +45091,8 @@ function php(hljs) {
44446
45091
  NAMED_ARGUMENT,
44447
45092
  LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
44448
45093
  hljs.C_BLOCK_COMMENT_MODE,
45094
+ hljs.C_LINE_COMMENT_MODE,
45095
+ hljs.HASH_COMMENT_MODE,
44449
45096
  STRING,
44450
45097
  NUMBER,
44451
45098
  CONSTRUCTOR_CALL,
@@ -44574,6 +45221,8 @@ function php(hljs) {
44574
45221
  VARIABLE,
44575
45222
  LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,
44576
45223
  hljs.C_BLOCK_COMMENT_MODE,
45224
+ hljs.C_LINE_COMMENT_MODE,
45225
+ hljs.HASH_COMMENT_MODE,
44577
45226
  STRING,
44578
45227
  NUMBER
44579
45228
  ]
@@ -46206,6 +46855,10 @@ const MODES = (hljs) => {
46206
46855
  scope: 'number',
46207
46856
  begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/
46208
46857
  },
46858
+ UNICODE_RANGE: {
46859
+ scope: 'number',
46860
+ begin: /\b[Uu]\+[0-9A-Fa-f][0-9A-Fa-f?]{0,4}(-[0-9A-Fa-f][0-9A-Fa-f]{0,4})?/
46861
+ },
46209
46862
  FUNCTION_DISPATCH: {
46210
46863
  className: "built_in",
46211
46864
  begin: /[\w-]+(?=\()/
@@ -46974,6 +47627,7 @@ const ATTRIBUTES = [
46974
47627
  'transition-timing-function',
46975
47628
  'translate',
46976
47629
  'unicode-bidi',
47630
+ 'unicode-range',
46977
47631
  'user-modify',
46978
47632
  'user-select',
46979
47633
  'vector-effect',
@@ -47087,6 +47741,7 @@ function scss(hljs) {
47087
47741
  VARIABLE,
47088
47742
  modes.HEXCOLOR,
47089
47743
  modes.CSS_NUMBER_MODE,
47744
+ modes.UNICODE_RANGE,
47090
47745
  hljs.QUOTE_STRING_MODE,
47091
47746
  hljs.APOS_STRING_MODE,
47092
47747
  modes.IMPORTANT,
@@ -48829,6 +49484,7 @@ function swift(hljs) {
48829
49484
  }
48830
49485
 
48831
49486
  const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
49487
+
48832
49488
  const KEYWORDS = [
48833
49489
  "as", // for exports
48834
49490
  "in",
@@ -49376,7 +50032,8 @@ function javascript(hljs) {
49376
50032
  noneOf([
49377
50033
  ...BUILT_IN_GLOBALS,
49378
50034
  "super",
49379
- "import"
50035
+ "import",
50036
+ "await",
49380
50037
  ].map(x => `${x}\\s*\\(`)),
49381
50038
  IDENT_RE$1, regex.lookahead(/\s*\(/)),
49382
50039
  className: "title.function",
@@ -49445,7 +50102,7 @@ function javascript(hljs) {
49445
50102
  keywords: KEYWORDS$1,
49446
50103
  // this will be extended by TypeScript
49447
50104
  exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
49448
- illegal: /#(?![$_A-z])/,
50105
+ illegal: /#(?![$_A-Za-z])/,
49449
50106
  contains: [
49450
50107
  hljs.SHEBANG({
49451
50108
  label: "shebang",
@@ -52094,7 +52751,7 @@ function requireCore () {
52094
52751
  return mode;
52095
52752
  }
52096
52753
 
52097
- var version = "11.11.1";
52754
+ var version = "11.11.2";
52098
52755
 
52099
52756
  class HTMLInjectionError extends Error {
52100
52757
  constructor(reason, html) {
@@ -52616,12 +53273,15 @@ function requireCore () {
52616
53273
  }
52617
53274
  }
52618
53275
 
52619
- // edge case for when illegal matches $ (end of line) which is technically
53276
+ // edge case for when illegal matches $ (end of line/text) which is technically
52620
53277
  // a 0 width match but not a begin/end match so it's not caught by the
52621
- // first handler (when ignoreIllegals is true)
53278
+ // first handler (when `ignoreIllegals` is true)
52622
53279
  if (match.type === "illegal" && lexeme === "") {
52623
- // advance so we aren't stuck in an infinite loop
52624
- modeBuffer += "\n";
53280
+ if (match.index === codeToHighlight.length) ; else {
53281
+ // matched literal `\n` (with `$`) so we must manually add the newline
53282
+ // itself to the modeBuffer so it is not lost when we advance the cursor
53283
+ modeBuffer += "\n";
53284
+ }
52625
53285
  return 1;
52626
53286
  }
52627
53287