@limetech/lime-elements 40.20.0 → 40.21.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 (35) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/lime-elements.cjs.js +1 -1
  3. package/dist/cjs/limel-chart.cjs.entry.js +52 -28
  4. package/dist/cjs/limel-markdown.cjs.entry.js +2 -2
  5. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +1 -1
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/cjs/{markdown-exporter-BWS2EBxq.js → markdown-exporter-CGNfjGr9.js} +80 -897
  8. package/dist/cjs/{markdown-parser-toAp9-Eq.js → markdown-parser-C14XF_G3.js} +994 -38
  9. package/dist/collection/components/chart/chart.css +27 -6
  10. package/dist/collection/components/chart/chart.js +29 -12
  11. package/dist/collection/components/chart/options.js +15 -19
  12. package/dist/collection/components/chart/scale.js +1 -1
  13. package/dist/collection/components/chart/theme.js +13 -1
  14. package/dist/esm/lime-elements.js +1 -1
  15. package/dist/esm/limel-chart.entry.js +52 -28
  16. package/dist/esm/limel-markdown.entry.js +2 -2
  17. package/dist/esm/limel-prosemirror-adapter.entry.js +1 -1
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/{markdown-exporter-B2vFxSLw.js → markdown-exporter-DcFcD699.js} +80 -897
  20. package/dist/esm/{markdown-parser-Cw8iW5R9.js → markdown-parser-8aHA9IYo.js} +991 -33
  21. package/dist/lime-elements/lime-elements.esm.js +1 -1
  22. package/dist/lime-elements/{p-8514480b.entry.js → p-7d6a12fe.entry.js} +2 -2
  23. package/dist/lime-elements/{p-1d9bc526.entry.js → p-9edd79a8.entry.js} +1 -1
  24. package/dist/lime-elements/p-C9gctvIB.js +1 -0
  25. package/dist/lime-elements/{p-c2f993cc.entry.js → p-a891f3e8.entry.js} +1 -1
  26. package/dist/lime-elements/p-kiQd8Ntf.js +7 -0
  27. package/dist/types/components/chart/chart.d.ts +7 -3
  28. package/dist/types/components/chart/chart.types.d.ts +4 -1
  29. package/dist/types/components/chart/options.d.ts +4 -3
  30. package/dist/types/components/chart/scale.d.ts +8 -3
  31. package/dist/types/components/chart/theme.d.ts +2 -2
  32. package/dist/types/components.d.ts +12 -12
  33. package/package.json +3 -3
  34. package/dist/lime-elements/p-Bd37Vplf.js +0 -7
  35. package/dist/lime-elements/p-CvHpvp0f.js +0 -1
@@ -15066,7 +15066,7 @@ function markdownTable(table, options = {}) {
15066
15066
  }
15067
15067
 
15068
15068
  while (++columnIndex < table[rowIndex].length) {
15069
- const cell = serialize(table[rowIndex][columnIndex]);
15069
+ const cell = serialize$1(table[rowIndex][columnIndex]);
15070
15070
 
15071
15071
  if (options.alignDelimiters !== false) {
15072
15072
  const size = stringLength(cell);
@@ -15237,7 +15237,7 @@ function markdownTable(table, options = {}) {
15237
15237
  * @param {string|null|undefined} [value]
15238
15238
  * @returns {string}
15239
15239
  */
15240
- function serialize(value) {
15240
+ function serialize$1(value) {
15241
15241
  return value === null || value === undefined ? '' : String(value)
15242
15242
  }
15243
15243
 
@@ -15281,7 +15281,7 @@ function toAlignment(value) {
15281
15281
  * Whether `value` is phrasing content.
15282
15282
  */
15283
15283
 
15284
- const phrasing =
15284
+ const phrasing$1 =
15285
15285
  /** @type {(node?: unknown) => node is PhrasingContent} */
15286
15286
  (
15287
15287
  convert([
@@ -15745,6 +15745,939 @@ function checkEmphasis(state) {
15745
15745
  return marker
15746
15746
  }
15747
15747
 
15748
+ /**
15749
+ * Get the first character of a value.
15750
+ *
15751
+ * Is aware of astral characters (such as emoji).
15752
+ *
15753
+ * @param {string} value
15754
+ * Value.
15755
+ * @returns {string}
15756
+ * First character; empty if `value` is empty.
15757
+ */
15758
+ function firstCharacter(value) {
15759
+ const code = value.codePointAt(0);
15760
+ return code === undefined ? '' : String.fromCodePoint(code)
15761
+ }
15762
+
15763
+ /**
15764
+ * Get the last character of a value.
15765
+ *
15766
+ * Is aware of astral characters (such as emoji).
15767
+ *
15768
+ * @param {string} value
15769
+ * Value.
15770
+ * @returns {string}
15771
+ * Last character; empty if `value` is empty.
15772
+ */
15773
+ function lastCharacter(value) {
15774
+ // Only a surrogate pair gives a code point above the BMP.
15775
+ const code = value.codePointAt(value.length - 2);
15776
+ return code !== undefined && code > 0xff_ff
15777
+ ? value.slice(-2)
15778
+ : value.slice(-1)
15779
+ }
15780
+
15781
+ /**
15782
+ * Encode a code point as a character reference.
15783
+ *
15784
+ * @param {number} code
15785
+ * Code point to encode.
15786
+ * @returns {string}
15787
+ * Encoded character reference.
15788
+ */
15789
+ function encodeCharacterReference(code) {
15790
+ return '&#x' + code.toString(16).toUpperCase() + ';'
15791
+ }
15792
+
15793
+ /**
15794
+ * @import {EncodeSides} from '../types.js'
15795
+ */
15796
+
15797
+
15798
+ /**
15799
+ * Check whether to encode (as a character reference) the characters
15800
+ * surrounding an attention run.
15801
+ *
15802
+ * Which characters are around an attention run influence whether it works or
15803
+ * not.
15804
+ *
15805
+ * See <https://github.com/orgs/syntax-tree/discussions/60> for more info.
15806
+ * See this markdown in a particular renderer to see what works:
15807
+ *
15808
+ * ```markdown
15809
+ * | | A (letter inside) | B (punctuation inside) | C (whitespace inside) | D (nothing inside) |
15810
+ * | ----------------------- | ----------------- | ---------------------- | --------------------- | ------------------ |
15811
+ * | 1 (letter outside) | x*y*z | x*.*z | x* *z | x**z |
15812
+ * | 2 (punctuation outside) | .*y*. | .*.*. | .* *. | .**. |
15813
+ * | 3 (whitespace outside) | x *y* z | x *.* z | x * * z | x ** z |
15814
+ * | 4 (nothing outside) | *x* | *.* | * * | ** |
15815
+ * ```
15816
+ *
15817
+ * @param {number} outside
15818
+ * Code point on the outer side of the run.
15819
+ * @param {number} inside
15820
+ * Code point on the inner side of the run.
15821
+ * @param {string} marker
15822
+ * Marker of the run.
15823
+ * Underscores are handled more strictly (they form less often) than
15824
+ * asterisks.
15825
+ * @returns {EncodeSides}
15826
+ * Whether to encode characters.
15827
+ */
15828
+ // Important: punctuation must never be encoded.
15829
+ // Punctuation is solely used by markdown constructs.
15830
+ // And by encoding itself.
15831
+ // Encoding them will break constructs or double encode things.
15832
+ function encodeInfo(outside, inside, marker) {
15833
+ const outsideKind = classifyCharacter(outside);
15834
+ const insideKind = classifyCharacter(inside);
15835
+
15836
+ // Letter outside:
15837
+ if (outsideKind === undefined) {
15838
+ return insideKind === undefined
15839
+ ? // Letter inside:
15840
+ // we have to encode *both* letters for `_` as it is looser.
15841
+ // it already forms for `*` (and GFMs `~`).
15842
+ marker === '_'
15843
+ ? {inside: true, outside: true}
15844
+ : {inside: false, outside: false}
15845
+ : insideKind === 1
15846
+ ? // Whitespace inside: encode both (letter, whitespace).
15847
+ {inside: true, outside: true}
15848
+ : // Punctuation inside: encode outer (letter)
15849
+ {inside: false, outside: true}
15850
+ }
15851
+
15852
+ // Whitespace outside:
15853
+ if (outsideKind === 1) {
15854
+ return insideKind === undefined
15855
+ ? // Letter inside: already forms.
15856
+ {inside: false, outside: false}
15857
+ : insideKind === 1
15858
+ ? // Whitespace inside: encode both (whitespace).
15859
+ {inside: true, outside: true}
15860
+ : // Punctuation inside: already forms.
15861
+ {inside: false, outside: false}
15862
+ }
15863
+
15864
+ // Punctuation outside:
15865
+ return insideKind === undefined
15866
+ ? // Letter inside: already forms.
15867
+ {inside: false, outside: false}
15868
+ : insideKind === 1
15869
+ ? // Whitespace inside: encode inner (whitespace).
15870
+ {inside: true, outside: false}
15871
+ : // Punctuation inside: already forms.
15872
+ {inside: false, outside: false}
15873
+ }
15874
+
15875
+ /**
15876
+ * @typedef {1 | 2 | 3 | 4 | 5 | 6 | 7} Kind
15877
+ * Kind of HTML (flow) element.
15878
+ */
15879
+
15880
+ /**
15881
+ * Infer the kind of HTML that `value` is.
15882
+ *
15883
+ * This works on valid trees as produced by `micromark`.
15884
+ * Kinds:
15885
+ *
15886
+ * 1. raw
15887
+ * 2. comment
15888
+ * 3. instruction
15889
+ * 4. declaration
15890
+ * 5. cdata
15891
+ * 6. block
15892
+ * 7. other
15893
+ *
15894
+ * See: <https://spec.commonmark.org/0.31.2/#html-blocks>.
15895
+ *
15896
+ * @param {string} value
15897
+ * HTML.
15898
+ * @returns {Kind | undefined}
15899
+ * Kind; `undefined` if unknown.
15900
+ */
15901
+ function htmlKind(value) {
15902
+ if (value.charCodeAt(0) !== 60 /* `<` */) return
15903
+
15904
+ const next = value.charCodeAt(1);
15905
+
15906
+ if (next === 33 /* `!` */) {
15907
+ const code = value.charCodeAt(2);
15908
+ if (code === 45 /* `-` */) return 2
15909
+ if (code === 91 /* `[` */) return 5
15910
+ if (asciiAlpha(code)) return 4
15911
+ return
15912
+ }
15913
+
15914
+ if (next === 63 /* `?` */) return 3
15915
+
15916
+ const closing = next === 47; /* `/` */
15917
+ const start = closing ? 2 : 1;
15918
+ let end = start;
15919
+ let code = value.charCodeAt(end);
15920
+
15921
+ if (!asciiAlpha(code)) return
15922
+
15923
+ while (code === 45 /* `-` */ || asciiAlphanumeric(code)) {
15924
+ code = value.charCodeAt(++end);
15925
+ }
15926
+
15927
+ const name = value.slice(start, end).toLowerCase();
15928
+
15929
+ if (!closing && code !== 47 /* `/` */ && htmlRawNames.includes(name)) {
15930
+ return 1
15931
+ }
15932
+
15933
+ return htmlBlockNames.includes(name) ? 6 : 7
15934
+ }
15935
+
15936
+ /**
15937
+ * @import {Attention, Handle, Info, State, Tracker} from 'mdast-util-to-markdown'
15938
+ * @import {PhrasingParents} from '../types.js'
15939
+ */
15940
+
15941
+
15942
+ /**
15943
+ * Markers for builtin attention (emphasis, strong) to whether they are stricter:
15944
+ * whether they cannot open and close inside words.
15945
+ *
15946
+ * Builtin runs pair following CommonMark rules for emphasis and strong:
15947
+ * they are split,
15948
+ * using one or two markers at a time,
15949
+ * with the rule of 3.
15950
+ * Other markers pair like GFM strikethrough:
15951
+ * whole runs pair with a run of the same size.
15952
+ *
15953
+ * @type {Map<string, boolean>}
15954
+ */
15955
+ const builtins = new Map([
15956
+ ['*', false],
15957
+ ['_', true]
15958
+ ]);
15959
+
15960
+ /**
15961
+ * @typedef AttentionResult
15962
+ * Attention, of which the sequence is chosen later.
15963
+ * @property {Array<Item>} children
15964
+ * Serialized children.
15965
+ * @property {Array<string>} sequences
15966
+ * Sequences that can be used, in order of preference.
15967
+ */
15968
+
15969
+ /**
15970
+ * @typedef Improvement
15971
+ * Improvement of attention sequences.
15972
+ * @property {Map<AttentionResult, string>} chosen
15973
+ * Chosen sequences for each attention.
15974
+ * @property {Array<Token>} tokens
15975
+ * Tokens involved in the improvement.
15976
+ * @property {Mistake | undefined} mistake
15977
+ * Mistake that led to this improvement, if any.
15978
+ */
15979
+
15980
+ /**
15981
+ * @typedef {AttentionResult | string} Item
15982
+ * Serialized phrasing.
15983
+ */
15984
+
15985
+ /**
15986
+ * @typedef Mistake
15987
+ * Sequence that does not form its attention.
15988
+ * @property {Array<AttentionResult>} attention
15989
+ * Attention to try other sequences for.
15990
+ * @property {number} index
15991
+ * Index of the token.
15992
+ */
15993
+
15994
+ /**
15995
+ * @typedef Run
15996
+ * Sequences next to each other with the same marker.
15997
+ * @property {boolean} close
15998
+ * Whether it can close.
15999
+ * @property {number} end
16000
+ * Index after the last marker not used (to open).
16001
+ * @property {Array<Token>} markers
16002
+ * Sequence of each marker.
16003
+ * @property {boolean} open
16004
+ * Whether it can open.
16005
+ * @property {boolean} split
16006
+ * Whether it can be split (built-in attention).
16007
+ * @property {number} start
16008
+ * Index of the first marker not used (to close).
16009
+ * @property {Array<Token>} tokens
16010
+ * Sequences.
16011
+ */
16012
+
16013
+ /**
16014
+ * @typedef Token
16015
+ * Rendered phrasing.
16016
+ * @property {AttentionResult | undefined} attention
16017
+ * Attention, if this is one of its sequences.
16018
+ * @property {string} value
16019
+ * Value.
16020
+ */
16021
+
16022
+ /**
16023
+ * Get candidates for a mistake:
16024
+ * attention to try other sequences for,
16025
+ * later first.
16026
+ *
16027
+ * @param {Array<Token>} tokens
16028
+ * Tokens.
16029
+ * @param {Array<Token>} involved
16030
+ * Sequences involved in the mistake.
16031
+ * @param {Map<Token, Run>} runOf
16032
+ * Run of each sequence.
16033
+ * @returns {Array<AttentionResult>}
16034
+ * Candidates.
16035
+ */
16036
+ function candidates(tokens, involved, runOf) {
16037
+ /** @type {Set<AttentionResult | undefined>} */
16038
+ const related = new Set();
16039
+
16040
+ // The attention involved, and attention in runs with its sequences.
16041
+ for (const token of tokens) {
16042
+ const siblings = runOf.get(token);
16043
+ if (
16044
+ siblings &&
16045
+ token.attention &&
16046
+ involved.some((d) => d.attention === token.attention)
16047
+ ) {
16048
+ for (const sibling of siblings.tokens) {
16049
+ related.add(sibling.attention);
16050
+ }
16051
+ }
16052
+ }
16053
+
16054
+ /** @type {Array<AttentionResult>} */
16055
+ const ordered = [];
16056
+
16057
+ for (const token of tokens) {
16058
+ if (token.attention && related.delete(token.attention)) {
16059
+ ordered.push(token.attention);
16060
+ }
16061
+ }
16062
+
16063
+ // Later first: attention that opens later is inner or next.
16064
+ ordered.reverse();
16065
+ return ordered
16066
+ }
16067
+
16068
+ /**
16069
+ * Check whether sequences form their attention, like `micromark`.
16070
+ *
16071
+ * Sequences of `*` and `_` pair like emphasis and strong in CommonMark,
16072
+ * others like strikethrough in GFM.
16073
+ *
16074
+ * @param {Array<Token>} tokens
16075
+ * Tokens.
16076
+ * @param {string} before
16077
+ * Characters before.
16078
+ * @param {string} after
16079
+ * Characters after.
16080
+ * @returns {Mistake | undefined}
16081
+ * First mistake, if any.
16082
+ */
16083
+ function check(tokens, before, after) {
16084
+ /** @type {Array<Run>} */
16085
+ const runs = [];
16086
+ /** @type {Map<Token, Array<Token>>} */
16087
+ const wrong = new Map();
16088
+ /** @type {Map<Token, Run>} */
16089
+ const runOf = new Map();
16090
+ let index = 0;
16091
+
16092
+ while (index < tokens.length) {
16093
+ if (!tokens[index].attention) {
16094
+ index++;
16095
+ continue
16096
+ }
16097
+
16098
+ const marker = tokens[index].value.charAt(0);
16099
+ const strict = builtins.get(marker);
16100
+ let end = index + 1;
16101
+
16102
+ while (
16103
+ end < tokens.length &&
16104
+ tokens[end].attention &&
16105
+ tokens[end].value.charAt(0) === marker
16106
+ ) {
16107
+ end++;
16108
+ }
16109
+
16110
+ const head = index ? tokens[index - 1].value : before;
16111
+ const previous = classifyCharacter(head.charCodeAt(head.length - 1));
16112
+ const next = classifyCharacter(
16113
+ (end < tokens.length ? tokens[end].value : after).charCodeAt(0)
16114
+ );
16115
+ const open = !next || (next === 2 && Boolean(previous));
16116
+ const close = !previous || (previous === 2 && Boolean(next));
16117
+ /** @type {Run} */
16118
+ const run = {
16119
+ tokens: tokens.slice(index, end),
16120
+ markers: [],
16121
+ start: 0,
16122
+ end: 0,
16123
+ // Underscores are strict, they cannot open or close inside words.
16124
+ open: strict ? open && (Boolean(previous) || !close) : open,
16125
+ close: strict ? close && (Boolean(next) || !open) : close,
16126
+ // All builtins can split runs.
16127
+ split: strict !== undefined
16128
+ };
16129
+
16130
+ for (const token of run.tokens) {
16131
+ // Every sequence is wrong until it pairs with its other sequence.
16132
+ wrong.set(token, [...run.tokens]);
16133
+ runOf.set(token, run);
16134
+ let size = token.value.length;
16135
+ while (size--) run.markers.push(token);
16136
+ }
16137
+
16138
+ run.end = run.markers.length;
16139
+ runs.push(run);
16140
+ index = end;
16141
+ }
16142
+
16143
+ pair(runs, wrong);
16144
+
16145
+ index = -1;
16146
+
16147
+ while (++index < tokens.length) {
16148
+ const involved = wrong.get(tokens[index]);
16149
+ if (involved) return {attention: candidates(tokens, involved, runOf), index}
16150
+ }
16151
+ }
16152
+
16153
+ /**
16154
+ * Serialize the children of a parent that contains phrasing children.
16155
+ *
16156
+ * @param {PhrasingParents} parent
16157
+ * Parent of phrasing nodes.
16158
+ * @param {State} state
16159
+ * Info passed around about the current state.
16160
+ * @param {Info} info
16161
+ * Info on where we are in the document we are generating.
16162
+ * @returns {string}
16163
+ * Serialized result.
16164
+ */
16165
+ function containerPhrasing(parent, state, info) {
16166
+ return serialize(phrasing(parent, state, info), info.before, info.after)
16167
+ }
16168
+
16169
+ /**
16170
+ * Encode the first or last character of tokens as a character reference,
16171
+ * if it is text.
16172
+ *
16173
+ * @param {Array<Token>} tokens
16174
+ * Tokens.
16175
+ * @param {boolean} start
16176
+ * Whether to encode the first or last character.
16177
+ * @returns {undefined}
16178
+ * Nothing.
16179
+ */
16180
+ function encode(tokens, start) {
16181
+ const token = tokens[start ? 0 : tokens.length - 1];
16182
+
16183
+ if (!token || token.attention) return
16184
+
16185
+ const character = start
16186
+ ? firstCharacter(token.value)
16187
+ : lastCharacter(token.value);
16188
+ const reference = encodeCharacterReference(
16189
+ /** @type {number} */ (character.codePointAt(0))
16190
+ );
16191
+
16192
+ if (start) {
16193
+ token.value = reference + token.value.slice(character.length);
16194
+ } else {
16195
+ let value = token.value.slice(0, token.value.length - character.length);
16196
+ let escapes = 0;
16197
+
16198
+ while (value.charCodeAt(value.length - 1 - escapes) === 92 /* `\` */) {
16199
+ escapes++;
16200
+ }
16201
+
16202
+ // Odd number would escape the `&` again.
16203
+ if (escapes % 2) value += '\\';
16204
+ token.value = value + reference;
16205
+ }
16206
+ }
16207
+
16208
+ /**
16209
+ * Try other sequences for the candidates of a mistake and use the first that
16210
+ * moves the mistake further.
16211
+ *
16212
+ * @param {Array<Item>} items
16213
+ * Items.
16214
+ * @param {Map<AttentionResult, string>} chosen
16215
+ * Sequences to use instead of preferred sequences.
16216
+ * @param {Mistake} mistake
16217
+ * Mistake.
16218
+ * @param {string} before
16219
+ * Characters before.
16220
+ * @param {string} after
16221
+ * Characters after.
16222
+ * @returns {Improvement | undefined}
16223
+ * Result if better.
16224
+ */
16225
+ function improve(items, chosen, mistake, before, after) {
16226
+ for (const attention of mistake.attention) {
16227
+ const current = chosen.get(attention) || attention.sequences[0];
16228
+
16229
+ for (const sequence of attention.sequences) {
16230
+ if (sequence === current) continue
16231
+ const trial = new Map(chosen);
16232
+ trial.set(attention, sequence);
16233
+ const tokens = render(items, trial, before, after);
16234
+ const next = check(tokens, before, after);
16235
+
16236
+ if (!next || next.index > mistake.index) {
16237
+ return {chosen: trial, mistake: next, tokens}
16238
+ }
16239
+ }
16240
+ }
16241
+ }
16242
+
16243
+ /**
16244
+ * Pair runs like `micromark` and mark sequences that do form their attention
16245
+ * as fine.
16246
+ *
16247
+ * Each pair uses markers from the end of an opener and the start of a closer.
16248
+ * It forms the intended attention if those markers are exactly the whole
16249
+ * opening and closing sequence of one attention.
16250
+ * Otherwise attention is mixed up:
16251
+ * either sequences of different attention pair,
16252
+ * part of a sequence is used (such as `**` of strong as `*`),
16253
+ * or several sequences are used together (such as `*` and `*` as `**`).
16254
+ * Then the sequences involved are recorded with each other.
16255
+ *
16256
+ * @param {Array<Run>} runs
16257
+ * Runs.
16258
+ * @param {Map<Token, Array<Token>>} wrong
16259
+ * Sequences that are wrong, with the sequences involved.
16260
+ * @returns {undefined}
16261
+ * Nothing, `wrong` is changed.
16262
+ */
16263
+ function pair(runs, wrong) {
16264
+ /** @type {Map<string, Array<Run>>} */
16265
+ const openersByMarker = new Map();
16266
+
16267
+ for (const closer of runs) {
16268
+ const marker = closer.tokens[0].value.charAt(0);
16269
+ let openers = openersByMarker.get(marker);
16270
+
16271
+ if (!openers) {
16272
+ openers = [];
16273
+ openersByMarker.set(marker, openers);
16274
+ }
16275
+
16276
+ let open = closer.close ? openers.length : 0;
16277
+
16278
+ while (open-- && closer.start < closer.end) {
16279
+ const opener = openers[open];
16280
+ const openerSize = opener.end - opener.start;
16281
+ const closerSize = closer.end - closer.start;
16282
+
16283
+ if (
16284
+ closer.split
16285
+ ? // The rule of 3, on the sizes that are left.
16286
+ (opener.close || closer.open) &&
16287
+ closerSize % 3 &&
16288
+ !((openerSize + closerSize) % 3)
16289
+ : // Others pair whole runs of the same size.
16290
+ openerSize !== opener.markers.length || openerSize !== closerSize
16291
+ ) {
16292
+ continue
16293
+ }
16294
+
16295
+ const size = closer.split
16296
+ ? openerSize > 1 && closerSize > 1
16297
+ ? 2
16298
+ : 1
16299
+ : closerSize;
16300
+ const opening = opener.markers.slice(opener.end - size, opener.end);
16301
+ const closing = closer.markers.slice(closer.start, closer.start + size);
16302
+ const openToken = opening[0];
16303
+ const closeToken = closing[0];
16304
+
16305
+ if (
16306
+ // Whole sequences:
16307
+ // the markers of a sequence are next to each other,
16308
+ // so if the first and last marker are of one sequence of that size,
16309
+ // all markers are exactly that sequence.
16310
+ openToken === opening[size - 1] &&
16311
+ openToken.value.length === size &&
16312
+ closeToken === closing[size - 1] &&
16313
+ closeToken.value.length === size &&
16314
+ // Of the same attention, so its opening and closing sequence.
16315
+ openToken.attention === closeToken.attention
16316
+ ) {
16317
+ wrong.delete(openToken);
16318
+ wrong.delete(closeToken);
16319
+ } else {
16320
+ const involved = [...new Set([...opening, ...closing])];
16321
+ // Add to what is involved already: a sequence can be in several pairs.
16322
+ for (const token of involved) {
16323
+ const list = wrong.get(token);
16324
+ if (list) list.push(...involved);
16325
+ }
16326
+ }
16327
+
16328
+ opener.end -= size;
16329
+ closer.start += size;
16330
+
16331
+ if (opener.start === opener.end) openers.splice(open, 1);
16332
+
16333
+ // Search again from the start, as this run may close more.
16334
+ open = openers.length;
16335
+ }
16336
+
16337
+ if (closer.open && closer.start < closer.end) openers.push(closer);
16338
+ }
16339
+ }
16340
+
16341
+ /**
16342
+ * Get the sequences that can be used for attention, in order of preference.
16343
+ *
16344
+ * @param {string} type
16345
+ * Node type.
16346
+ * @param {Array<string>} markers
16347
+ * Markers.
16348
+ * @param {Array<number>} sizes
16349
+ * Sizes.
16350
+ * @returns {Array<string>}
16351
+ * Sequences.
16352
+ */
16353
+ function attentionSequences(type, markers, sizes) {
16354
+ if (markers.length === 0) {
16355
+ throw new Error(
16356
+ 'Cannot serialize `' +
16357
+ type +
16358
+ '` as attention without markers, expected one or more markers'
16359
+ )
16360
+ }
16361
+
16362
+ if (sizes.length === 0) {
16363
+ throw new Error(
16364
+ 'Cannot serialize `' +
16365
+ type +
16366
+ '` as attention without sizes, expected one or more sizes'
16367
+ )
16368
+ }
16369
+
16370
+ for (const size of sizes) {
16371
+ if (!Number.isSafeInteger(size) || size < 1) {
16372
+ throw new Error(
16373
+ 'Cannot serialize `' +
16374
+ type +
16375
+ '` as attention with `' +
16376
+ size +
16377
+ '` as size, expected positive integer'
16378
+ )
16379
+ }
16380
+ }
16381
+
16382
+ /** @type {Array<string>} */
16383
+ const sequences = [];
16384
+
16385
+ for (const marker of markers) {
16386
+ if (marker.length !== 1) {
16387
+ throw new Error(
16388
+ 'Cannot serialize `' +
16389
+ type +
16390
+ '` as attention with `' +
16391
+ marker +
16392
+ '` as marker, expected a single ascii character'
16393
+ )
16394
+ }
16395
+
16396
+ if (!asciiPunctuation(marker.charCodeAt(0))) {
16397
+ throw new Error(
16398
+ 'Cannot serialize `' +
16399
+ type +
16400
+ '` as attention with `' +
16401
+ marker +
16402
+ '` as marker, expected ascii punctuation'
16403
+ )
16404
+ }
16405
+
16406
+ for (const size of sizes) {
16407
+ sequences.push(marker.repeat(size));
16408
+ }
16409
+ }
16410
+
16411
+ return sequences
16412
+ }
16413
+
16414
+ /**
16415
+ * Serialize the children of a parent that contains phrasing children,
16416
+ * keeping attention separate,
16417
+ * so that its markers can be chosen later.
16418
+ *
16419
+ * @param {PhrasingParents} parent
16420
+ * Parent of phrasing nodes.
16421
+ * @param {State} state
16422
+ * Info passed around about the current state.
16423
+ * @param {Info} info
16424
+ * Info on where we are in the document we are generating.
16425
+ * @returns {Array<Item>}
16426
+ * Items.
16427
+ */
16428
+ function phrasing(parent, state, info) {
16429
+ const indexStack = state.indexStack;
16430
+ const children = parent.children || [];
16431
+ /** @type {Array<Item>} */
16432
+ const results = [];
16433
+ let index = -1;
16434
+ let before = info.before;
16435
+
16436
+ indexStack.push(-1);
16437
+ let tracker = state.createTracker(info);
16438
+
16439
+ while (++index < children.length) {
16440
+ const child = children[index];
16441
+ /** @type {string} */
16442
+ let after;
16443
+
16444
+ indexStack[indexStack.length - 1] = index;
16445
+
16446
+ if (index + 1 < children.length) {
16447
+ /** @type {Handle} */
16448
+ // @ts-expect-error: hush, it’s actually a `zwitch`.
16449
+ let handle = state.handle.handlers[children[index + 1].type];
16450
+ // @ts-expect-error: hush, it’s actually a `zwitch`.
16451
+ if (handle && handle.peek) handle = handle.peek;
16452
+ after = handle
16453
+ ? firstCharacter(
16454
+ handle(children[index + 1], parent, state, {
16455
+ before: '',
16456
+ after: '',
16457
+ ...tracker.current()
16458
+ })
16459
+ )
16460
+ : '';
16461
+ } else {
16462
+ after = info.after;
16463
+ }
16464
+
16465
+ // In some cases, html (text) can be found in phrasing right after an eol.
16466
+ // When we’d serialize that, it could be seen as html (flow): all its kinds
16467
+ // except 7 can interrupt a paragraph.
16468
+ // As we can’t escape or so to prevent it from happening,
16469
+ // we take a somewhat reasonable approach:
16470
+ // replace that eol with a space.
16471
+ // See: <https://github.com/syntax-tree/mdast-util-to-markdown/issues/15>
16472
+ const previous = results[results.length - 1];
16473
+
16474
+ if (
16475
+ typeof previous === 'string' &&
16476
+ (before === '\r' || before === '\n') &&
16477
+ child.type === 'html' &&
16478
+ htmlKind(child.value) !== 7
16479
+ ) {
16480
+ results[results.length - 1] = previous.replace(/(\r?\n|\r)$/, ' ');
16481
+ before = ' ';
16482
+
16483
+ // To do: does this work to reset tracker?
16484
+ tracker = state.createTracker(info);
16485
+ tracker.move(serialize(results, info.before, info.after));
16486
+ }
16487
+
16488
+ /** @type {(Handle & {attention?: Attention | undefined}) | undefined} */
16489
+ // @ts-expect-error: hush, it’s actually a `zwitch`.
16490
+ const handle = state.handle.handlers[child.type];
16491
+
16492
+ if (handle && handle.attention) {
16493
+ const item = attentionItem(
16494
+ /** @type {PhrasingParents} */ (child),
16495
+ handle.attention,
16496
+ state,
16497
+ tracker
16498
+ );
16499
+ results.push(item);
16500
+ before = lastCharacter(item.sequences[0]);
16501
+ } else {
16502
+ const value = state.handle(child, parent, state, {
16503
+ ...tracker.current(),
16504
+ after,
16505
+ before
16506
+ });
16507
+
16508
+ if (!value) continue
16509
+ tracker.move(value);
16510
+ results.push(value);
16511
+ before = lastCharacter(value);
16512
+ }
16513
+ }
16514
+
16515
+ indexStack.pop();
16516
+
16517
+ return results
16518
+ }
16519
+
16520
+ /**
16521
+ * Serialize a node as attention,
16522
+ * with its sequence chosen later.
16523
+ *
16524
+ * @param {PhrasingParents} node
16525
+ * Node.
16526
+ * @param {Attention} attention
16527
+ * Attention of the node.
16528
+ * @param {State} state
16529
+ * Info passed around about the current state.
16530
+ * @param {Tracker} tracker
16531
+ * Tracker.
16532
+ * @returns {AttentionResult}
16533
+ * Attention.
16534
+ */
16535
+ function attentionItem(node, attention, state, tracker) {
16536
+ const {construct, markers, sizes} = attention(node, state);
16537
+ const sequences = attentionSequences(node.type, markers, sizes);
16538
+ const sequence = sequences[0];
16539
+ const exit = state.enter(construct);
16540
+ tracker.move(sequence);
16541
+ const children = phrasing(node, state, {
16542
+ ...tracker.current(),
16543
+ before: sequence,
16544
+ after: sequence
16545
+ });
16546
+ tracker.move(serialize(children, sequence, sequence));
16547
+ tracker.move(sequence);
16548
+ exit();
16549
+ return {children, sequences}
16550
+ }
16551
+
16552
+ /**
16553
+ * Render items with sequences;
16554
+ * encoding characters around attention where needed.
16555
+ *
16556
+ * @param {Array<Item>} items
16557
+ * Serialized phrasing.
16558
+ * @param {Map<AttentionResult, string>} chosen
16559
+ * Sequences to use instead of preferred sequences.
16560
+ * @param {string} before
16561
+ * Characters before.
16562
+ * @param {string} after
16563
+ * Characters after.
16564
+ * @returns {Array<Token>}
16565
+ * Tokens.
16566
+ */
16567
+ function render(items, chosen, before, after) {
16568
+ /** @type {Array<Token>} */
16569
+ const tokens = [];
16570
+ /** @type {string | undefined} */
16571
+ let encodeAfter;
16572
+ let previous = lastCharacter(before);
16573
+ let index = -1;
16574
+
16575
+ while (++index < items.length) {
16576
+ const item = items[index];
16577
+
16578
+ if (typeof item === 'string') {
16579
+ /** @type {Token} */
16580
+ const token = {value: item, attention: undefined};
16581
+
16582
+ // If attention before had to encode the character after it, encode it.
16583
+ if (encodeAfter && encodeAfter === firstCharacter(item)) {
16584
+ encode([token], true);
16585
+ }
16586
+
16587
+ encodeAfter = undefined;
16588
+ tokens.push(token);
16589
+ if (token.value) previous = lastCharacter(token.value);
16590
+ continue
16591
+ }
16592
+
16593
+ const sequence = chosen.get(item) || item.sequences[0];
16594
+ const marker = sequence.charAt(0);
16595
+ const next = items[index + 1];
16596
+ const outsideBefore = previous;
16597
+ const outsideAfter = firstCharacter(
16598
+ next === undefined
16599
+ ? after
16600
+ : typeof next === 'string'
16601
+ ? next
16602
+ : chosen.get(next) || next.sequences[0]
16603
+ );
16604
+ const inside = render(item.children, chosen, sequence, sequence);
16605
+ const head = inside.length > 0 ? inside[0].value : '';
16606
+ const open = encodeInfo(
16607
+ outsideBefore.charCodeAt(outsideBefore.length - 1),
16608
+ head.charCodeAt(0),
16609
+ marker
16610
+ );
16611
+
16612
+ if (open.inside) encode(inside, true);
16613
+
16614
+ const tail =
16615
+ inside.length > 0 ? lastCharacter(inside[inside.length - 1].value) : '';
16616
+ const close = encodeInfo(
16617
+ outsideAfter.charCodeAt(0),
16618
+ tail.charCodeAt(tail.length - 1),
16619
+ marker
16620
+ );
16621
+
16622
+ if (close.inside) encode(inside, false);
16623
+
16624
+ if (open.outside && outsideBefore !== '\n' && outsideBefore !== '\r') {
16625
+ encode(tokens, false);
16626
+ }
16627
+
16628
+ if (close.outside) encodeAfter = outsideAfter;
16629
+
16630
+ tokens.push({value: sequence, attention: item}, ...inside, {
16631
+ value: sequence,
16632
+ attention: item
16633
+ });
16634
+ previous = sequence.charAt(sequence.length - 1);
16635
+ }
16636
+
16637
+ return tokens
16638
+ }
16639
+
16640
+ /**
16641
+ * Serialize phrasing with attention.
16642
+ *
16643
+ * Whether attention forms depends on everything around it.
16644
+ * This checks that it does and tries other sequences if not.
16645
+ *
16646
+ * @param {Array<Item>} items
16647
+ * Phrasing items.
16648
+ * @param {string} before
16649
+ * Characters before.
16650
+ * @param {string} after
16651
+ * Characters after.
16652
+ * @returns {string}
16653
+ * Serialized markdown.
16654
+ */
16655
+ function serialize(items, before, after) {
16656
+ /** @type {Map<AttentionResult, string>} */
16657
+ let chosen = new Map();
16658
+ const initial = render(items, chosen, before, after);
16659
+ let tokens = initial;
16660
+ let mistake = check(tokens, before, after);
16661
+
16662
+ while (mistake) {
16663
+ const next = improve(items, chosen, mistake, before, after);
16664
+
16665
+ if (!next) {
16666
+ tokens = initial;
16667
+ break
16668
+ }
16669
+
16670
+ chosen = next.chosen;
16671
+ tokens = next.tokens;
16672
+ mistake = next.mistake;
16673
+ }
16674
+
16675
+ // Join the tokens.
16676
+ let result = '';
16677
+ for (const token of tokens) result += token.value;
16678
+ return result
16679
+ }
16680
+
15748
16681
  /**
15749
16682
  * @import {AttentionInfo, Info, State} from 'mdast-util-to-markdown'
15750
16683
  * @import {Emphasis, Parents} from 'mdast'
@@ -15772,7 +16705,8 @@ emphasis.peek = peek$1;
15772
16705
  */
15773
16706
  function emphasis(node, _, state, info) {
15774
16707
  const exit = state.enter('phrasing');
15775
- const value = state.containerPhrasing({type: 'root', children: [node]}, info);
16708
+ const item = attentionItem(node, attention$1, state, state.createTracker(info));
16709
+ const value = serialize([item], info.before, info.after);
15776
16710
  exit();
15777
16711
  return value
15778
16712
  }
@@ -15812,18 +16746,6 @@ function peek$1(_, _1, state) {
15812
16746
  return state.options.emphasis || '*'
15813
16747
  }
15814
16748
 
15815
- /**
15816
- * Encode a code point as a character reference.
15817
- *
15818
- * @param {number} code
15819
- * Code point to encode.
15820
- * @returns {string}
15821
- * Encoded character reference.
15822
- */
15823
- function encodeCharacterReference(code) {
15824
- return '&#x' + code.toString(16).toUpperCase() + ';'
15825
- }
15826
-
15827
16749
  /**
15828
16750
  * @import {State} from 'mdast-util-to-markdown'
15829
16751
  * @import {Heading} from 'mdast'
@@ -16326,21 +17248,56 @@ function link(node, _, state, info) {
16326
17248
  const exit = state.enter('link');
16327
17249
  let subexit = state.enter('label');
16328
17250
  let value = tracker.move('[');
16329
- value += tracker.move(
16330
- state.containerPhrasing(node, {
16331
- before: value,
16332
- after: '](',
16333
- ...tracker.current()
16334
- })
16335
- );
16336
- value += tracker.move('](');
17251
+ const text = state.containerPhrasing(node, {
17252
+ before: value,
17253
+ after: '](',
17254
+ ...tracker.current()
17255
+ });
17256
+ value += tracker.move(text);
16337
17257
  subexit();
17258
+ value += tracker.move('](');
17259
+
17260
+ // A link could accidentally turn into a definition in certain contexts:
17261
+ // at the start of a line, without title, when its text has a `]` that
17262
+ // cannot be escaped (such as in code).
17263
+ //
17264
+ // We can prevent that with an empty title:
17265
+ //
17266
+ // ```
17267
+ // [`a]:`](b)
17268
+ // ```
17269
+ //
17270
+ // …is a definition with `` `](b) `` as its destination.
17271
+ //
17272
+ // Using:
17273
+ //
17274
+ // ```
17275
+ // [`a]:`](b "")
17276
+ // ```
17277
+ //
17278
+ // …instead fixes it.
17279
+ //
17280
+ // Control characters or whitespace in the url need an enclosed destination,
17281
+ // which also prevents this.
17282
+ const enclose = /[\0- \u007F]/.test(node.url);
17283
+ const last = info.before.charAt(info.before.length - 1);
17284
+ let title = node.title || undefined;
17285
+
17286
+ if (!title && !enclose && (last === '\n' || last === '\r')) {
17287
+ let index = 0;
17288
+
17289
+ while (index < text.length && text.charCodeAt(index) !== 93 /* `]` */) {
17290
+ index += text.charCodeAt(index) === 92 /* `\` */ ? 2 : 1;
17291
+ }
17292
+
17293
+ if (text.charCodeAt(index + 1) === 58 /* `:` */) title = '';
17294
+ }
16338
17295
 
16339
17296
  if (
16340
17297
  // If there’s no url but there is a title…
16341
- (!node.url && node.title) ||
17298
+ (!node.url && typeof title === 'string') ||
16342
17299
  // If there are control characters or whitespace.
16343
- /[\0- \u007F]/.test(node.url)
17300
+ enclose
16344
17301
  ) {
16345
17302
  subexit = state.enter('destinationLiteral');
16346
17303
  value += tracker.move('<');
@@ -16354,7 +17311,7 @@ function link(node, _, state, info) {
16354
17311
  value += tracker.move(
16355
17312
  state.safe(node.url, {
16356
17313
  before: value,
16357
- after: node.title ? ' ' : ')',
17314
+ after: typeof title === 'string' ? ' ' : ')',
16358
17315
  ...tracker.current()
16359
17316
  })
16360
17317
  );
@@ -16362,11 +17319,11 @@ function link(node, _, state, info) {
16362
17319
 
16363
17320
  subexit();
16364
17321
 
16365
- if (node.title) {
17322
+ if (typeof title === 'string') {
16366
17323
  subexit = state.enter(`title${suffix}`);
16367
17324
  value += tracker.move(' ' + quote);
16368
17325
  value += tracker.move(
16369
- state.safe(node.title, {
17326
+ state.safe(title, {
16370
17327
  before: value,
16371
17328
  after: quote,
16372
17329
  ...tracker.current()
@@ -16850,7 +17807,7 @@ function paragraph(node, _, state, info) {
16850
17807
  function root$2(node, _, state, info) {
16851
17808
  // Note: `html` nodes are ambiguous.
16852
17809
  const hasPhrasing = node.children.some(function (d) {
16853
- return phrasing(d)
17810
+ return phrasing$1(d)
16854
17811
  });
16855
17812
 
16856
17813
  if (!hasPhrasing) return state.containerFlow(node, info)
@@ -16914,7 +17871,8 @@ strong.peek = peek;
16914
17871
  */
16915
17872
  function strong(node, _, state, info) {
16916
17873
  const exit = state.enter('phrasing');
16917
- const value = state.containerPhrasing({type: 'root', children: [node]}, info);
17874
+ const item = attentionItem(node, attention, state, state.createTracker(info));
17875
+ const value = serialize([item], info.before, info.after);
16918
17876
  exit();
16919
17877
  return value
16920
17878
  }
@@ -16976,7 +17934,7 @@ function peek(_, _1, state) {
16976
17934
  function text$3(node, parent, state, info) {
16977
17935
  /* c8 ignore next -- parent always passed */
16978
17936
  const siblings = parent ? parent.children : [];
16979
- const index = siblings.indexOf(node);
17937
+ const index = state.indexStack[state.indexStack.length - 1];
16980
17938
 
16981
17939
  return state.safe(node.value, {
16982
17940
  ...info,
@@ -33850,4 +34808,4 @@ function getWhiteList(allowedComponents) {
33850
34808
  return whitelist;
33851
34809
  }
33852
34810
 
33853
- export { asciiAlpha as a, asciiAlphanumeric as b, htmlBlockNames as c, formatHeadingAsSetext as d, decodeString as e, formatCodeAsIndented as f, getLinkAttributes as g, htmlRawNames as h, classifyCharacter as i, asciiPunctuation as j, encodeCharacterReference as k, handle as l, markdownToHTML as m, phrasing as n, remarkParse as o, patternInScope as p, remarkGfm as r, sanitizeHTML as s, toString as t };
34811
+ export { formatHeadingAsSetext as a, classifyCharacter as b, checkRule as c, decodeString as d, encodeCharacterReference as e, formatCodeAsIndented as f, getLinkAttributes as g, htmlKind as h, handle as i, phrasing$1 as j, containerPhrasing as k, remarkParse as l, markdownToHTML as m, patternInScope as p, remarkGfm as r, sanitizeHTML as s, toString as t };