@limetech/lime-elements 40.19.0 → 40.20.1

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 (73) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cjs/keyboard-navigation-VyqkMDKy.js +152 -0
  3. package/dist/cjs/lime-elements.cjs.js +1 -1
  4. package/dist/cjs/{limel-breadcrumbs_6.cjs.entry.js → limel-badge_7.cjs.entry.js} +33 -0
  5. package/dist/cjs/limel-chart.cjs.entry.js +51371 -268
  6. package/dist/cjs/limel-markdown.cjs.entry.js +2 -2
  7. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +1 -1
  8. package/dist/cjs/limel-tab-bar.cjs.entry.js +6 -149
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/cjs/{markdown-exporter-BWS2EBxq.js → markdown-exporter-CGNfjGr9.js} +80 -897
  11. package/dist/cjs/{markdown-parser-toAp9-Eq.js → markdown-parser-C14XF_G3.js} +994 -38
  12. package/dist/collection/components/chart/chart.css +75 -924
  13. package/dist/collection/components/chart/chart.js +332 -287
  14. package/dist/collection/components/chart/options.js +568 -0
  15. package/dist/collection/components/chart/scale.js +193 -0
  16. package/dist/collection/components/chart/theme.js +145 -0
  17. package/dist/collection/components/scroller/scroller.js +1 -1
  18. package/dist/esm/keyboard-navigation-BF7IKmnG.js +147 -0
  19. package/dist/esm/{keycodes-Bu6-QXrA.js → keycodes-DQ5DmW_Y.js} +1 -1
  20. package/dist/esm/lime-elements.js +1 -1
  21. package/dist/esm/{limel-breadcrumbs_6.entry.js → limel-badge_7.entry.js} +36 -4
  22. package/dist/esm/limel-chart.entry.js +51372 -269
  23. package/dist/esm/limel-chip-set.entry.js +1 -1
  24. package/dist/esm/limel-chip_2.entry.js +1 -1
  25. package/dist/esm/limel-markdown.entry.js +2 -2
  26. package/dist/esm/limel-pagination-jump.entry.js +1 -1
  27. package/dist/esm/limel-picker.entry.js +2 -2
  28. package/dist/esm/limel-popover_2.entry.js +1 -1
  29. package/dist/esm/limel-prosemirror-adapter.entry.js +1 -1
  30. package/dist/esm/limel-resize-handle.entry.js +1 -1
  31. package/dist/esm/limel-select.entry.js +2 -2
  32. package/dist/esm/limel-side-panel.entry.js +1 -1
  33. package/dist/esm/limel-tab-bar.entry.js +2 -145
  34. package/dist/esm/limel-text-editor-link-menu.entry.js +1 -1
  35. package/dist/esm/loader.js +1 -1
  36. package/dist/esm/{markdown-exporter-B2vFxSLw.js → markdown-exporter-DcFcD699.js} +80 -897
  37. package/dist/esm/{markdown-parser-Cw8iW5R9.js → markdown-parser-8aHA9IYo.js} +991 -33
  38. package/dist/esm/{typeahead-DOlnT3wh.js → typeahead-B4PwrlM3.js} +1 -1
  39. package/dist/lime-elements/lime-elements.esm.js +1 -1
  40. package/dist/lime-elements/{p-d4702653.entry.js → p-07f3565b.entry.js} +1 -1
  41. package/dist/lime-elements/p-0887e0df.entry.js +56 -0
  42. package/dist/lime-elements/{p-0910aefc.entry.js → p-22e9e327.entry.js} +1 -1
  43. package/dist/lime-elements/{p-7bf3bf8a.entry.js → p-23067836.entry.js} +1 -1
  44. package/dist/lime-elements/{p-7f0743d6.entry.js → p-56e2fa48.entry.js} +1 -1
  45. package/dist/lime-elements/{p-af7d07fd.entry.js → p-5e408c27.entry.js} +1 -1
  46. package/dist/lime-elements/{p-843886fe.entry.js → p-7fcd48c6.entry.js} +1 -1
  47. package/dist/lime-elements/{p-1d9bc526.entry.js → p-9edd79a8.entry.js} +1 -1
  48. package/dist/lime-elements/p-C9gctvIB.js +1 -0
  49. package/dist/lime-elements/{p-fYs7n6yY.js → p-DNYOwOWu.js} +1 -1
  50. package/dist/lime-elements/{p-Bu6-QXrA.js → p-DQ5DmW_Y.js} +1 -1
  51. package/dist/lime-elements/p-_1yBt1pG.js +1 -0
  52. package/dist/lime-elements/p-a807a45f.entry.js +159 -0
  53. package/dist/lime-elements/{p-c2f993cc.entry.js → p-a891f3e8.entry.js} +1 -1
  54. package/dist/lime-elements/{p-45572e9d.entry.js → p-c8a34cef.entry.js} +1 -1
  55. package/dist/lime-elements/{p-4834e7c1.entry.js → p-cd479c23.entry.js} +1 -1
  56. package/dist/lime-elements/p-cf2d43c7.entry.js +1 -0
  57. package/dist/lime-elements/{p-94ae27e2.entry.js → p-f3b93ce8.entry.js} +2 -2
  58. package/dist/lime-elements/p-kiQd8Ntf.js +7 -0
  59. package/dist/types/components/chart/chart.d.ts +51 -52
  60. package/dist/types/components/chart/chart.types.d.ts +5 -0
  61. package/dist/types/components/chart/options.d.ts +88 -0
  62. package/dist/types/components/chart/scale.d.ts +101 -0
  63. package/dist/types/components/chart/theme.d.ts +52 -0
  64. package/dist/types/components.d.ts +7 -38
  65. package/package.json +4 -3
  66. package/dist/cjs/limel-badge.cjs.entry.js +0 -37
  67. package/dist/esm/limel-badge.entry.js +0 -35
  68. package/dist/lime-elements/p-02aac2c0.entry.js +0 -1
  69. package/dist/lime-elements/p-38ab193f.entry.js +0 -1
  70. package/dist/lime-elements/p-3ca188f6.entry.js +0 -159
  71. package/dist/lime-elements/p-Bd37Vplf.js +0 -7
  72. package/dist/lime-elements/p-CvHpvp0f.js +0 -1
  73. package/dist/lime-elements/p-f7a90228.entry.js +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-DIiA99Er.js');
4
- var markdownParser = require('./markdown-parser-toAp9-Eq.js');
4
+ var markdownParser = require('./markdown-parser-C14XF_G3.js');
5
5
  require('./_commonjsHelpers-CFO10eej.js');
6
6
 
7
7
  /**
@@ -103,67 +103,6 @@ function map(left, right) {
103
103
  }
104
104
  }
105
105
 
106
- /**
107
- * @typedef {1 | 2 | 3 | 4 | 5 | 6 | 7} Kind
108
- * Kind of HTML (flow) element.
109
- */
110
-
111
- /**
112
- * Infer the kind of HTML that `value` is.
113
- *
114
- * This works on valid trees as produced by `micromark`.
115
- * Kinds:
116
- *
117
- * 1. raw
118
- * 2. comment
119
- * 3. instruction
120
- * 4. declaration
121
- * 5. cdata
122
- * 6. block
123
- * 7. other
124
- *
125
- * See: <https://spec.commonmark.org/0.31.2/#html-blocks>.
126
- *
127
- * @param {string} value
128
- * HTML.
129
- * @returns {Kind | undefined}
130
- * Kind; `undefined` if unknown.
131
- */
132
- function htmlKind(value) {
133
- if (value.charCodeAt(0) !== 60 /* `<` */) return
134
-
135
- const next = value.charCodeAt(1);
136
-
137
- if (next === 33 /* `!` */) {
138
- const code = value.charCodeAt(2);
139
- if (code === 45 /* `-` */) return 2
140
- if (code === 91 /* `[` */) return 5
141
- if (markdownParser.asciiAlpha(code)) return 4
142
- return
143
- }
144
-
145
- if (next === 63 /* `?` */) return 3
146
-
147
- const closing = next === 47; /* `/` */
148
- const start = closing ? 2 : 1;
149
- let end = start;
150
- let code = value.charCodeAt(end);
151
-
152
- if (!markdownParser.asciiAlpha(code)) return
153
-
154
- while (code === 45 /* `-` */ || markdownParser.asciiAlphanumeric(code)) {
155
- code = value.charCodeAt(++end);
156
- }
157
-
158
- const name = value.slice(start, end).toLowerCase();
159
-
160
- if (!closing && code !== 47 /* `/` */ && markdownParser.htmlRawNames.includes(name)) {
161
- return 1
162
- }
163
-
164
- return markdownParser.htmlBlockNames.includes(name) ? 6 : 7
165
- }
166
-
167
106
  /**
168
107
  * @import {Join} from 'mdast-util-to-markdown'
169
108
  */
@@ -191,30 +130,74 @@ function joinDefaults(left, right, parent, state) {
191
130
  // Join children of a list or an item.
192
131
  // In which case, `parent` has a `spread` field.
193
132
  if ('spread' in parent && typeof parent.spread === 'boolean') {
133
+ if (parent.spread) return 1
134
+
135
+ // HTML that only ends at a blank line.
136
+ if (left.type === 'html') {
137
+ const kind = markdownParser.htmlKind(left.value);
138
+ if (kind === undefined || kind === 6 || kind === 7) return 1
139
+ }
140
+
141
+ if (left.type === 'blockquote' && right.type === 'blockquote') return 1
142
+
143
+ // Lists with non-1 start would turn into a paragraph.
144
+ if (
145
+ (left.type === 'definition' || left.type === 'paragraph') &&
146
+ right.type === 'list' &&
147
+ ((right.ordered &&
148
+ typeof right.start === 'number' &&
149
+ right.start !== 1) ||
150
+ (right.children.length > 0 && right.children[0].children.length === 0))
151
+ ) {
152
+ return 1
153
+ }
154
+
155
+ // Thematic break with dashes would turn into a setext heading.
194
156
  if (
195
157
  left.type === 'paragraph' &&
196
- // Two paragraphs.
197
- (left.type === right.type ||
198
- right.type === 'definition' ||
199
- // Paragraph followed by a setext heading.
200
- (right.type === 'heading' && markdownParser.formatHeadingAsSetext(right, state)))
158
+ right.type === 'thematicBreak' &&
159
+ markdownParser.checkRule(state) === '-' &&
160
+ !state.options.ruleSpaces
201
161
  ) {
202
- return
162
+ return 1
203
163
  }
204
164
 
205
- // HTML that only ends at a blank line followed by something.
206
- if (left.type === 'html') {
207
- const kind = htmlKind(left.value);
208
- if (kind === undefined || kind === 6 || kind === 7) return 1
165
+ // We have to “delve” into containers that form from the left margin.
166
+ let tail = left;
167
+
168
+ while (
169
+ (tail.type === 'blockquote' ||
170
+ tail.type === 'list' ||
171
+ tail.type === 'listItem') &&
172
+ tail.children.length > 0
173
+ ) {
174
+ tail = tail.children[tail.children.length - 1];
209
175
  }
210
176
 
211
- // HTML that cannot interrupt a paragraph (kind 7) after one.
212
- if (left.type === 'paragraph' && right.type === 'html') {
213
- const kind = htmlKind(right.value);
177
+ if (tail.type !== 'definition' && tail.type !== 'paragraph') return 0
178
+
179
+ // Indented code would turn into a paragraph.
180
+ if (right.type === 'code' && markdownParser.formatCodeAsIndented(right, state)) return 1
181
+
182
+ // Kind 7 HTML would turn into a paragraph.
183
+ if (right.type === 'html') {
184
+ const kind = markdownParser.htmlKind(right.value);
214
185
  if (kind === undefined || kind === 7) return 1
215
186
  }
216
187
 
217
- return parent.spread ? 1 : 0
188
+ // Text joins the paragraph before it, also one at the end of a container.
189
+ // Not a definition before it: definitions are parsed out of the start of
190
+ // a paragraph, so they and the text after them are read back the same.
191
+ if (
192
+ (left.type === 'paragraph' || left !== tail) &&
193
+ (right.type === 'definition' ||
194
+ (right.type === 'heading' && markdownParser.formatHeadingAsSetext(right, state)) ||
195
+ right.type === 'paragraph')
196
+ ) {
197
+ return 1
198
+ }
199
+
200
+ return 0
218
201
  }
219
202
  }
220
203
 
@@ -294,7 +277,22 @@ const unsafe = [
294
277
  {character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'},
295
278
  // Dollar sign and percentage are not used in markdown.
296
279
  // An ampersand could start a character reference.
297
- {character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'},
280
+ // Labels match on their source.
281
+ {
282
+ character: '&',
283
+ after: '[#A-Za-z]',
284
+ inConstruct: [
285
+ 'codeFencedLangGraveAccent',
286
+ 'codeFencedLangTilde',
287
+ 'codeFencedMetaGraveAccent',
288
+ 'codeFencedMetaTilde',
289
+ 'destinationLiteral',
290
+ 'destinationRaw',
291
+ 'phrasing',
292
+ 'titleApostrophe',
293
+ 'titleQuote'
294
+ ]
295
+ },
298
296
  // An apostrophe can break out of a title.
299
297
  {character: "'", inConstruct: 'titleApostrophe'},
300
298
  // A left paren could break out of a destination raw.
@@ -443,820 +441,6 @@ function compilePattern(pattern) {
443
441
  return pattern._compiled
444
442
  }
445
443
 
446
- /**
447
- * Get the first character of a value.
448
- *
449
- * Is aware of astral characters (such as emoji).
450
- *
451
- * @param {string} value
452
- * Value.
453
- * @returns {string}
454
- * First character; empty if `value` is empty.
455
- */
456
- function firstCharacter(value) {
457
- const code = value.codePointAt(0);
458
- return code === undefined ? '' : String.fromCodePoint(code)
459
- }
460
-
461
- /**
462
- * Get the last character of a value.
463
- *
464
- * Is aware of astral characters (such as emoji).
465
- *
466
- * @param {string} value
467
- * Value.
468
- * @returns {string}
469
- * Last character; empty if `value` is empty.
470
- */
471
- function lastCharacter(value) {
472
- // Only a surrogate pair gives a code point above the BMP.
473
- const code = value.codePointAt(value.length - 2);
474
- return code !== undefined && code > 0xff_ff
475
- ? value.slice(-2)
476
- : value.slice(-1)
477
- }
478
-
479
- /**
480
- * @import {EncodeSides} from '../types.js'
481
- */
482
-
483
-
484
- /**
485
- * Check whether to encode (as a character reference) the characters
486
- * surrounding an attention run.
487
- *
488
- * Which characters are around an attention run influence whether it works or
489
- * not.
490
- *
491
- * See <https://github.com/orgs/syntax-tree/discussions/60> for more info.
492
- * See this markdown in a particular renderer to see what works:
493
- *
494
- * ```markdown
495
- * | | A (letter inside) | B (punctuation inside) | C (whitespace inside) | D (nothing inside) |
496
- * | ----------------------- | ----------------- | ---------------------- | --------------------- | ------------------ |
497
- * | 1 (letter outside) | x*y*z | x*.*z | x* *z | x**z |
498
- * | 2 (punctuation outside) | .*y*. | .*.*. | .* *. | .**. |
499
- * | 3 (whitespace outside) | x *y* z | x *.* z | x * * z | x ** z |
500
- * | 4 (nothing outside) | *x* | *.* | * * | ** |
501
- * ```
502
- *
503
- * @param {number} outside
504
- * Code point on the outer side of the run.
505
- * @param {number} inside
506
- * Code point on the inner side of the run.
507
- * @param {string} marker
508
- * Marker of the run.
509
- * Underscores are handled more strictly (they form less often) than
510
- * asterisks.
511
- * @returns {EncodeSides}
512
- * Whether to encode characters.
513
- */
514
- // Important: punctuation must never be encoded.
515
- // Punctuation is solely used by markdown constructs.
516
- // And by encoding itself.
517
- // Encoding them will break constructs or double encode things.
518
- function encodeInfo(outside, inside, marker) {
519
- const outsideKind = markdownParser.classifyCharacter(outside);
520
- const insideKind = markdownParser.classifyCharacter(inside);
521
-
522
- // Letter outside:
523
- if (outsideKind === undefined) {
524
- return insideKind === undefined
525
- ? // Letter inside:
526
- // we have to encode *both* letters for `_` as it is looser.
527
- // it already forms for `*` (and GFMs `~`).
528
- marker === '_'
529
- ? {inside: true, outside: true}
530
- : {inside: false, outside: false}
531
- : insideKind === 1
532
- ? // Whitespace inside: encode both (letter, whitespace).
533
- {inside: true, outside: true}
534
- : // Punctuation inside: encode outer (letter)
535
- {inside: false, outside: true}
536
- }
537
-
538
- // Whitespace outside:
539
- if (outsideKind === 1) {
540
- return insideKind === undefined
541
- ? // Letter inside: already forms.
542
- {inside: false, outside: false}
543
- : insideKind === 1
544
- ? // Whitespace inside: encode both (whitespace).
545
- {inside: true, outside: true}
546
- : // Punctuation inside: already forms.
547
- {inside: false, outside: false}
548
- }
549
-
550
- // Punctuation outside:
551
- return insideKind === undefined
552
- ? // Letter inside: already forms.
553
- {inside: false, outside: false}
554
- : insideKind === 1
555
- ? // Whitespace inside: encode inner (whitespace).
556
- {inside: true, outside: false}
557
- : // Punctuation inside: already forms.
558
- {inside: false, outside: false}
559
- }
560
-
561
- /**
562
- * @import {Attention, Handle, Info, State} from 'mdast-util-to-markdown'
563
- * @import {PhrasingParents} from '../types.js'
564
- */
565
-
566
-
567
- /**
568
- * Markers for builtin attention (emphasis, strong) to whether they are stricter:
569
- * whether they cannot open and close inside words.
570
- *
571
- * Builtin runs pair following CommonMark rules for emphasis and strong:
572
- * they are split,
573
- * using one or two markers at a time,
574
- * with the rule of 3.
575
- * Other markers pair like GFM strikethrough:
576
- * whole runs pair with a run of the same size.
577
- *
578
- * @type {Map<string, boolean>}
579
- */
580
- const builtins = new Map([
581
- ['*', false],
582
- ['_', true]
583
- ]);
584
-
585
- /**
586
- * @typedef AttentionResult
587
- * Attention, of which the sequence is chosen later.
588
- * @property {Array<Item>} children
589
- * Serialized children.
590
- * @property {Array<string>} sequences
591
- * Sequences that can be used, in order of preference.
592
- */
593
-
594
- /**
595
- * @typedef Improvement
596
- * Improvement of attention sequences.
597
- * @property {Map<AttentionResult, string>} chosen
598
- * Chosen sequences for each attention.
599
- * @property {Array<Token>} tokens
600
- * Tokens involved in the improvement.
601
- * @property {Mistake | undefined} mistake
602
- * Mistake that led to this improvement, if any.
603
- */
604
-
605
- /**
606
- * @typedef {AttentionResult | string} Item
607
- * Serialized phrasing.
608
- */
609
-
610
- /**
611
- * @typedef Mistake
612
- * Sequence that does not form its attention.
613
- * @property {Array<AttentionResult>} attention
614
- * Attention to try other sequences for.
615
- * @property {number} index
616
- * Index of the token.
617
- */
618
-
619
- /**
620
- * @typedef Run
621
- * Sequences next to each other with the same marker.
622
- * @property {boolean} close
623
- * Whether it can close.
624
- * @property {number} end
625
- * Index after the last marker not used (to open).
626
- * @property {Array<Token>} markers
627
- * Sequence of each marker.
628
- * @property {boolean} open
629
- * Whether it can open.
630
- * @property {boolean} split
631
- * Whether it can be split (built-in attention).
632
- * @property {number} start
633
- * Index of the first marker not used (to close).
634
- * @property {Array<Token>} tokens
635
- * Sequences.
636
- */
637
-
638
- /**
639
- * @typedef Token
640
- * Rendered phrasing.
641
- * @property {AttentionResult | undefined} attention
642
- * Attention, if this is one of its sequences.
643
- * @property {string} value
644
- * Value.
645
- */
646
-
647
- /**
648
- * Get candidates for a mistake:
649
- * attention to try other sequences for,
650
- * later first.
651
- *
652
- * @param {Array<Token>} tokens
653
- * Tokens.
654
- * @param {Array<Token>} involved
655
- * Sequences involved in the mistake.
656
- * @param {Map<Token, Run>} runOf
657
- * Run of each sequence.
658
- * @returns {Array<AttentionResult>}
659
- * Candidates.
660
- */
661
- function candidates(tokens, involved, runOf) {
662
- /** @type {Set<AttentionResult | undefined>} */
663
- const related = new Set();
664
-
665
- // The attention involved, and attention in runs with its sequences.
666
- for (const token of tokens) {
667
- const siblings = runOf.get(token);
668
- if (
669
- siblings &&
670
- token.attention &&
671
- involved.some((d) => d.attention === token.attention)
672
- ) {
673
- for (const sibling of siblings.tokens) {
674
- related.add(sibling.attention);
675
- }
676
- }
677
- }
678
-
679
- /** @type {Array<AttentionResult>} */
680
- const ordered = [];
681
-
682
- for (const token of tokens) {
683
- if (token.attention && related.delete(token.attention)) {
684
- ordered.push(token.attention);
685
- }
686
- }
687
-
688
- // Later first: attention that opens later is inner or next.
689
- ordered.reverse();
690
- return ordered
691
- }
692
-
693
- /**
694
- * Check whether sequences form their attention, like `micromark`.
695
- *
696
- * Sequences of `*` and `_` pair like emphasis and strong in CommonMark,
697
- * others like strikethrough in GFM.
698
- *
699
- * @param {Array<Token>} tokens
700
- * Tokens.
701
- * @param {string} before
702
- * Characters before.
703
- * @param {string} after
704
- * Characters after.
705
- * @returns {Mistake | undefined}
706
- * First mistake, if any.
707
- */
708
- function check(tokens, before, after) {
709
- /** @type {Array<Run>} */
710
- const runs = [];
711
- /** @type {Map<Token, Array<Token>>} */
712
- const wrong = new Map();
713
- /** @type {Map<Token, Run>} */
714
- const runOf = new Map();
715
- let index = 0;
716
-
717
- while (index < tokens.length) {
718
- if (!tokens[index].attention) {
719
- index++;
720
- continue
721
- }
722
-
723
- const marker = tokens[index].value.charAt(0);
724
- const strict = builtins.get(marker);
725
- let end = index + 1;
726
-
727
- while (
728
- end < tokens.length &&
729
- tokens[end].attention &&
730
- tokens[end].value.charAt(0) === marker
731
- ) {
732
- end++;
733
- }
734
-
735
- const head = index ? tokens[index - 1].value : before;
736
- const previous = markdownParser.classifyCharacter(head.charCodeAt(head.length - 1));
737
- const next = markdownParser.classifyCharacter(
738
- (end < tokens.length ? tokens[end].value : after).charCodeAt(0)
739
- );
740
- const open = !next || (next === 2 && Boolean(previous));
741
- const close = !previous || (previous === 2 && Boolean(next));
742
- /** @type {Run} */
743
- const run = {
744
- tokens: tokens.slice(index, end),
745
- markers: [],
746
- start: 0,
747
- end: 0,
748
- // Underscores are strict, they cannot open or close inside words.
749
- open: strict ? open && (Boolean(previous) || !close) : open,
750
- close: strict ? close && (Boolean(next) || !open) : close,
751
- // All builtins can split runs.
752
- split: strict !== undefined
753
- };
754
-
755
- for (const token of run.tokens) {
756
- // Every sequence is wrong until it pairs with its other sequence.
757
- wrong.set(token, [...run.tokens]);
758
- runOf.set(token, run);
759
- let size = token.value.length;
760
- while (size--) run.markers.push(token);
761
- }
762
-
763
- run.end = run.markers.length;
764
- runs.push(run);
765
- index = end;
766
- }
767
-
768
- pair(runs, wrong);
769
-
770
- index = -1;
771
-
772
- while (++index < tokens.length) {
773
- const involved = wrong.get(tokens[index]);
774
- if (involved) return {attention: candidates(tokens, involved, runOf), index}
775
- }
776
- }
777
-
778
- /**
779
- * Serialize the children of a parent that contains phrasing children.
780
- *
781
- * @param {PhrasingParents} parent
782
- * Parent of phrasing nodes.
783
- * @param {State} state
784
- * Info passed around about the current state.
785
- * @param {Info} info
786
- * Info on where we are in the document we are generating.
787
- * @returns {string}
788
- * Serialized result.
789
- */
790
- function containerPhrasing(parent, state, info) {
791
- return serialize(phrasing$2(parent, state, info), info.before, info.after)
792
- }
793
-
794
- /**
795
- * Encode the first or last character of tokens as a character reference,
796
- * if it is text.
797
- *
798
- * @param {Array<Token>} tokens
799
- * Tokens.
800
- * @param {boolean} start
801
- * Whether to encode the first or last character.
802
- * @returns {undefined}
803
- * Nothing.
804
- */
805
- function encode(tokens, start) {
806
- const token = tokens[start ? 0 : tokens.length - 1];
807
-
808
- if (!token || token.attention) return
809
-
810
- const character = start
811
- ? firstCharacter(token.value)
812
- : lastCharacter(token.value);
813
- const reference = markdownParser.encodeCharacterReference(
814
- /** @type {number} */ (character.codePointAt(0))
815
- );
816
-
817
- token.value = start
818
- ? reference + token.value.slice(character.length)
819
- : token.value.slice(0, token.value.length - character.length) + reference;
820
- }
821
-
822
- /**
823
- * Try other sequences for the candidates of a mistake and use the first that
824
- * moves the mistake further.
825
- *
826
- * @param {Array<Item>} items
827
- * Items.
828
- * @param {Map<AttentionResult, string>} chosen
829
- * Sequences to use instead of preferred sequences.
830
- * @param {Mistake} mistake
831
- * Mistake.
832
- * @param {string} before
833
- * Characters before.
834
- * @param {string} after
835
- * Characters after.
836
- * @returns {Improvement | undefined}
837
- * Result if better.
838
- */
839
- function improve(items, chosen, mistake, before, after) {
840
- for (const attention of mistake.attention) {
841
- const current = chosen.get(attention) || attention.sequences[0];
842
-
843
- for (const sequence of attention.sequences) {
844
- if (sequence === current) continue
845
- const trial = new Map(chosen);
846
- trial.set(attention, sequence);
847
- const tokens = render(items, trial, before, after);
848
- const next = check(tokens, before, after);
849
-
850
- if (!next || next.index > mistake.index) {
851
- return {chosen: trial, mistake: next, tokens}
852
- }
853
- }
854
- }
855
- }
856
-
857
- /**
858
- * Pair runs like `micromark` and mark sequences that do form their attention
859
- * as fine.
860
- *
861
- * Each pair uses markers from the end of an opener and the start of a closer.
862
- * It forms the intended attention if those markers are exactly the whole
863
- * opening and closing sequence of one attention.
864
- * Otherwise attention is mixed up:
865
- * either sequences of different attention pair,
866
- * part of a sequence is used (such as `**` of strong as `*`),
867
- * or several sequences are used together (such as `*` and `*` as `**`).
868
- * Then the sequences involved are recorded with each other.
869
- *
870
- * @param {Array<Run>} runs
871
- * Runs.
872
- * @param {Map<Token, Array<Token>>} wrong
873
- * Sequences that are wrong, with the sequences involved.
874
- * @returns {undefined}
875
- * Nothing, `wrong` is changed.
876
- */
877
- function pair(runs, wrong) {
878
- let index = 0;
879
-
880
- while (index < runs.length) {
881
- const closer = runs[index];
882
- const marker = closer.tokens[0].value.charAt(0);
883
- const closerSize = closer.end - closer.start;
884
- let open = closer.close && closerSize ? index : 0;
885
-
886
- while (open--) {
887
- const opener = runs[open];
888
- const openerSize = opener.end - opener.start;
889
-
890
- if (
891
- opener.tokens[0].value.charAt(0) === marker &&
892
- opener.open &&
893
- openerSize &&
894
- (closer.split
895
- ? // The rule of 3, on the sizes that are left.
896
- !((opener.close || closer.open) && closerSize % 3) ||
897
- (openerSize + closerSize) % 3
898
- : // Others pair whole runs of the same size.
899
- openerSize === opener.markers.length && openerSize === closerSize)
900
- ) {
901
- const size = closer.split
902
- ? openerSize > 1 && closerSize > 1
903
- ? 2
904
- : 1
905
- : closerSize;
906
- const opening = opener.markers.slice(opener.end - size, opener.end);
907
- const closing = closer.markers.slice(closer.start, closer.start + size);
908
- const openToken = opening[0];
909
- const closeToken = closing[0];
910
-
911
- if (
912
- // Whole sequences:
913
- // the markers of a sequence are next to each other,
914
- // so if the first and last marker are of one sequence of that size,
915
- // all markers are exactly that sequence.
916
- openToken === opening[size - 1] &&
917
- openToken.value.length === size &&
918
- closeToken === closing[size - 1] &&
919
- closeToken.value.length === size &&
920
- // Of the same attention, so its opening and closing sequence.
921
- openToken.attention === closeToken.attention
922
- ) {
923
- wrong.delete(openToken);
924
- wrong.delete(closeToken);
925
- } else {
926
- const involved = [...new Set([...opening, ...closing])];
927
- // Add to what is involved already: a sequence can be in several pairs.
928
- for (const token of involved) {
929
- const list = wrong.get(token);
930
- if (list) list.push(...involved);
931
- }
932
- }
933
-
934
- opener.end -= size;
935
- closer.start += size;
936
- break
937
- }
938
- }
939
-
940
- // Stay on this run if it can close more.
941
- if (open === -1 || closer.start === closer.end) index++;
942
- }
943
- }
944
-
945
- /**
946
- * Get the sequences that can be used for attention, in order of preference.
947
- *
948
- * @param {string} type
949
- * Node type.
950
- * @param {Array<string>} markers
951
- * Markers.
952
- * @param {Array<number>} sizes
953
- * Sizes.
954
- * @returns {Array<string>}
955
- * Sequences.
956
- */
957
- function attentionSequences(type, markers, sizes) {
958
- if (markers.length === 0) {
959
- throw new Error(
960
- 'Cannot serialize `' +
961
- type +
962
- '` as attention without markers, expected one or more markers'
963
- )
964
- }
965
-
966
- if (sizes.length === 0) {
967
- throw new Error(
968
- 'Cannot serialize `' +
969
- type +
970
- '` as attention without sizes, expected one or more sizes'
971
- )
972
- }
973
-
974
- for (const size of sizes) {
975
- if (!Number.isSafeInteger(size) || size < 1) {
976
- throw new Error(
977
- 'Cannot serialize `' +
978
- type +
979
- '` as attention with `' +
980
- size +
981
- '` as size, expected positive integer'
982
- )
983
- }
984
- }
985
-
986
- /** @type {Array<string>} */
987
- const sequences = [];
988
-
989
- for (const marker of markers) {
990
- if (marker.length !== 1) {
991
- throw new Error(
992
- 'Cannot serialize `' +
993
- type +
994
- '` as attention with `' +
995
- marker +
996
- '` as marker, expected a single ascii character'
997
- )
998
- }
999
-
1000
- if (!markdownParser.asciiPunctuation(marker.charCodeAt(0))) {
1001
- throw new Error(
1002
- 'Cannot serialize `' +
1003
- type +
1004
- '` as attention with `' +
1005
- marker +
1006
- '` as marker, expected ascii punctuation'
1007
- )
1008
- }
1009
-
1010
- for (const size of sizes) {
1011
- sequences.push(marker.repeat(size));
1012
- }
1013
- }
1014
-
1015
- return sequences
1016
- }
1017
-
1018
- /**
1019
- * Serialize the children of a parent that contains phrasing children,
1020
- * keeping attention separate,
1021
- * so that its markers can be chosen later.
1022
- *
1023
- * @param {PhrasingParents} parent
1024
- * Parent of phrasing nodes.
1025
- * @param {State} state
1026
- * Info passed around about the current state.
1027
- * @param {Info} info
1028
- * Info on where we are in the document we are generating.
1029
- * @returns {Array<Item>}
1030
- * Items.
1031
- */
1032
- function phrasing$2(parent, state, info) {
1033
- const indexStack = state.indexStack;
1034
- const children = parent.children || [];
1035
- /** @type {Array<Item>} */
1036
- const results = [];
1037
- let index = -1;
1038
- let before = info.before;
1039
-
1040
- indexStack.push(-1);
1041
- let tracker = state.createTracker(info);
1042
-
1043
- while (++index < children.length) {
1044
- const child = children[index];
1045
- /** @type {string} */
1046
- let after;
1047
-
1048
- indexStack[indexStack.length - 1] = index;
1049
-
1050
- if (index + 1 < children.length) {
1051
- /** @type {Handle} */
1052
- // @ts-expect-error: hush, it’s actually a `zwitch`.
1053
- let handle = state.handle.handlers[children[index + 1].type];
1054
- // @ts-expect-error: hush, it’s actually a `zwitch`.
1055
- if (handle && handle.peek) handle = handle.peek;
1056
- after = handle
1057
- ? firstCharacter(
1058
- handle(children[index + 1], parent, state, {
1059
- before: '',
1060
- after: '',
1061
- ...tracker.current()
1062
- })
1063
- )
1064
- : '';
1065
- } else {
1066
- after = info.after;
1067
- }
1068
-
1069
- // In some cases, html (text) can be found in phrasing right after an eol.
1070
- // When we’d serialize that, it could be seen as html (flow): all its kinds
1071
- // except 7 can interrupt a paragraph.
1072
- // As we can’t escape or so to prevent it from happening,
1073
- // we take a somewhat reasonable approach:
1074
- // replace that eol with a space.
1075
- // See: <https://github.com/syntax-tree/mdast-util-to-markdown/issues/15>
1076
- const previous = results[results.length - 1];
1077
-
1078
- if (
1079
- typeof previous === 'string' &&
1080
- (before === '\r' || before === '\n') &&
1081
- child.type === 'html' &&
1082
- htmlKind(child.value) !== 7
1083
- ) {
1084
- results[results.length - 1] = previous.replace(/(\r?\n|\r)$/, ' ');
1085
- before = ' ';
1086
-
1087
- // To do: does this work to reset tracker?
1088
- tracker = state.createTracker(info);
1089
- tracker.move(serialize(results, info.before, info.after));
1090
- }
1091
-
1092
- /** @type {(Handle & {attention?: Attention | undefined}) | undefined} */
1093
- // @ts-expect-error: hush, it’s actually a `zwitch`.
1094
- const handle = state.handle.handlers[child.type];
1095
-
1096
- if (handle && handle.attention) {
1097
- const {construct, markers, sizes} = handle.attention(child, state);
1098
- const sequences = attentionSequences(child.type, markers, sizes);
1099
- const sequence = sequences[0];
1100
- const exit = state.enter(construct);
1101
- tracker.move(sequence);
1102
- const inside = phrasing$2(/** @type {PhrasingParents} */ (child), state, {
1103
- ...tracker.current(),
1104
- before: sequence,
1105
- after: sequence
1106
- });
1107
- tracker.move(serialize(inside, sequence, sequence));
1108
- tracker.move(sequence);
1109
- exit();
1110
- results.push({children: inside, sequences});
1111
- before = sequence.charAt(sequence.length - 1);
1112
- } else {
1113
- const value = state.handle(child, parent, state, {
1114
- ...tracker.current(),
1115
- after,
1116
- before
1117
- });
1118
-
1119
- if (!value) continue
1120
- tracker.move(value);
1121
- results.push(value);
1122
- before = lastCharacter(value);
1123
- }
1124
- }
1125
-
1126
- indexStack.pop();
1127
-
1128
- return results
1129
- }
1130
-
1131
- /**
1132
- * Render items with sequences;
1133
- * encoding characters around attention where needed.
1134
- *
1135
- * @param {Array<Item>} items
1136
- * Serialized phrasing.
1137
- * @param {Map<AttentionResult, string>} chosen
1138
- * Sequences to use instead of preferred sequences.
1139
- * @param {string} before
1140
- * Characters before.
1141
- * @param {string} after
1142
- * Characters after.
1143
- * @returns {Array<Token>}
1144
- * Tokens.
1145
- */
1146
- function render(items, chosen, before, after) {
1147
- /** @type {Array<Token>} */
1148
- const tokens = [];
1149
- /** @type {string | undefined} */
1150
- let encodeAfter;
1151
- let previous = lastCharacter(before);
1152
- let index = -1;
1153
-
1154
- while (++index < items.length) {
1155
- const item = items[index];
1156
-
1157
- if (typeof item === 'string') {
1158
- /** @type {Token} */
1159
- const token = {value: item, attention: undefined};
1160
-
1161
- // If attention before had to encode the character after it, encode it.
1162
- if (encodeAfter && encodeAfter === firstCharacter(item)) {
1163
- encode([token], true);
1164
- }
1165
-
1166
- encodeAfter = undefined;
1167
- tokens.push(token);
1168
- if (token.value) previous = lastCharacter(token.value);
1169
- continue
1170
- }
1171
-
1172
- const sequence = chosen.get(item) || item.sequences[0];
1173
- const marker = sequence.charAt(0);
1174
- const next = items[index + 1];
1175
- const outsideBefore = previous;
1176
- const outsideAfter = firstCharacter(
1177
- next === undefined
1178
- ? after
1179
- : typeof next === 'string'
1180
- ? next
1181
- : chosen.get(next) || next.sequences[0]
1182
- );
1183
- const inside = render(item.children, chosen, sequence, sequence);
1184
- const head = inside.length > 0 ? inside[0].value : '';
1185
- const open = encodeInfo(
1186
- outsideBefore.charCodeAt(outsideBefore.length - 1),
1187
- head.charCodeAt(0),
1188
- marker
1189
- );
1190
-
1191
- if (open.inside) encode(inside, true);
1192
-
1193
- const tail =
1194
- inside.length > 0 ? lastCharacter(inside[inside.length - 1].value) : '';
1195
- const close = encodeInfo(
1196
- outsideAfter.charCodeAt(0),
1197
- tail.charCodeAt(tail.length - 1),
1198
- marker
1199
- );
1200
-
1201
- if (close.inside) encode(inside, false);
1202
-
1203
- if (open.outside && outsideBefore !== '\n' && outsideBefore !== '\r') {
1204
- encode(tokens, false);
1205
- }
1206
-
1207
- if (close.outside) encodeAfter = outsideAfter;
1208
-
1209
- tokens.push({value: sequence, attention: item}, ...inside, {
1210
- value: sequence,
1211
- attention: item
1212
- });
1213
- previous = sequence.charAt(sequence.length - 1);
1214
- }
1215
-
1216
- return tokens
1217
- }
1218
-
1219
- /**
1220
- * Serialize phrasing with attention.
1221
- *
1222
- * Whether attention forms depends on everything around it.
1223
- * This checks that it does and tries other sequences if not.
1224
- *
1225
- * @param {Array<Item>} items
1226
- * Phrasing items.
1227
- * @param {string} before
1228
- * Characters before.
1229
- * @param {string} after
1230
- * Characters after.
1231
- * @returns {string}
1232
- * Serialized markdown.
1233
- */
1234
- function serialize(items, before, after) {
1235
- /** @type {Map<AttentionResult, string>} */
1236
- let chosen = new Map();
1237
- const initial = render(items, chosen, before, after);
1238
- let tokens = initial;
1239
- let mistake = check(tokens, before, after);
1240
-
1241
- while (mistake) {
1242
- const next = improve(items, chosen, mistake, before, after);
1243
-
1244
- if (!next) {
1245
- tokens = initial;
1246
- break
1247
- }
1248
-
1249
- chosen = next.chosen;
1250
- tokens = next.tokens;
1251
- mistake = next.mistake;
1252
- }
1253
-
1254
- // Join the tokens.
1255
- let result = '';
1256
- for (const token of tokens) result += token.value;
1257
- return result
1258
- }
1259
-
1260
444
  /**
1261
445
  * @import {State} from 'mdast-util-to-markdown'
1262
446
  * @import {FlowChildren, FlowParents, TrackFields} from '../types.js'
@@ -1537,7 +721,8 @@ function safe(state, input, config) {
1537
721
  infos[position].after &&
1538
722
  !infos[position + 1].before &&
1539
723
  !infos[position + 1].after) ||
1540
- (positions[index - 1] === position - 1 &&
724
+ (position - 1 >= offset &&
725
+ positions[index - 1] === position - 1 &&
1541
726
  infos[position].before &&
1542
727
  !infos[position - 1].before &&
1543
728
  !infos[position - 1].after)
@@ -1553,7 +738,7 @@ function safe(state, input, config) {
1553
738
  result.push(percentEncode ? slice : escapeBackslashes(slice, '\\'));
1554
739
  }
1555
740
 
1556
- start = position;
741
+ start = position + 1;
1557
742
 
1558
743
  // Percent-encoding such as `%20`.
1559
744
  if (percentEncode) {
@@ -1561,17 +746,15 @@ function safe(state, input, config) {
1561
746
  '%' +
1562
747
  value.charCodeAt(position).toString(16).toUpperCase().padStart(2, '0')
1563
748
  );
1564
- start++;
1565
749
  } else if (
1566
750
  /[!-/:-@[-`{-~]/.test(value.charAt(position)) &&
1567
751
  (!config.encode || !config.encode.includes(value.charAt(position)))
1568
752
  ) {
1569
753
  // Character escape.
1570
- result.push('\\');
754
+ result.push('\\' + value.charAt(position));
1571
755
  } else {
1572
756
  // Character reference.
1573
757
  result.push(markdownParser.encodeCharacterReference(value.charCodeAt(position)));
1574
- start++;
1575
758
  }
1576
759
  }
1577
760
 
@@ -1859,7 +1042,7 @@ function joinDefinition(left, right) {
1859
1042
  * Serialized children, joined together.
1860
1043
  */
1861
1044
  function containerPhrasingBound(parent, info) {
1862
- return containerPhrasing(parent, this, info)
1045
+ return markdownParser.containerPhrasing(parent, this, info)
1863
1046
  }
1864
1047
 
1865
1048
  /**