@agentshouse/mdruntime 0.1.0-cb9c79aee537a → 0.1.0-cc5745cd9af96
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/dist/adapter.d.ts +13 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/change-set.d.ts +5 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -1
- package/dist/chat/list.d.ts +2 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +7 -3
- package/dist/chat/message.d.ts +1 -0
- package/dist/chat/message.d.ts.map +1 -1
- package/dist/chat/message.js +12 -2
- package/dist/chat/messages.d.ts +2 -0
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +52 -20
- package/dist/chat/overlay.d.ts +1 -0
- package/dist/chat/overlay.d.ts.map +1 -1
- package/dist/chat/overlay.js +10 -0
- package/dist/chat/pieces.d.ts +13 -2
- package/dist/chat/pieces.d.ts.map +1 -1
- package/dist/chat/pieces.js +397 -84
- package/dist/chat/provider.d.ts +1 -0
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +13 -3
- package/dist/chat/ready.d.ts +1 -1
- package/dist/chat/ready.d.ts.map +1 -1
- package/dist/chat/ready.js +1 -1
- package/dist/chat/steady.d.ts +3 -0
- package/dist/chat/steady.d.ts.map +1 -0
- package/dist/chat/steady.js +26 -0
- package/dist/chat.d.ts +1 -1
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +45 -30
- package/dist/conversation.d.ts +6 -0
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +36 -1
- package/dist/host.d.ts +1 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +1 -1
- package/dist/overlay.d.ts +3 -4
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +178 -141
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +4 -2
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +34 -15
- package/dist/replica.d.ts +2 -1
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +18 -15
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +8 -9
- package/dist/save.d.ts +1 -1
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +154 -92
- package/dist/shared.d.ts +1 -0
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +5 -1
- package/dist/store.d.ts +2 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +387 -339
- package/dist/turn.d.ts +1 -1
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +4 -4
- package/package.json +2 -2
package/dist/chat/pieces.js
CHANGED
|
@@ -36,6 +36,11 @@ const PUNCTUATION = /[\p{P}\p{S}]/u;
|
|
|
36
36
|
const ESCAPABLE = /[!-/:-@[-`{-~]/;
|
|
37
37
|
const TAG_START = /[A-Za-z!?/]/;
|
|
38
38
|
const LINE_ENDING = /\r\n?|\n/g;
|
|
39
|
+
const QUOTE_MARKER = /^ {0,3}> ?/;
|
|
40
|
+
const MARKER = /^(?:[-+*]|\d{1,9}[.)])/;
|
|
41
|
+
const TASK = /^\[[ \txX]\]/;
|
|
42
|
+
const NOTE = /^\[\^(?:[^\\\]]|\\.){1,999}\]:/;
|
|
43
|
+
const SPACES = /^[ \t]*$/;
|
|
39
44
|
const START = {
|
|
40
45
|
fence: null,
|
|
41
46
|
list: null,
|
|
@@ -288,11 +293,12 @@ export function longOf(text) {
|
|
|
288
293
|
anchors,
|
|
289
294
|
candidates,
|
|
290
295
|
pieces: [],
|
|
291
|
-
next: { start: 0, path: [], join: '', carry: '' },
|
|
296
|
+
next: { start: 0, path: [], join: '', carry: '', levels: [] },
|
|
292
297
|
urls: new Map(),
|
|
293
298
|
spans: new Map(),
|
|
294
299
|
discoveries: new Map(),
|
|
295
300
|
regions: new Map(),
|
|
301
|
+
spreads: new Map(),
|
|
296
302
|
};
|
|
297
303
|
}
|
|
298
304
|
function offsetOf(node) {
|
|
@@ -328,6 +334,7 @@ function windowOf(long, from, end, prefix) {
|
|
|
328
334
|
lead,
|
|
329
335
|
prefix,
|
|
330
336
|
carry: from.carry,
|
|
337
|
+
levels: from.levels,
|
|
331
338
|
nodes,
|
|
332
339
|
defined: definedIn(nodes, from.start - lead),
|
|
333
340
|
};
|
|
@@ -344,16 +351,15 @@ function spanned(long, anchor, stop) {
|
|
|
344
351
|
function discovered(long, anchor, stop) {
|
|
345
352
|
let discovery = long.discoveries.get(anchor);
|
|
346
353
|
if (discovery === undefined) {
|
|
347
|
-
discovery = { found: [], next: { start: anchor, path: [], join: '', carry: '' } };
|
|
354
|
+
discovery = { found: [], next: { start: anchor, path: [], join: '', carry: '', levels: [] } };
|
|
348
355
|
long.discoveries.set(anchor, discovery);
|
|
349
356
|
}
|
|
350
357
|
while (discovery.next !== null && discovery.next.start < stop) {
|
|
351
358
|
const from = discovery.next;
|
|
352
|
-
const {
|
|
359
|
+
const { pane, cut } = cutWindow(long, from, 'discover', (end) => windowOf(long, from, end, ''));
|
|
353
360
|
const end = cut?.at ?? long.text.length;
|
|
354
|
-
discovery.found.push(...
|
|
355
|
-
discovery.next =
|
|
356
|
-
cut === null ? null : { start: cut.at, path: cut.path, join: cut.join, carry: cut.carry };
|
|
361
|
+
discovery.found.push(...pane.defined.filter((one) => one.at < end));
|
|
362
|
+
discovery.next = cut === null ? null : nextOf(cut);
|
|
357
363
|
}
|
|
358
364
|
return discovery.found;
|
|
359
365
|
}
|
|
@@ -420,10 +426,10 @@ function renderWindow(long, from, end) {
|
|
|
420
426
|
long.urls.set(key, url);
|
|
421
427
|
known.push(key);
|
|
422
428
|
}
|
|
423
|
-
const
|
|
429
|
+
const pane = windowOf(long, from, end, prefixOf(known));
|
|
424
430
|
const later = [];
|
|
425
431
|
for (const key of deferred) {
|
|
426
|
-
const native =
|
|
432
|
+
const native = pane.defined.find((one) => one.key === key);
|
|
427
433
|
if (native !== undefined) {
|
|
428
434
|
long.urls.set(key, native.url);
|
|
429
435
|
continue;
|
|
@@ -434,7 +440,7 @@ function renderWindow(long, from, end) {
|
|
|
434
440
|
long.urls.set(key, url);
|
|
435
441
|
later.push(key);
|
|
436
442
|
}
|
|
437
|
-
return later.length === 0 ?
|
|
443
|
+
return later.length === 0 ? pane : windowOf(long, from, end, prefixOf([...known, ...later]));
|
|
438
444
|
}
|
|
439
445
|
function windowEnd(long, start, size) {
|
|
440
446
|
const at = start + size;
|
|
@@ -443,19 +449,209 @@ function windowEnd(long, start, size) {
|
|
|
443
449
|
const end = lineEnd(long.starts, long.text, lineOf(long, at));
|
|
444
450
|
return end - at <= VIEW_CHARS ? Math.min(end + 1, long.text.length) : at;
|
|
445
451
|
}
|
|
446
|
-
function
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
452
|
+
function nextOf(cut) {
|
|
453
|
+
return { start: cut.at, path: cut.path, join: cut.join, carry: cut.carry, levels: cut.levels };
|
|
454
|
+
}
|
|
455
|
+
function quotesOf(levels) {
|
|
456
|
+
return levels.filter((level) => level.kind === 'quote').length;
|
|
457
|
+
}
|
|
458
|
+
function itemed(levels) {
|
|
459
|
+
return levels.some((level) => level.kind !== 'quote');
|
|
460
|
+
}
|
|
461
|
+
function stepsOf(levels) {
|
|
462
|
+
return levels.flatMap((level) => level.kind === 'quote'
|
|
463
|
+
? ['blockquote']
|
|
464
|
+
: level.kind === 'item'
|
|
465
|
+
? ['list', 'item']
|
|
466
|
+
: ['footnote']);
|
|
467
|
+
}
|
|
468
|
+
function carryOf(levels) {
|
|
469
|
+
return levels.map((level) => level.carry).join('');
|
|
470
|
+
}
|
|
471
|
+
function columnOn(long, index, levels) {
|
|
472
|
+
const raw = lineText(long.starts, long.text, index);
|
|
473
|
+
let at = 0;
|
|
474
|
+
for (const level of levels) {
|
|
475
|
+
if (level.line === index) {
|
|
476
|
+
at = level.column;
|
|
477
|
+
if (at < 0)
|
|
478
|
+
return -1;
|
|
479
|
+
}
|
|
480
|
+
else if (level.kind === 'quote') {
|
|
481
|
+
const marker = QUOTE_MARKER.exec(raw.slice(at));
|
|
482
|
+
if (marker === null)
|
|
483
|
+
return -1;
|
|
484
|
+
at += marker[0].length;
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
for (let column = 0; column < level.size; column += 1) {
|
|
488
|
+
if (raw[at + column] !== ' ')
|
|
489
|
+
return -1;
|
|
490
|
+
}
|
|
491
|
+
at += level.size;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return at;
|
|
495
|
+
}
|
|
496
|
+
function withinOf(raw, levels) {
|
|
497
|
+
let rest = raw;
|
|
498
|
+
for (const [index, level] of levels.entries()) {
|
|
499
|
+
if (level.kind === 'quote') {
|
|
500
|
+
const marker = QUOTE_MARKER.exec(rest);
|
|
501
|
+
if (marker === null)
|
|
502
|
+
return SPACES.test(rest) ? 'gone' : 'line';
|
|
503
|
+
rest = rest.slice(marker[0].length);
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
if (SPACES.test(rest))
|
|
507
|
+
return quotesOf(levels.slice(index)) > 0 ? 'gone' : 'blank';
|
|
508
|
+
if (!rest.startsWith(' '.repeat(level.size)))
|
|
509
|
+
return 'line';
|
|
510
|
+
rest = rest.slice(level.size);
|
|
511
|
+
}
|
|
512
|
+
return SPACES.test(rest) ? 'blank' : 'line';
|
|
513
|
+
}
|
|
514
|
+
function plain(facts) {
|
|
515
|
+
return (!opens(facts) &&
|
|
516
|
+
!TAG.test(facts.content) &&
|
|
517
|
+
!DELIMITER_ROW.test(facts.content) &&
|
|
518
|
+
!UNDERLINE.test(facts.content));
|
|
519
|
+
}
|
|
520
|
+
function spreadScan(long, line, column, size, parents) {
|
|
521
|
+
const { text, starts } = long;
|
|
522
|
+
const lines = starts.length - 1;
|
|
523
|
+
const quotes = quotesOf(parents);
|
|
524
|
+
const breaks = quotes > 0 ? long.quoteBreaks : long.breaks;
|
|
525
|
+
const kind = (index) => withinOf(lineText(starts, text, index), parents);
|
|
526
|
+
let blank = breaks[line + 1];
|
|
527
|
+
while (blank < lines && kind(blank) === 'line')
|
|
528
|
+
blank = breaks[blank + 1];
|
|
529
|
+
if (blank >= lines || kind(blank) === 'gone')
|
|
530
|
+
return false;
|
|
531
|
+
let next = blank + 1;
|
|
532
|
+
while (next < lines && kind(next) === 'blank')
|
|
533
|
+
next += 1;
|
|
534
|
+
if (next >= lines || kind(next) === 'gone')
|
|
535
|
+
return false;
|
|
536
|
+
const at = columnOn(long, next, parents);
|
|
537
|
+
if (at < 0)
|
|
538
|
+
return false;
|
|
539
|
+
const lead = /^[ \t]*/.exec(lineText(starts, text, next).slice(at))[0];
|
|
540
|
+
if (lead.includes('\t'))
|
|
541
|
+
return null;
|
|
542
|
+
if (lead.length < size)
|
|
543
|
+
return false;
|
|
544
|
+
const leads = new RegExp(`^(?: {0,3}> ?){0,${quotes}}`);
|
|
545
|
+
if (!plain(lineFacts(lineText(starts, text, line).slice(column))))
|
|
546
|
+
return null;
|
|
547
|
+
for (let index = line + 1; index < blank; index += 1) {
|
|
548
|
+
const raw = lineText(starts, text, index);
|
|
549
|
+
const held = columnOn(long, index, parents);
|
|
550
|
+
const rest = held < 0 ? raw.replace(leads, '') : raw.slice(held);
|
|
551
|
+
const indent = /^[ \t]*/.exec(rest)[0];
|
|
552
|
+
if (indent.includes('\t'))
|
|
553
|
+
return null;
|
|
554
|
+
const inner = indent.length >= size ? lineFacts(rest.slice(size)) : lineFacts(rest);
|
|
555
|
+
if (indent.length >= size && inner.indent >= 4)
|
|
556
|
+
return null;
|
|
557
|
+
if (!plain(inner))
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
function spreadOf(long, line, column, size, parents) {
|
|
563
|
+
const key = long.starts[line] + column;
|
|
564
|
+
const held = long.spreads.get(key);
|
|
451
565
|
if (held !== undefined)
|
|
452
566
|
return held;
|
|
567
|
+
const spread = spreadScan(long, line, column, size, parents);
|
|
568
|
+
long.spreads.set(key, spread);
|
|
569
|
+
return spread;
|
|
570
|
+
}
|
|
571
|
+
function itemLevel(long, pane, item, outer) {
|
|
572
|
+
const { text, starts } = long;
|
|
573
|
+
const marker = offsetOf(item) + pane.start - pane.lead;
|
|
574
|
+
const line = lineOf(long, marker);
|
|
575
|
+
const start = starts[line];
|
|
576
|
+
const base = columnOn(long, line, outer);
|
|
577
|
+
if (base < 0 || marker < start + base || !/^ *$/.test(text.slice(start + base, marker))) {
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
const sign = MARKER.exec(text.slice(marker, marker + 11))?.[0];
|
|
581
|
+
if (sign === undefined)
|
|
582
|
+
return null;
|
|
583
|
+
let after = marker + sign.length;
|
|
584
|
+
while (text[after] === ' ')
|
|
585
|
+
after += 1;
|
|
586
|
+
const spaces = after - marker - sign.length;
|
|
587
|
+
if (spaces < 1 || spaces > 4 || after >= lineEnd(starts, text, line))
|
|
588
|
+
return null;
|
|
589
|
+
if (/[\t\r\n]/.test(text[after]))
|
|
590
|
+
return null;
|
|
591
|
+
const column = after - start;
|
|
592
|
+
const size = column - base;
|
|
593
|
+
const spread = item.spread === true
|
|
594
|
+
? true
|
|
595
|
+
: spreadOf(long, line, column, size, outer);
|
|
596
|
+
if (spread === null)
|
|
597
|
+
return null;
|
|
598
|
+
long.spreads.set(start + column, spread);
|
|
599
|
+
const carry = `${' '.repeat(marker - start - base)}${sign}${' '.repeat(spaces)}`;
|
|
600
|
+
return { kind: 'item', line, column, size, carry, spread };
|
|
601
|
+
}
|
|
602
|
+
function noteLevel(long, pane, note, outer) {
|
|
603
|
+
const { text, starts } = long;
|
|
604
|
+
const marker = offsetOf(note) + pane.start - pane.lead;
|
|
605
|
+
const line = lineOf(long, marker);
|
|
606
|
+
const start = starts[line];
|
|
607
|
+
const base = columnOn(long, line, outer);
|
|
608
|
+
if (base < 0 || marker < start + base || !/^ *$/.test(text.slice(start + base, marker))) {
|
|
609
|
+
return null;
|
|
610
|
+
}
|
|
611
|
+
const label = NOTE.exec(text.slice(marker, marker + 1_004))?.[0];
|
|
612
|
+
if (label === undefined)
|
|
613
|
+
return null;
|
|
614
|
+
let after = marker + label.length;
|
|
615
|
+
while (text[after] === ' ')
|
|
616
|
+
after += 1;
|
|
617
|
+
if (text[after] === '\t')
|
|
618
|
+
return null;
|
|
619
|
+
const column = after - start;
|
|
620
|
+
return { kind: 'note', line, column, size: 4, carry: `${label} `, spread: false };
|
|
621
|
+
}
|
|
622
|
+
function quoteLevel(long, pane, quote) {
|
|
623
|
+
const { text, starts } = long;
|
|
624
|
+
const marker = offsetOf(quote) + pane.start - pane.lead;
|
|
625
|
+
const line = lineOf(long, marker);
|
|
626
|
+
const known = text[marker] === '>' && text[marker + 1] !== '\t';
|
|
627
|
+
const after = text[marker + 1] === ' ' ? marker + 2 : marker + 1;
|
|
628
|
+
return {
|
|
629
|
+
kind: 'quote',
|
|
630
|
+
line,
|
|
631
|
+
column: known ? after - starts[line] : -1,
|
|
632
|
+
size: 0,
|
|
633
|
+
carry: '> ',
|
|
634
|
+
spread: false,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
function regionOf(long, line, levels) {
|
|
638
|
+
const quotes = quotesOf(levels);
|
|
639
|
+
const lined = !itemed(levels);
|
|
640
|
+
const stop = (quotes > 0 ? long.quoteBreaks : long.breaks)[line];
|
|
641
|
+
const markers = markersOf(quotes);
|
|
642
|
+
const leads = new RegExp(`^(?: {0,3}> ?){0,${quotes}}`);
|
|
643
|
+
const name = `${levels.map((level) => (level.kind === 'quote' ? '>' : level.size)).join(' ')}:${stop}`;
|
|
644
|
+
const held = long.regions.get(name);
|
|
645
|
+
if (held !== undefined && held.from <= line + 1)
|
|
646
|
+
return held;
|
|
453
647
|
const { text, starts } = long;
|
|
454
|
-
|
|
455
|
-
for (let index = line + 1; index < stop
|
|
648
|
+
const looks = [];
|
|
649
|
+
for (let index = line + 1; index < stop; index += 1) {
|
|
456
650
|
const raw = lineText(starts, text, index);
|
|
457
|
-
const
|
|
458
|
-
|
|
651
|
+
const column = lined ? (markers.exec(raw)?.[0].length ?? -1) : columnOn(long, index, levels);
|
|
652
|
+
const facts = lineFacts(column < 0 ? raw.replace(lined ? markers : leads, '') : raw.slice(column));
|
|
653
|
+
if (facts.indent <= 3 && UNDERLINE.test(facts.content))
|
|
654
|
+
looks.push(index);
|
|
459
655
|
}
|
|
460
656
|
const from = starts[line];
|
|
461
657
|
const to = Math.min(starts[stop], text.length);
|
|
@@ -470,10 +666,22 @@ function regionOf(long, line, depth) {
|
|
|
470
666
|
runs.set(end - at, at);
|
|
471
667
|
at = text.indexOf('`', end);
|
|
472
668
|
}
|
|
473
|
-
const region = {
|
|
669
|
+
const region = { from: line + 1, looks, last, runs };
|
|
474
670
|
long.regions.set(name, region);
|
|
475
671
|
return region;
|
|
476
672
|
}
|
|
673
|
+
function after(lines, line) {
|
|
674
|
+
let low = 0;
|
|
675
|
+
let high = lines.length;
|
|
676
|
+
while (low < high) {
|
|
677
|
+
const middle = (low + high) >> 1;
|
|
678
|
+
if (lines[middle] <= line)
|
|
679
|
+
low = middle + 1;
|
|
680
|
+
else
|
|
681
|
+
high = middle;
|
|
682
|
+
}
|
|
683
|
+
return lines[low] ?? Infinity;
|
|
684
|
+
}
|
|
477
685
|
const CODE = 1;
|
|
478
686
|
const LINKED = 2;
|
|
479
687
|
const EMPHASIZED = 4;
|
|
@@ -513,12 +721,12 @@ function opener(text, from, to, paragraph) {
|
|
|
513
721
|
const right = !space(before) && (!mark(before) || space(after) || mark(after));
|
|
514
722
|
return left && (!right || mark(before));
|
|
515
723
|
}
|
|
516
|
-
function pendingAt(long,
|
|
724
|
+
function pendingAt(long, pane, paragraph, start, region) {
|
|
517
725
|
const { text } = long;
|
|
518
|
-
const shift =
|
|
519
|
-
const flags = new Uint8Array(
|
|
726
|
+
const shift = pane.start - pane.lead;
|
|
727
|
+
const flags = new Uint8Array(pane.end - start);
|
|
520
728
|
marked(paragraph, flags, shift, start, text);
|
|
521
|
-
for (let at = start; at <
|
|
729
|
+
for (let at = start; at < pane.end; at += 1) {
|
|
522
730
|
if ((flags[at - start] & CODE) !== 0)
|
|
523
731
|
continue;
|
|
524
732
|
const one = text[at];
|
|
@@ -565,61 +773,102 @@ function inside(spans, at) {
|
|
|
565
773
|
function markersOf(depth) {
|
|
566
774
|
return new RegExp(`^(?: {0,3}> ?){${depth}}`);
|
|
567
775
|
}
|
|
568
|
-
function
|
|
776
|
+
function spreadAlong(nodes, levels) {
|
|
777
|
+
let node = nodes.at(-1);
|
|
778
|
+
for (const level of levels) {
|
|
779
|
+
if (node === undefined || !('children' in node))
|
|
780
|
+
break;
|
|
781
|
+
if (level.kind !== 'item') {
|
|
782
|
+
node = node.children.at(-1);
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
const item = node.children.at(-1);
|
|
786
|
+
if (node.type !== 'list' || item?.type !== 'listItem')
|
|
787
|
+
break;
|
|
788
|
+
item.spread = level.spread;
|
|
789
|
+
node = item.children.at(-1);
|
|
790
|
+
}
|
|
791
|
+
return nodes;
|
|
792
|
+
}
|
|
793
|
+
function openable(long, line, cut, begun, frame) {
|
|
569
794
|
const { text, starts } = long;
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
const
|
|
574
|
-
|
|
795
|
+
if (!/^ *$/.test(text.slice(cut, begun)))
|
|
796
|
+
return false;
|
|
797
|
+
const content = lineText(starts, text, line).slice(cut - starts[line]);
|
|
798
|
+
const inner = frame.at(-1).kind;
|
|
799
|
+
if (inner !== 'quote' && cut !== begun)
|
|
800
|
+
return false;
|
|
801
|
+
if (inner === 'item' && TASK.test(content))
|
|
802
|
+
return false;
|
|
803
|
+
return frame.every((_, index) => {
|
|
804
|
+
const facts = lineFacts(`${carryOf(frame.slice(index))}${content}`);
|
|
805
|
+
return facts.indent > 3 || !THEMATIC.test(facts.content);
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
function paragraphCuts(long, pane, paragraph, levels, mode) {
|
|
809
|
+
const { text, starts } = long;
|
|
810
|
+
const quotes = quotesOf(levels);
|
|
811
|
+
const lined = !itemed(levels);
|
|
812
|
+
const markers = markersOf(quotes);
|
|
813
|
+
const leads = new RegExp(`^(?: {0,3}> ?){0,${quotes}}`);
|
|
814
|
+
const carry = carryOf(levels);
|
|
815
|
+
const shift = pane.start - pane.lead;
|
|
816
|
+
const start = Math.max(offsetOf(paragraph) + shift, pane.start);
|
|
575
817
|
const first = lineOf(long, start);
|
|
576
|
-
const region = regionOf(long, first,
|
|
577
|
-
if (region.
|
|
818
|
+
const region = regionOf(long, first, levels);
|
|
819
|
+
if (after(region.looks, first) !== Infinity)
|
|
578
820
|
return [];
|
|
579
|
-
const pending = mode === 'render' ? pendingAt(long,
|
|
821
|
+
const pending = mode === 'render' ? pendingAt(long, pane, paragraph, start, region) : Infinity;
|
|
580
822
|
const spans = mode === 'render'
|
|
581
823
|
? paragraph.children
|
|
582
824
|
.filter((child) => child.type !== 'text')
|
|
583
825
|
.map((child) => [offsetOf(child) + shift, endOf(child) + shift])
|
|
584
826
|
: [];
|
|
585
|
-
const last = lineOf(long,
|
|
827
|
+
const last = lineOf(long, pane.end - 1);
|
|
586
828
|
const lines = starts.length - 1;
|
|
587
|
-
const path = [...
|
|
588
|
-
const reparsed = (at) => () => windowOf(long, { start:
|
|
829
|
+
const path = [...stepsOf(levels), 'paragraph'];
|
|
830
|
+
const reparsed = (at) => () => spreadAlong(windowOf(long, { start: pane.start, path: [], join: '', carry: pane.carry, levels: pane.levels }, at, pane.prefix).nodes, levels);
|
|
589
831
|
const cuts = [];
|
|
590
832
|
const settled = (at) => at > start && at < pending && !inside(spans, at);
|
|
591
|
-
const
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return !DELIMITER_ROW.test(lineFacts(next.replace(markers, '')).content);
|
|
833
|
+
const restOf = (index) => {
|
|
834
|
+
const raw = lineText(starts, text, index);
|
|
835
|
+
const column = lined ? -1 : columnOn(long, index, levels);
|
|
836
|
+
return column < 0 ? raw.replace(lined ? markers : leads, '') : raw.slice(column);
|
|
596
837
|
};
|
|
597
|
-
const
|
|
838
|
+
const unbroken = (index) => index >= lines || !DELIMITER_ROW.test(lineFacts(restOf(index)).content);
|
|
839
|
+
const contentOf = (index) => {
|
|
840
|
+
const raw = lineText(starts, text, index);
|
|
841
|
+
const column = lined ? -1 : columnOn(long, index, levels);
|
|
842
|
+
return starts[index] + (column < 0 ? leads.exec(raw)[0].length : column);
|
|
843
|
+
};
|
|
844
|
+
const fresh = (at) => levels.at(-1)?.kind !== 'item' || !TASK.test(text.slice(at, at + 3));
|
|
598
845
|
for (let index = first + 1; index <= last; index += 1) {
|
|
599
846
|
const line = starts[index];
|
|
600
847
|
if (line >= pending)
|
|
601
848
|
break;
|
|
602
|
-
const whole = markers.test(lineText(starts, text, index));
|
|
849
|
+
const whole = lined && markers.test(lineText(starts, text, index));
|
|
603
850
|
const content = contentOf(index);
|
|
604
851
|
const at = whole ? line : content;
|
|
605
852
|
const previous = lineText(starts, text, index - 1);
|
|
606
|
-
if (!restartable(text, content) || /[ \t\\]$/.test(previous))
|
|
853
|
+
if (!restartable(text, content) || !fresh(content) || /[ \t\\]$/.test(previous))
|
|
607
854
|
continue;
|
|
608
855
|
if (!settled(at) || !unbroken(index + 1))
|
|
609
856
|
continue;
|
|
610
857
|
const join = text.slice(starts[index - 1] + previous.length, line);
|
|
611
|
-
cuts.push({ at, path, join, carry: whole ? '' : carry, nodes: reparsed(at) });
|
|
858
|
+
cuts.push({ at, path, join, carry: whole ? '' : carry, levels, nodes: reparsed(at) });
|
|
612
859
|
}
|
|
613
860
|
if (cuts.length > 0)
|
|
614
861
|
return cuts;
|
|
615
862
|
for (let index = first; index <= last; index += 1) {
|
|
616
863
|
const content = contentOf(index);
|
|
617
|
-
const end = Math.min(lineEnd(starts, text, index),
|
|
864
|
+
const end = Math.min(lineEnd(starts, text, index), pane.end);
|
|
618
865
|
for (let at = Math.max(content + 1, start + 1); at < end; at += 1) {
|
|
619
866
|
if (at >= pending)
|
|
620
867
|
return cuts;
|
|
621
868
|
if (!/[ \t]/.test(text[at - 1]) || !restartable(text, at) || !settled(at))
|
|
622
869
|
continue;
|
|
870
|
+
if (!fresh(at))
|
|
871
|
+
continue;
|
|
623
872
|
if (!unbroken(index + 1))
|
|
624
873
|
break;
|
|
625
874
|
let from = at - 1;
|
|
@@ -627,21 +876,21 @@ function paragraphCuts(long, window, paragraph, depth, mode) {
|
|
|
627
876
|
from -= 1;
|
|
628
877
|
if (from === content)
|
|
629
878
|
continue;
|
|
630
|
-
cuts.push({ at, path, join: text.slice(from, at), carry, nodes: reparsed(at) });
|
|
879
|
+
cuts.push({ at, path, join: text.slice(from, at), carry, levels, nodes: reparsed(at) });
|
|
631
880
|
}
|
|
632
881
|
}
|
|
633
882
|
return cuts;
|
|
634
883
|
}
|
|
635
|
-
function cutsOf(long,
|
|
636
|
-
const { nodes } =
|
|
637
|
-
const shift =
|
|
884
|
+
function cutsOf(long, pane, mode) {
|
|
885
|
+
const { nodes } = pane;
|
|
886
|
+
const shift = pane.start - pane.lead;
|
|
638
887
|
const at = (node) => lineStartOf(long, offsetOf(node) + shift);
|
|
639
888
|
const cuts = [];
|
|
640
889
|
for (let index = 1; index < nodes.length; index += 1) {
|
|
641
890
|
const start = at(nodes[index]);
|
|
642
|
-
if (start >
|
|
891
|
+
if (start > pane.start) {
|
|
643
892
|
const taken = nodes.slice(0, index);
|
|
644
|
-
cuts.push({ at: start, path: [], join: '', carry: '', nodes: () => taken });
|
|
893
|
+
cuts.push({ at: start, path: [], join: '', carry: '', levels: [], nodes: () => taken });
|
|
645
894
|
}
|
|
646
895
|
}
|
|
647
896
|
const last = nodes.at(-1);
|
|
@@ -649,46 +898,111 @@ function cutsOf(long, window, mode) {
|
|
|
649
898
|
return cuts;
|
|
650
899
|
const before = nodes.slice(0, -1);
|
|
651
900
|
const chain = [];
|
|
652
|
-
const
|
|
901
|
+
const levels = [];
|
|
902
|
+
const spreads = new Map();
|
|
903
|
+
const within = (parent, path, frame, header) => {
|
|
653
904
|
const held = [...chain, parent];
|
|
654
|
-
const
|
|
655
|
-
const marked = markersOf(
|
|
905
|
+
const lined = !itemed(frame);
|
|
906
|
+
const marked = markersOf(quotesOf(frame));
|
|
656
907
|
for (let index = 1; index < parent.children.length; index += 1) {
|
|
657
|
-
const
|
|
658
|
-
|
|
908
|
+
const begun = offsetOf(parent.children[index]) + shift;
|
|
909
|
+
const line = lineOf(long, begun);
|
|
910
|
+
let cut = long.starts[line];
|
|
911
|
+
if (lined) {
|
|
912
|
+
if (!marked.test(lineText(long.starts, long.text, line)))
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
const column = columnOn(long, line, frame);
|
|
917
|
+
if (column < 0)
|
|
918
|
+
continue;
|
|
919
|
+
if (header === null) {
|
|
920
|
+
cut += column;
|
|
921
|
+
if (!openable(long, line, cut, begun, frame))
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
if (cut <= pane.start)
|
|
659
926
|
continue;
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
cuts.push({ at: start, path, join: '', carry, nodes: () => taken });
|
|
927
|
+
const taken = [...before, truncated(held, index, spreads)];
|
|
928
|
+
const carry = header ?? (lined ? '' : carryOf(frame));
|
|
929
|
+
cuts.push({ at: cut, path, join: '', carry, levels: frame, nodes: () => taken });
|
|
664
930
|
}
|
|
665
931
|
};
|
|
932
|
+
const carried = (node) => offsetOf(node) < pane.lead;
|
|
666
933
|
let node = last;
|
|
667
934
|
while (node !== undefined) {
|
|
668
935
|
if (node.type === 'paragraph') {
|
|
669
|
-
cuts.push(...paragraphCuts(long,
|
|
936
|
+
cuts.push(...paragraphCuts(long, pane, node, levels, mode));
|
|
670
937
|
}
|
|
671
|
-
if (node.type === 'list')
|
|
672
|
-
within(node, 'list', '');
|
|
673
938
|
if (node.type === 'table' && node.children.length > 1) {
|
|
674
|
-
const begun = offsetOf(node) + shift
|
|
675
|
-
const
|
|
676
|
-
|
|
939
|
+
const begun = offsetOf(node) + shift;
|
|
940
|
+
const lined = !itemed(levels);
|
|
941
|
+
const header = begun < pane.start
|
|
942
|
+
? pane.carry
|
|
943
|
+
: lined
|
|
944
|
+
? long.text.slice(at(node), at(node.children[1]))
|
|
945
|
+
: long.text[begun] === ' '
|
|
946
|
+
? null
|
|
947
|
+
: `${carryOf(levels)}${long.text.slice(begun, at(node.children[1]))}`;
|
|
948
|
+
if (header !== null)
|
|
949
|
+
within(node, [...stepsOf(levels), 'table'], levels, header);
|
|
950
|
+
}
|
|
951
|
+
if (node.type === 'list') {
|
|
952
|
+
within(node, [...stepsOf(levels), 'list'], levels, null);
|
|
953
|
+
const item = node.children.at(-1);
|
|
954
|
+
if (item === undefined)
|
|
955
|
+
break;
|
|
956
|
+
const level = carried(item)
|
|
957
|
+
? pane.levels[levels.length]
|
|
958
|
+
: itemLevel(long, pane, item, levels);
|
|
959
|
+
if (level === undefined || level === null || level.kind !== 'item')
|
|
960
|
+
break;
|
|
961
|
+
chain.push(node);
|
|
962
|
+
levels.push(level);
|
|
963
|
+
spreads.set(item, level.spread);
|
|
964
|
+
within(item, stepsOf(levels), levels, null);
|
|
965
|
+
chain.push(item);
|
|
966
|
+
node = item.children.at(-1);
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
if (node.type === 'footnoteDefinition') {
|
|
970
|
+
const level = carried(node)
|
|
971
|
+
? pane.levels[levels.length]
|
|
972
|
+
: noteLevel(long, pane, node, levels);
|
|
973
|
+
if (level === undefined || level === null || level.kind !== 'note')
|
|
974
|
+
break;
|
|
975
|
+
levels.push(level);
|
|
976
|
+
within(node, stepsOf(levels), levels, null);
|
|
977
|
+
chain.push(node);
|
|
978
|
+
node = node.children.at(-1);
|
|
979
|
+
continue;
|
|
677
980
|
}
|
|
678
981
|
if (node.type !== 'blockquote')
|
|
679
982
|
break;
|
|
680
|
-
|
|
983
|
+
const level = carried(node) ? pane.levels[levels.length] : quoteLevel(long, pane, node);
|
|
984
|
+
if (level === undefined || level.kind !== 'quote')
|
|
985
|
+
break;
|
|
986
|
+
levels.push(level);
|
|
987
|
+
within(node, stepsOf(levels), levels, null);
|
|
681
988
|
chain.push(node);
|
|
682
989
|
node = node.children.at(-1);
|
|
683
990
|
}
|
|
684
991
|
return cuts;
|
|
685
992
|
}
|
|
686
|
-
function truncated(chain, index) {
|
|
993
|
+
function truncated(chain, index, spreads) {
|
|
687
994
|
const [outer, ...inner] = chain;
|
|
688
|
-
|
|
689
|
-
|
|
995
|
+
const spread = spreads.get(outer);
|
|
996
|
+
const kept = spread === undefined ? {} : { spread };
|
|
997
|
+
if (inner.length === 0) {
|
|
998
|
+
return { ...outer, ...kept, children: outer.children.slice(0, index) };
|
|
999
|
+
}
|
|
690
1000
|
const children = outer.children.slice(0, -1);
|
|
691
|
-
return {
|
|
1001
|
+
return {
|
|
1002
|
+
...outer,
|
|
1003
|
+
...kept,
|
|
1004
|
+
children: [...children, truncated(inner, index, spreads)],
|
|
1005
|
+
};
|
|
692
1006
|
}
|
|
693
1007
|
function chosen(cuts, target) {
|
|
694
1008
|
let best = null;
|
|
@@ -704,12 +1018,12 @@ function chosen(cuts, target) {
|
|
|
704
1018
|
}
|
|
705
1019
|
return best;
|
|
706
1020
|
}
|
|
707
|
-
function closingOf(long,
|
|
708
|
-
const last =
|
|
1021
|
+
function closingOf(long, pane) {
|
|
1022
|
+
const last = pane.nodes.at(-1);
|
|
709
1023
|
if (last?.type !== 'code')
|
|
710
1024
|
return 0;
|
|
711
1025
|
const { text, starts } = long;
|
|
712
|
-
const line = lineOf(long, offsetOf(last) +
|
|
1026
|
+
const line = lineOf(long, offsetOf(last) + pane.start - pane.lead);
|
|
713
1027
|
const fence = fenceOf(lineFacts(lineText(starts, text, line)));
|
|
714
1028
|
if (fence === null)
|
|
715
1029
|
return 0;
|
|
@@ -725,30 +1039,29 @@ function cutWindow(long, from, mode, open) {
|
|
|
725
1039
|
const line = Math.min(lineOf(long, from.start) + WINDOW_LINES, long.starts.length - 1);
|
|
726
1040
|
let end = windowEnd(long, from.start, Math.min(WINDOW_CHARS, long.starts[line] - from.start));
|
|
727
1041
|
for (;;) {
|
|
728
|
-
const
|
|
1042
|
+
const pane = open(end);
|
|
729
1043
|
if (end >= long.text.length)
|
|
730
|
-
return {
|
|
731
|
-
const cut = chosen(cutsOf(long,
|
|
1044
|
+
return { pane, cut: null };
|
|
1045
|
+
const cut = chosen(cutsOf(long, pane, mode), from.start + VIEW_CHARS);
|
|
732
1046
|
if (cut !== null)
|
|
733
|
-
return {
|
|
1047
|
+
return { pane, cut };
|
|
734
1048
|
const grown = windowEnd(long, from.start, 2 * (end - from.start));
|
|
735
1049
|
const whole = 2 * grown - from.start >= long.text.length;
|
|
736
|
-
end = Math.max(whole ? long.text.length : grown, closingOf(long,
|
|
1050
|
+
end = Math.max(whole ? long.text.length : grown, closingOf(long, pane));
|
|
737
1051
|
}
|
|
738
1052
|
}
|
|
739
1053
|
export function pieceAt(long, index) {
|
|
740
1054
|
while (long.pieces.length <= index && long.next !== null) {
|
|
741
1055
|
const from = long.next;
|
|
742
|
-
const {
|
|
1056
|
+
const { pane, cut } = cutWindow(long, from, 'render', (end) => renderWindow(long, from, end));
|
|
743
1057
|
const end = cut?.at ?? long.text.length;
|
|
744
|
-
for (const one of
|
|
1058
|
+
for (const one of pane.defined) {
|
|
745
1059
|
if (one.at < end && !long.urls.has(one.key))
|
|
746
1060
|
long.urls.set(one.key, one.url);
|
|
747
1061
|
}
|
|
748
|
-
const nodes = cut === null ?
|
|
1062
|
+
const nodes = cut === null ? pane.nodes : cut.nodes();
|
|
749
1063
|
long.pieces.push({ nodes, path: from.path, join: from.join });
|
|
750
|
-
long.next =
|
|
751
|
-
cut === null ? null : { start: cut.at, path: cut.path, join: cut.join, carry: cut.carry };
|
|
1064
|
+
long.next = cut === null ? null : nextOf(cut);
|
|
752
1065
|
}
|
|
753
1066
|
return long.pieces[index] ?? null;
|
|
754
1067
|
}
|