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