@bendyline/squisq 2.11.0 → 2.11.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/dist/{chunk-CUYHFOFL.js → chunk-6ATZOUCQ.js} +223 -14
- package/dist/{chunk-ZYCSRDSX.js → chunk-B26DU2RH.js} +1 -1
- package/dist/{chunk-T3B4WJBR.js → chunk-B3AK7SLZ.js} +87 -5
- package/dist/{chunk-EH4S7HXE.js → chunk-QQ4I5HWV.js} +36 -4
- package/dist/{chunk-ZWID3HM5.js → chunk-UXKFSYTQ.js} +1 -1
- package/dist/doc/index.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/narration/index.js +3 -3
- package/dist/proof/index.d.ts +22 -3
- package/dist/proof/index.js +1 -1
- package/dist/recommend/index.js +1 -1
- package/package.json +1 -1
|
@@ -176,6 +176,11 @@ function parseAsciiDiagramWithStats(text) {
|
|
|
176
176
|
const style = detectStyle(grid);
|
|
177
177
|
const rects = traceBoxes(grid);
|
|
178
178
|
const boxes = buildBoxes(grid, rects, warnings);
|
|
179
|
+
const boxNodes = boxes.length;
|
|
180
|
+
const railBoxes = findRailLabels(grid, boxes);
|
|
181
|
+
for (const rail of railBoxes) boxes.push(rail);
|
|
182
|
+
const railNodes = railBoxes.length;
|
|
183
|
+
if (railNodes > 0) warnings.push(`rail-labels(${railNodes})`);
|
|
179
184
|
const mask = new Uint8Array(W * H);
|
|
180
185
|
const perimeterOwners = /* @__PURE__ */ new Map();
|
|
181
186
|
for (let b = 0; b < boxes.length; b++) {
|
|
@@ -248,18 +253,21 @@ function parseAsciiDiagramWithStats(text) {
|
|
|
248
253
|
if (looseRuns.length > MAX_LOOSE_WARNINGS) {
|
|
249
254
|
warnings.push(`loose-text (+${looseRuns.length - MAX_LOOSE_WARNINGS} more)`);
|
|
250
255
|
}
|
|
251
|
-
const nodes = boxes.map((box) =>
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
const nodes = boxes.map((box) => {
|
|
257
|
+
const rect = box.emit ?? box;
|
|
258
|
+
return {
|
|
259
|
+
id: box.id,
|
|
260
|
+
label: box.labelLines.join("\n"),
|
|
261
|
+
col: rect.c0,
|
|
262
|
+
row: rect.r0,
|
|
263
|
+
wCols: rect.c1 - rect.c0 + 1,
|
|
264
|
+
hRows: rect.r1 - rect.r0 + 1,
|
|
265
|
+
...box.parentIdx >= 0 ? { containerId: boxes[box.parentIdx].id } : {}
|
|
266
|
+
};
|
|
267
|
+
}).sort((a, b) => a.row - b.row || a.col - b.col);
|
|
260
268
|
return {
|
|
261
269
|
diagram: { nodes, edges, style, warnings },
|
|
262
|
-
stats: { totalNonSpaceCells, looseNonSpaceCells, hasWideChars }
|
|
270
|
+
stats: { totalNonSpaceCells, looseNonSpaceCells, hasWideChars, boxNodes, railNodes }
|
|
263
271
|
};
|
|
264
272
|
}
|
|
265
273
|
function buildGrid(text, warnings) {
|
|
@@ -497,6 +505,176 @@ function slugify(s) {
|
|
|
497
505
|
const slug2 = s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
498
506
|
return slug2 || "node";
|
|
499
507
|
}
|
|
508
|
+
var BUS_LABEL_LOOKASIDE = 3;
|
|
509
|
+
var RAIL_LABEL_PAD = 1;
|
|
510
|
+
var BOX_SPILL_GAP = 2;
|
|
511
|
+
var RAIL_ROW_SCALE = 3;
|
|
512
|
+
var RAIL_COL_SCALE = 2;
|
|
513
|
+
function railRect(text, lines, boxScale) {
|
|
514
|
+
if (boxScale) {
|
|
515
|
+
const r0 = text.r0 * RAIL_ROW_SCALE;
|
|
516
|
+
const c0 = text.c0 * RAIL_COL_SCALE;
|
|
517
|
+
return {
|
|
518
|
+
r0,
|
|
519
|
+
c0,
|
|
520
|
+
r1: r0 + Math.max(3, lines + 2) - 1,
|
|
521
|
+
c1: c0 + Math.max(3, text.c1 - text.c0 + 1 + 4) - 1
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
const top = Math.max(0, text.r0 - RAIL_LABEL_PAD);
|
|
525
|
+
const left = Math.max(0, text.c0 - RAIL_LABEL_PAD);
|
|
526
|
+
return {
|
|
527
|
+
r0: top,
|
|
528
|
+
c0: left,
|
|
529
|
+
r1: top + (text.r1 - text.r0) + 2 * RAIL_LABEL_PAD,
|
|
530
|
+
c1: left + (text.c1 - text.c0) + 2 * RAIL_LABEL_PAD
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function findRailLabels(grid, boxes) {
|
|
534
|
+
const H = grid.length;
|
|
535
|
+
const W = H > 0 ? grid[0].length : 0;
|
|
536
|
+
if (H === 0 || W === 0) return [];
|
|
537
|
+
const inBox = new Uint8Array(W * H);
|
|
538
|
+
for (const box of boxes) {
|
|
539
|
+
for (let r = Math.max(0, box.r0); r <= Math.min(H - 1, box.r1); r++) {
|
|
540
|
+
for (let c = Math.max(0, box.c0); c <= Math.min(W - 1, box.c1); c++) inBox[r * W + c] = 1;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const at = (r, c) => r >= 0 && r < H && c >= 0 && c < W ? grid[r][c] : " ";
|
|
544
|
+
const joins = (ch) => isLineChar(ch) || isJunction(ch) || isPlus(ch) || isAnyCorner(ch);
|
|
545
|
+
const vertJoins = (ch) => {
|
|
546
|
+
const arrow = arrowDirection(ch);
|
|
547
|
+
return joins(ch) || arrow === "up" || arrow === "down";
|
|
548
|
+
};
|
|
549
|
+
const horizJoins = (ch) => {
|
|
550
|
+
const arrow = arrowDirection(ch);
|
|
551
|
+
return joins(ch) || arrow === "left" || arrow === "right";
|
|
552
|
+
};
|
|
553
|
+
const routingRow = [];
|
|
554
|
+
for (let r = 0; r < H; r++) {
|
|
555
|
+
let any = false;
|
|
556
|
+
let all = true;
|
|
557
|
+
for (let c = 0; c < W && all; c++) {
|
|
558
|
+
const ch = grid[r][c];
|
|
559
|
+
if (ch === " ") continue;
|
|
560
|
+
any = true;
|
|
561
|
+
if (!isLineChar(ch) && arrowDirection(ch) === null) all = false;
|
|
562
|
+
}
|
|
563
|
+
routingRow.push(any && all);
|
|
564
|
+
}
|
|
565
|
+
const structural = (r, c) => {
|
|
566
|
+
const ch = at(r, c);
|
|
567
|
+
if (ch === " ") return false;
|
|
568
|
+
if (arrowDirection(ch) !== null) return true;
|
|
569
|
+
const ascii = asciiArrowDirection(ch);
|
|
570
|
+
if (ascii !== null && asciiArrowGate(grid, r, c, ascii)) return true;
|
|
571
|
+
if (!isLineChar(ch)) return false;
|
|
572
|
+
if (routingRow[r]) return true;
|
|
573
|
+
const vert = vertJoins(at(r - 1, c)) || vertJoins(at(r + 1, c));
|
|
574
|
+
if (isVert(ch)) return vert;
|
|
575
|
+
const horiz = horizJoins(at(r, c - 1)) || horizJoins(at(r, c + 1));
|
|
576
|
+
if (isHoriz(ch)) return horiz;
|
|
577
|
+
return vert || horiz;
|
|
578
|
+
};
|
|
579
|
+
const isTextCell = (r, c) => c >= 0 && c < W && grid[r][c] !== " " && !inBox[r * W + c] && !structural(r, c);
|
|
580
|
+
const runs = [];
|
|
581
|
+
for (let r = 0; r < H; r++) {
|
|
582
|
+
let start = -1;
|
|
583
|
+
let end = -1;
|
|
584
|
+
const flush = () => {
|
|
585
|
+
if (start >= 0) {
|
|
586
|
+
const text = grid[r].slice(start, end + 1).join("").trim();
|
|
587
|
+
if (text.length > 0) runs.push({ row: r, c0: start, c1: end, text });
|
|
588
|
+
}
|
|
589
|
+
start = -1;
|
|
590
|
+
};
|
|
591
|
+
for (let c = 0; c < W; c++) {
|
|
592
|
+
if (isTextCell(r, c)) {
|
|
593
|
+
if (start < 0) start = c;
|
|
594
|
+
end = c;
|
|
595
|
+
} else if (start >= 0 && grid[r][c] === " " && isTextCell(r, c + 1)) {
|
|
596
|
+
continue;
|
|
597
|
+
} else {
|
|
598
|
+
flush();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
flush();
|
|
602
|
+
}
|
|
603
|
+
const abutsRail = (run) => [-1, 1].some((dir) => {
|
|
604
|
+
for (let step = 1; step <= BUS_LABEL_LOOKASIDE; step++) {
|
|
605
|
+
const c = dir < 0 ? run.c0 - step : run.c1 + step;
|
|
606
|
+
if (at(run.row, c) === " ") continue;
|
|
607
|
+
return structural(run.row, c);
|
|
608
|
+
}
|
|
609
|
+
return false;
|
|
610
|
+
});
|
|
611
|
+
const spillsFromBox = (run) => boxes.some(
|
|
612
|
+
(box) => run.row >= box.r0 && run.row <= box.r1 && run.c0 <= box.c1 + BOX_SPILL_GAP && run.c1 >= box.c0 - BOX_SPILL_GAP
|
|
613
|
+
);
|
|
614
|
+
const candidates = runs.filter(
|
|
615
|
+
(run) => /[a-z0-9]/i.test(run.text) && !abutsRail(run) && !spillsFromBox(run)
|
|
616
|
+
);
|
|
617
|
+
const groups = [];
|
|
618
|
+
let previousRow = [];
|
|
619
|
+
for (let r = 0; r < H; r++) {
|
|
620
|
+
const rowRuns = candidates.filter((run) => run.row === r);
|
|
621
|
+
const currentRow = [];
|
|
622
|
+
for (const run of rowRuns) {
|
|
623
|
+
const host = previousRow.find((group) => {
|
|
624
|
+
const last = group[group.length - 1];
|
|
625
|
+
return last.row === r - 1 && last.c0 <= run.c1 && run.c0 <= last.c1;
|
|
626
|
+
});
|
|
627
|
+
if (host) {
|
|
628
|
+
host.push(run);
|
|
629
|
+
currentRow.push(host);
|
|
630
|
+
} else {
|
|
631
|
+
const group = [run];
|
|
632
|
+
groups.push(group);
|
|
633
|
+
currentRow.push(group);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
previousRow = currentRow;
|
|
637
|
+
}
|
|
638
|
+
const railHead = (r, c) => {
|
|
639
|
+
if (r < 0 || r >= H || inBox[r * W + c] === 1 || !structural(r, c)) return false;
|
|
640
|
+
const ch = grid[r][c];
|
|
641
|
+
const arrow = arrowDirection(ch) ?? asciiArrowDirection(ch);
|
|
642
|
+
return isVert(ch) || isJunction(ch) || isPlus(ch) || arrow === "up" || arrow === "down";
|
|
643
|
+
};
|
|
644
|
+
const railAdjacent = (group) => group.some(
|
|
645
|
+
(run) => [run.row - 1, run.row + 1].some((r) => {
|
|
646
|
+
for (let c = Math.max(0, run.c0 - 1); c <= Math.min(W - 1, run.c1 + 1); c++) {
|
|
647
|
+
if (railHead(r, c)) return true;
|
|
648
|
+
}
|
|
649
|
+
return false;
|
|
650
|
+
})
|
|
651
|
+
);
|
|
652
|
+
const usedIds = /* @__PURE__ */ new Map();
|
|
653
|
+
for (const box of boxes) usedIds.set(box.id, (usedIds.get(box.id) ?? 0) + 1);
|
|
654
|
+
const out = [];
|
|
655
|
+
for (const group of groups) {
|
|
656
|
+
if (!railAdjacent(group)) continue;
|
|
657
|
+
const labelLines = group.map((run) => run.text);
|
|
658
|
+
const r0 = group[0].row;
|
|
659
|
+
const r1 = group[group.length - 1].row;
|
|
660
|
+
const c0 = Math.min(...group.map((run) => run.c0));
|
|
661
|
+
const c1 = Math.max(...group.map((run) => run.c1));
|
|
662
|
+
const base = slugify(labelLines[0]);
|
|
663
|
+
const count = usedIds.get(base) ?? 0;
|
|
664
|
+
usedIds.set(base, count + 1);
|
|
665
|
+
out.push({
|
|
666
|
+
r0,
|
|
667
|
+
c0,
|
|
668
|
+
r1,
|
|
669
|
+
c1,
|
|
670
|
+
parentIdx: -1,
|
|
671
|
+
labelLines,
|
|
672
|
+
id: count === 0 ? base : `${base}-${count + 1}`,
|
|
673
|
+
emit: railRect({ r0, c0, r1, c1 }, labelLines.length, boxes.length === 0)
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
return out;
|
|
677
|
+
}
|
|
500
678
|
function extractEdges(grid, mask, perimeterOwners, boxes, warnings) {
|
|
501
679
|
const H = grid.length;
|
|
502
680
|
const W = H > 0 ? grid[0].length : 0;
|
|
@@ -687,6 +865,26 @@ function extractEdges(grid, mask, perimeterOwners, boxes, warnings) {
|
|
|
687
865
|
attachmentsByBox.set(boxIdx, { boxIdx, isArrowEnd: false });
|
|
688
866
|
}
|
|
689
867
|
}
|
|
868
|
+
if (attachmentsByBox.size < 2) {
|
|
869
|
+
for (const idx of component) {
|
|
870
|
+
const r = Math.floor(idx / W);
|
|
871
|
+
const c = idx % W;
|
|
872
|
+
const ch = grid[r][c];
|
|
873
|
+
const axis = isVert(ch) ? [
|
|
874
|
+
[-1, 0],
|
|
875
|
+
[1, 0]
|
|
876
|
+
] : isHoriz(ch) ? [
|
|
877
|
+
[0, -1],
|
|
878
|
+
[0, 1]
|
|
879
|
+
] : [];
|
|
880
|
+
for (const [dr, dc] of axis) {
|
|
881
|
+
const boxIdx = nearestOwner(r + dr, c + dc);
|
|
882
|
+
if (boxIdx !== null && !attachmentsByBox.has(boxIdx)) {
|
|
883
|
+
attachmentsByBox.set(boxIdx, { boxIdx, isArrowEnd: false });
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
690
888
|
const attachments = [...attachmentsByBox.values()].sort(
|
|
691
889
|
(a, b) => boxes[a.boxIdx].r0 - boxes[b.boxIdx].r0 || boxes[a.boxIdx].c0 - boxes[b.boxIdx].c0
|
|
692
890
|
);
|
|
@@ -908,6 +1106,7 @@ var MAX_LINES = 400;
|
|
|
908
1106
|
var MAX_COLS = 400;
|
|
909
1107
|
var MIN_LINES = 3;
|
|
910
1108
|
var MAX_LOOSE_RATIO = 0.25;
|
|
1109
|
+
var ROUTING_ROW = /^[\s\u2500-\u257F+\-|^v<>\u25B2\u25BC\u25C0\u25B6\u25C4\u25BA\u2190\u2192\u2191\u2193]+$/;
|
|
911
1110
|
var STRUCTURAL_IN_LABEL = /[│┃║┌┐└┘├┤┬┴┼╭╮╰╯┏┓┗┛╔╗╚╝┣┫┳┻╋╠╣╦╩╬╞╡╥╨╫╪]/;
|
|
912
1111
|
function isEligibleAsciiFenceLang(lang) {
|
|
913
1112
|
if (lang === null || lang === void 0) return true;
|
|
@@ -940,8 +1139,14 @@ function detectAsciiDiagram(text, opts = {}) {
|
|
|
940
1139
|
const plusMatches = line.match(/\+[-+]/g);
|
|
941
1140
|
tlCandidates += plusMatches ? plusMatches.length : 0;
|
|
942
1141
|
}
|
|
943
|
-
|
|
944
|
-
|
|
1142
|
+
const routingRows = lines.filter(
|
|
1143
|
+
(line) => line.trim().length > 0 && ROUTING_ROW.test(line)
|
|
1144
|
+
).length;
|
|
1145
|
+
if (tlCandidates < 2 && routingRows < 2) {
|
|
1146
|
+
return {
|
|
1147
|
+
isDiagram: false,
|
|
1148
|
+
reasons: [`too-few-corner-candidates(${tlCandidates}) routing-rows(${routingRows})`]
|
|
1149
|
+
};
|
|
945
1150
|
}
|
|
946
1151
|
}
|
|
947
1152
|
const nonBlank = lines.filter((l) => l.trim().length > 0);
|
|
@@ -960,6 +1165,9 @@ function detectAsciiDiagram(text, opts = {}) {
|
|
|
960
1165
|
return { isDiagram: false, reasons: [`garbled-labels(${garbled}/${diagram.nodes.length})`] };
|
|
961
1166
|
}
|
|
962
1167
|
if (!explicit) {
|
|
1168
|
+
if (stats.boxNodes === 0 && diagram.edges.length === 0) {
|
|
1169
|
+
return { isDiagram: false, reasons: [`rail-labels-unconnected(${stats.railNodes})`] };
|
|
1170
|
+
}
|
|
963
1171
|
if (diagram.edges.length === 0 && diagram.nodes.length >= 4 && isLattice(diagram)) {
|
|
964
1172
|
return { isDiagram: false, reasons: ["table-lattice"] };
|
|
965
1173
|
}
|
|
@@ -1961,7 +2169,7 @@ function detectAsciiTimeline(text, options = {}) {
|
|
|
1961
2169
|
if (!explicit && lines.some((line) => BOX_TOP_EDGE_RE.test(line))) {
|
|
1962
2170
|
return { isTimeline: false, reasons: ["has-box-corners"] };
|
|
1963
2171
|
}
|
|
1964
|
-
const boxes = parseAsciiDiagramWithStats(text).
|
|
2172
|
+
const boxes = parseAsciiDiagramWithStats(text).stats.boxNodes;
|
|
1965
2173
|
if (boxes >= (explicit ? 2 : 1)) {
|
|
1966
2174
|
return { isTimeline: false, reasons: [`has-boxes(${boxes})`] };
|
|
1967
2175
|
}
|
|
@@ -2205,7 +2413,7 @@ function detectTree(text, opts = {}) {
|
|
|
2205
2413
|
if (!explicit && detectAsciiTimeline(text).isTimeline) {
|
|
2206
2414
|
return { isTree: false, reasons: ["is-timeline"] };
|
|
2207
2415
|
}
|
|
2208
|
-
const boxes = parseAsciiDiagramWithStats(text).
|
|
2416
|
+
const boxes = parseAsciiDiagramWithStats(text).stats.boxNodes;
|
|
2209
2417
|
if (boxes >= 2) {
|
|
2210
2418
|
return { isTree: false, reasons: [`has-boxes(${boxes})`] };
|
|
2211
2419
|
}
|
|
@@ -2488,6 +2696,7 @@ export {
|
|
|
2488
2696
|
isVert,
|
|
2489
2697
|
isJunction,
|
|
2490
2698
|
arrowDirection,
|
|
2699
|
+
isLineChar,
|
|
2491
2700
|
UNICODE_VOCAB,
|
|
2492
2701
|
ASCII_VOCAB,
|
|
2493
2702
|
MAX_BRIDGE_GAP,
|
|
@@ -40,14 +40,96 @@ function categorizeLintKind(kind) {
|
|
|
40
40
|
|
|
41
41
|
// src/proof/masking.ts
|
|
42
42
|
var ANNOTATION_RE = /\{\[[^\n]*?\]\}/g;
|
|
43
|
-
function blankProtectedSpans(text) {
|
|
43
|
+
function blankProtectedSpans(text, options = {}) {
|
|
44
|
+
const ranges = [];
|
|
45
|
+
ANNOTATION_RE.lastIndex = 0;
|
|
46
|
+
let match;
|
|
47
|
+
while ((match = ANNOTATION_RE.exec(text)) !== null) {
|
|
48
|
+
ranges.push({ start: match.index, end: match.index + match[0].length });
|
|
49
|
+
}
|
|
50
|
+
if (options.markdownCode) ranges.push(...markdownCodeRanges(text));
|
|
51
|
+
if (ranges.length === 0) return { text, blanked: [] };
|
|
52
|
+
ranges.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
44
53
|
const blanked = [];
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
for (const range of ranges) {
|
|
55
|
+
const last = blanked[blanked.length - 1];
|
|
56
|
+
if (last && range.start <= last.end) last.end = Math.max(last.end, range.end);
|
|
57
|
+
else blanked.push({ ...range });
|
|
58
|
+
}
|
|
59
|
+
let out = "";
|
|
60
|
+
let cursor = 0;
|
|
61
|
+
for (const range of blanked) {
|
|
62
|
+
out += text.slice(cursor, range.start);
|
|
63
|
+
out += text.slice(range.start, range.end).replace(/[^\n]/g, " ");
|
|
64
|
+
cursor = range.end;
|
|
65
|
+
}
|
|
66
|
+
out += text.slice(cursor);
|
|
49
67
|
return { text: out, blanked };
|
|
50
68
|
}
|
|
69
|
+
function markdownCodeRanges(text) {
|
|
70
|
+
const fences = fencedCodeRanges(text);
|
|
71
|
+
const ranges = [...fences];
|
|
72
|
+
let cursor = 0;
|
|
73
|
+
for (const fence of fences) {
|
|
74
|
+
collectInlineCodeRanges(text, cursor, fence.start, ranges);
|
|
75
|
+
cursor = fence.end;
|
|
76
|
+
}
|
|
77
|
+
collectInlineCodeRanges(text, cursor, text.length, ranges);
|
|
78
|
+
return ranges;
|
|
79
|
+
}
|
|
80
|
+
var FENCE_RE = /^( {0,3})(`{3,}|~{3,})(.*)$/;
|
|
81
|
+
function fencedCodeRanges(text) {
|
|
82
|
+
const ranges = [];
|
|
83
|
+
let lineStart = 0;
|
|
84
|
+
let open = null;
|
|
85
|
+
for (; ; ) {
|
|
86
|
+
const newline = text.indexOf("\n", lineStart);
|
|
87
|
+
const lineEnd = newline === -1 ? text.length : newline;
|
|
88
|
+
const match = FENCE_RE.exec(text.slice(lineStart, lineEnd));
|
|
89
|
+
if (!open) {
|
|
90
|
+
if (match) open = { start: lineStart, marker: match[2] };
|
|
91
|
+
} else if (match && // A closing fence is the same character, at least as long, and bare.
|
|
92
|
+
match[2][0] === open.marker[0] && match[2].length >= open.marker.length && match[3].trim() === "") {
|
|
93
|
+
ranges.push({ start: open.start, end: lineEnd });
|
|
94
|
+
open = null;
|
|
95
|
+
}
|
|
96
|
+
if (newline === -1) break;
|
|
97
|
+
lineStart = newline + 1;
|
|
98
|
+
}
|
|
99
|
+
if (open) ranges.push({ start: open.start, end: text.length });
|
|
100
|
+
return ranges;
|
|
101
|
+
}
|
|
102
|
+
function collectInlineCodeRanges(text, from, to, out) {
|
|
103
|
+
let i = from;
|
|
104
|
+
let openStart = -1;
|
|
105
|
+
let openLength = 0;
|
|
106
|
+
while (i < to) {
|
|
107
|
+
if (text[i] === "`") {
|
|
108
|
+
let run = 1;
|
|
109
|
+
while (i + run < to && text[i + run] === "`") run++;
|
|
110
|
+
if (openStart < 0) {
|
|
111
|
+
openStart = i;
|
|
112
|
+
openLength = run;
|
|
113
|
+
} else if (run === openLength) {
|
|
114
|
+
out.push({ start: openStart, end: i + run });
|
|
115
|
+
openStart = -1;
|
|
116
|
+
openLength = 0;
|
|
117
|
+
}
|
|
118
|
+
i += run;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (openStart >= 0 && text[i] === "\n" && startsBlankLine(text, i + 1, to)) {
|
|
122
|
+
openStart = -1;
|
|
123
|
+
openLength = 0;
|
|
124
|
+
}
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function startsBlankLine(text, index, to) {
|
|
129
|
+
let i = index;
|
|
130
|
+
while (i < to && (text[i] === " " || text[i] === " ")) i++;
|
|
131
|
+
return i >= to || text[i] === "\n";
|
|
132
|
+
}
|
|
51
133
|
function dropMaskedFindings(findings, blanked) {
|
|
52
134
|
if (blanked.length === 0) return [...findings];
|
|
53
135
|
return findings.filter(
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
templateRegistry,
|
|
31
31
|
writeCustomTemplatesToFrontmatter,
|
|
32
32
|
writeCustomThemesToFrontmatter
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-B26DU2RH.js";
|
|
34
34
|
import {
|
|
35
35
|
iconMarker
|
|
36
36
|
} from "./chunk-7ZAAICW4.js";
|
|
@@ -45,11 +45,12 @@ import {
|
|
|
45
45
|
detectAsciiDiagram,
|
|
46
46
|
isHoriz,
|
|
47
47
|
isJunction,
|
|
48
|
+
isLineChar,
|
|
48
49
|
isVert,
|
|
49
50
|
toCells,
|
|
50
51
|
toGrid,
|
|
51
52
|
traceBoxes
|
|
52
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-6ATZOUCQ.js";
|
|
53
54
|
import {
|
|
54
55
|
defaultPageStyle,
|
|
55
56
|
resolveMediaSchedule
|
|
@@ -5115,6 +5116,19 @@ function pickSides(s, t) {
|
|
|
5115
5116
|
gaps.sort((a, b) => a.gap - b.gap);
|
|
5116
5117
|
return { exit: gaps[0].side, enter: gaps[0].side };
|
|
5117
5118
|
}
|
|
5119
|
+
function blockedAttachmentColumns(p) {
|
|
5120
|
+
const blocked = /* @__PURE__ */ new Set();
|
|
5121
|
+
const innerW = p.rect.c1 - p.rect.c0 - 1;
|
|
5122
|
+
const lines = p.isContainer ? p.labelLines.slice(1) : p.labelLines;
|
|
5123
|
+
for (const line of lines) {
|
|
5124
|
+
const cells = toCells(line);
|
|
5125
|
+
const pad = Math.max(0, Math.floor((innerW - cells.length) / 2));
|
|
5126
|
+
cells.forEach((ch, j) => {
|
|
5127
|
+
if (isLineChar(ch)) blocked.add(p.rect.c0 + 1 + pad + j);
|
|
5128
|
+
});
|
|
5129
|
+
}
|
|
5130
|
+
return blocked;
|
|
5131
|
+
}
|
|
5118
5132
|
function assignAttachments(plans, placed) {
|
|
5119
5133
|
const bySide = /* @__PURE__ */ new Map();
|
|
5120
5134
|
plans.forEach((plan, i) => {
|
|
@@ -5143,13 +5157,31 @@ function assignAttachments(plans, placed) {
|
|
|
5143
5157
|
const to = horizontal ? node.rect.c1 - 1 : node.rect.r1 - 1;
|
|
5144
5158
|
const inner = Math.max(1, to - from + 1);
|
|
5145
5159
|
const k = list2.length;
|
|
5160
|
+
const blocked = horizontal ? blockedAttachmentColumns(node) : /* @__PURE__ */ new Set();
|
|
5161
|
+
const taken = [];
|
|
5162
|
+
const place = (want) => {
|
|
5163
|
+
const free = (pos) => pos >= from && pos <= to && !blocked.has(pos) && taken.every((t) => Math.abs(t - pos) >= 2);
|
|
5164
|
+
for (let d = 0; d <= inner; d++) {
|
|
5165
|
+
for (const pos of d === 0 ? [want] : [want - d, want + d]) {
|
|
5166
|
+
if (!free(pos)) continue;
|
|
5167
|
+
taken.push(pos);
|
|
5168
|
+
return pos;
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5171
|
+
taken.push(want);
|
|
5172
|
+
return want;
|
|
5173
|
+
};
|
|
5146
5174
|
if (k === 1) {
|
|
5147
|
-
result.set(list2[0].key, {
|
|
5175
|
+
result.set(list2[0].key, {
|
|
5176
|
+
pos: place(from + Math.floor((inner - 1) / 2)),
|
|
5177
|
+
index: 0,
|
|
5178
|
+
count: 1
|
|
5179
|
+
});
|
|
5148
5180
|
} else {
|
|
5149
5181
|
const span = 2 * k - 1;
|
|
5150
5182
|
const start = from + Math.max(0, Math.floor((inner - span) / 2));
|
|
5151
5183
|
list2.forEach((req, i) => {
|
|
5152
|
-
result.set(req.key, { pos: Math.min(to, start + 2 * i), index: i, count: k });
|
|
5184
|
+
result.set(req.key, { pos: place(Math.min(to, start + 2 * i)), index: i, count: k });
|
|
5153
5185
|
});
|
|
5154
5186
|
}
|
|
5155
5187
|
}
|
package/dist/doc/index.js
CHANGED
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
validateMarkdownDoc,
|
|
71
71
|
validateMarkdownSource,
|
|
72
72
|
writeDashboardLayoutsToFrontmatter
|
|
73
|
-
} from "../chunk-
|
|
73
|
+
} from "../chunk-QQ4I5HWV.js";
|
|
74
74
|
import {
|
|
75
75
|
ASCII_CHAR_H,
|
|
76
76
|
ASCII_CHAR_W,
|
|
@@ -192,7 +192,7 @@ import {
|
|
|
192
192
|
wrapWithPersistentLayers,
|
|
193
193
|
writeCustomTemplatesToFrontmatter,
|
|
194
194
|
writeCustomThemesToFrontmatter
|
|
195
|
-
} from "../chunk-
|
|
195
|
+
} from "../chunk-B26DU2RH.js";
|
|
196
196
|
import {
|
|
197
197
|
PATH_SHAPE_KINDS,
|
|
198
198
|
anchorPoint,
|
|
@@ -229,7 +229,7 @@ import {
|
|
|
229
229
|
parseAsciiTimelineWithStats,
|
|
230
230
|
parseTree,
|
|
231
231
|
parseWrappedFlowTimeline
|
|
232
|
-
} from "../chunk-
|
|
232
|
+
} from "../chunk-6ATZOUCQ.js";
|
|
233
233
|
import "../chunk-GAZKTT4R.js";
|
|
234
234
|
import {
|
|
235
235
|
DEFAULT_THEME,
|
package/dist/index.d.ts
CHANGED
|
@@ -26,5 +26,5 @@ export { IconSuggestion, canonicalIconToken, iconGlyph, looksLikeIconToken, reso
|
|
|
26
26
|
export { BlockContentProfile, RecommendationResult, profileBlockContents, recommendTemplatesForBlock } from './recommend/index.js';
|
|
27
27
|
export { AdvanceCoverage, AlignConfig, AlignInput, BandpassState, BuildAdvanceTimingOptions, BuildNarrationTimingOptions, BuildScriptOptions, DEFAULT_ALIGN_CONFIG, DEFAULT_FEATURE_CONFIG, DEFAULT_NUCLEI_CONFIG, DEFAULT_PACING_CONFIG, DEFAULT_VAD_CONFIG, EMPTY_ADVANCE_LOG, FeatureConfig, FeatureState, FrameFeatures, NarrationAlignment, NarrationBlockRange, NarrationScript, NarrationSessionConfig, NarrationSessionState, NarrationTimingBlock, NarrationTimingJsonV3, NarrationTimingMethod, NarrationTrace, NucleiConfig, NucleiState, PacingConfig, PacingState, PacingTick, ScriptBlockRange, ScriptToken, SlideAdvance, SlideAdvanceLog, TraceSample, VadConfig, VadState, WordTiming, advanceCoverage, alignNarration, bandpassRun, buildAdvanceTimingJson, buildNarrationScript, buildNarrationTimingJson, createBandpass, createFeatureState, createNarrationSession, createNucleiState, createPacingState, createVadState, detectSyllableOnsets, downsampleTrace, estimateSyllables, expectedSyllablesAt, extractFrameFeatures, featureStep, narrationSessionStep, nucleiStep, pacingStep, parseNarrationTimingJson, reanchorPacing, reanchorSession, recordSlideShown, traceWordPosAt, vadStep, wordIndexAtChar, wordIndexAtTime, wordPosAtExpectedSyllables } from './narration/index.js';
|
|
28
28
|
export { FenceRenderContext, FenceRenderer, FenceRendererMap, fenceRendererLangs } from './fence/index.js';
|
|
29
|
-
export { BlankedText, DEFAULT_PROOF_SETTINGS, JoinedSegments, LINT_KIND_CATEGORIES, PROOF_DIALECTS, PROOF_FRONTMATTER_KEYS, PROOF_JOIN_SEPARATOR, ProofCategory, ProofDialect, ProofFinding, ProofRange, ProofSuggestion, ProofSuggestionKind, ProofingSettings, SegmentSpan, blankProtectedSpans, buildJoinedText, categorizeLintKind, dropMaskedFindings, formatProofDictionary, mapJoinedSpanToSegment, parseProofDictionary, readProofingSettings, resolveProofDialect } from './proof/index.js';
|
|
29
|
+
export { BlankProtectedSpansOptions, BlankedText, DEFAULT_PROOF_SETTINGS, JoinedSegments, LINT_KIND_CATEGORIES, PROOF_DIALECTS, PROOF_FRONTMATTER_KEYS, PROOF_JOIN_SEPARATOR, ProofCategory, ProofDialect, ProofFinding, ProofRange, ProofSuggestion, ProofSuggestionKind, ProofingSettings, SegmentSpan, blankProtectedSpans, buildJoinedText, categorizeLintKind, dropMaskedFindings, formatProofDictionary, mapJoinedSpanToSegment, parseProofDictionary, readProofingSettings, resolveProofDialect } from './proof/index.js';
|
|
30
30
|
import './viewState-lTZS-hP_.js';
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
recordSlideShown,
|
|
28
28
|
traceWordPosAt,
|
|
29
29
|
vadStep
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-UXKFSYTQ.js";
|
|
31
31
|
import {
|
|
32
32
|
fenceRendererLangs
|
|
33
33
|
} from "./chunk-PGI7HSWE.js";
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
parseProofDictionary,
|
|
47
47
|
readProofingSettings,
|
|
48
48
|
resolveProofDialect
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-B3AK7SLZ.js";
|
|
50
50
|
import {
|
|
51
51
|
DEFAULT_TRANSFORM_STYLE_ID,
|
|
52
52
|
analyzeBlocks,
|
|
@@ -227,7 +227,7 @@ import {
|
|
|
227
227
|
validateMarkdownDoc,
|
|
228
228
|
validateMarkdownSource,
|
|
229
229
|
writeDashboardLayoutsToFrontmatter
|
|
230
|
-
} from "./chunk-
|
|
230
|
+
} from "./chunk-QQ4I5HWV.js";
|
|
231
231
|
import {
|
|
232
232
|
ASCII_CHAR_H,
|
|
233
233
|
ASCII_CHAR_W,
|
|
@@ -357,7 +357,7 @@ import {
|
|
|
357
357
|
wrapWithPersistentLayers,
|
|
358
358
|
writeCustomTemplatesToFrontmatter,
|
|
359
359
|
writeCustomThemesToFrontmatter
|
|
360
|
-
} from "./chunk-
|
|
360
|
+
} from "./chunk-B26DU2RH.js";
|
|
361
361
|
import {
|
|
362
362
|
PATH_SHAPE_KINDS,
|
|
363
363
|
anchorPoint,
|
|
@@ -402,7 +402,7 @@ import {
|
|
|
402
402
|
parseWrappedFlowTimeline,
|
|
403
403
|
profileBlockContents,
|
|
404
404
|
recommendTemplatesForBlock
|
|
405
|
-
} from "./chunk-
|
|
405
|
+
} from "./chunk-6ATZOUCQ.js";
|
|
406
406
|
import {
|
|
407
407
|
defaultPageStyle,
|
|
408
408
|
getDocPlaybackDuration,
|
package/dist/narration/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
recordSlideShown,
|
|
28
28
|
traceWordPosAt,
|
|
29
29
|
vadStep
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-UXKFSYTQ.js";
|
|
31
31
|
import {
|
|
32
32
|
buildNarrationScript,
|
|
33
33
|
buildNarrationTimingJson,
|
|
@@ -37,9 +37,9 @@ import {
|
|
|
37
37
|
wordIndexAtChar,
|
|
38
38
|
wordIndexAtTime,
|
|
39
39
|
wordPosAtExpectedSyllables
|
|
40
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-B26DU2RH.js";
|
|
41
41
|
import "../chunk-PUS54YU6.js";
|
|
42
|
-
import "../chunk-
|
|
42
|
+
import "../chunk-6ATZOUCQ.js";
|
|
43
43
|
import "../chunk-SBAX4ZPO.js";
|
|
44
44
|
import "../chunk-BAOV476U.js";
|
|
45
45
|
import "../chunk-TMOHAFYE.js";
|
package/dist/proof/index.d.ts
CHANGED
|
@@ -73,6 +73,15 @@ declare function categorizeLintKind(kind: string): ProofCategory;
|
|
|
73
73
|
* spaces — every surrounding offset stays byte-identical — and afterwards
|
|
74
74
|
* drop any finding that intersects a blanked range (which also swallows
|
|
75
75
|
* the whitespace-formatting lints the blank runs themselves can induce).
|
|
76
|
+
*
|
|
77
|
+
* MARKDOWN SOURCE carries a second family of machine vocabulary: code.
|
|
78
|
+
* A fence is a program, and an inline span is an identifier or a signature
|
|
79
|
+
* (``raycast(origin, dir, maxDist)`` draws a spelling lint on every one of
|
|
80
|
+
* those words), so `markdownCode` blanks both. It is off by default because
|
|
81
|
+
* it is only meaningful for source text: the Write view lints the editor's
|
|
82
|
+
* PLAIN TEXT, where code is a ProseMirror mark with no backticks to find
|
|
83
|
+
* (`writeViewText.ts` blanks it during collection instead). Newlines are
|
|
84
|
+
* never blanked, so a line/column mapping over the result stays exact.
|
|
76
85
|
*/
|
|
77
86
|
|
|
78
87
|
interface BlankedText {
|
|
@@ -81,8 +90,18 @@ interface BlankedText {
|
|
|
81
90
|
/** The replaced ranges, in ascending order. */
|
|
82
91
|
blanked: ProofRange[];
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
|
|
93
|
+
interface BlankProtectedSpansOptions {
|
|
94
|
+
/**
|
|
95
|
+
* Also blank markdown code: fenced blocks (delimiters and info string
|
|
96
|
+
* included) and inline code spans. Only correct for markdown SOURCE text.
|
|
97
|
+
*/
|
|
98
|
+
markdownCode?: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Blank protected spans to equal-length runs of spaces: `{[…]}` annotations
|
|
102
|
+
* always, and markdown code when `markdownCode` is set.
|
|
103
|
+
*/
|
|
104
|
+
declare function blankProtectedSpans(text: string, options?: BlankProtectedSpansOptions): BlankedText;
|
|
86
105
|
/** Keep only findings whose span does not intersect any blanked range. */
|
|
87
106
|
declare function dropMaskedFindings<T extends ProofRange>(findings: readonly T[], blanked: readonly ProofRange[]): T[];
|
|
88
107
|
|
|
@@ -176,4 +195,4 @@ declare function formatProofDictionary(words: readonly string[]): string | null;
|
|
|
176
195
|
/** Read all proofing settings from a parsed frontmatter record. */
|
|
177
196
|
declare function readProofingSettings(frontmatter: Record<string, unknown> | undefined): ProofingSettings;
|
|
178
197
|
|
|
179
|
-
export { type BlankedText, DEFAULT_PROOF_SETTINGS, type JoinedSegments, LINT_KIND_CATEGORIES, PROOF_DIALECTS, PROOF_FRONTMATTER_KEYS, PROOF_JOIN_SEPARATOR, type ProofCategory, type ProofDialect, type ProofFinding, type ProofRange, type ProofSuggestion, type ProofSuggestionKind, type ProofingSettings, type SegmentSpan, blankProtectedSpans, buildJoinedText, categorizeLintKind, dropMaskedFindings, formatProofDictionary, mapJoinedSpanToSegment, parseProofDictionary, readProofingSettings, resolveProofDialect };
|
|
198
|
+
export { type BlankProtectedSpansOptions, type BlankedText, DEFAULT_PROOF_SETTINGS, type JoinedSegments, LINT_KIND_CATEGORIES, PROOF_DIALECTS, PROOF_FRONTMATTER_KEYS, PROOF_JOIN_SEPARATOR, type ProofCategory, type ProofDialect, type ProofFinding, type ProofRange, type ProofSuggestion, type ProofSuggestionKind, type ProofingSettings, type SegmentSpan, blankProtectedSpans, buildJoinedText, categorizeLintKind, dropMaskedFindings, formatProofDictionary, mapJoinedSpanToSegment, parseProofDictionary, readProofingSettings, resolveProofDialect };
|
package/dist/proof/index.js
CHANGED
package/dist/recommend/index.js
CHANGED