pickier 0.1.24 → 0.1.25
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/bin/cli.js +225 -60
- package/dist/src/index.js +224 -59
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -16536,6 +16536,7 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16536
16536
|
if (openParenIdx !== -1) {
|
|
16537
16537
|
let isTypeSignature = false;
|
|
16538
16538
|
let angleDepthBack = 0;
|
|
16539
|
+
let parenDepthBack = 0;
|
|
16539
16540
|
for (let k = openParenIdx - 1;k >= 0; k--) {
|
|
16540
16541
|
const ch = line[k];
|
|
16541
16542
|
if (ch === ">") {
|
|
@@ -16547,10 +16548,13 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16547
16548
|
angleDepthBack--;
|
|
16548
16549
|
continue;
|
|
16549
16550
|
}
|
|
16550
|
-
|
|
16551
|
-
|
|
16551
|
+
if (parenDepthBack === 0) {
|
|
16552
|
+
isTypeSignature = true;
|
|
16553
|
+
break;
|
|
16554
|
+
}
|
|
16555
|
+
continue;
|
|
16552
16556
|
}
|
|
16553
|
-
if (ch === ":" && angleDepthBack === 0) {
|
|
16557
|
+
if (ch === ":" && angleDepthBack === 0 && parenDepthBack === 0) {
|
|
16554
16558
|
isTypeSignature = true;
|
|
16555
16559
|
break;
|
|
16556
16560
|
}
|
|
@@ -16558,11 +16562,34 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16558
16562
|
continue;
|
|
16559
16563
|
if (ch === ",")
|
|
16560
16564
|
continue;
|
|
16561
|
-
if (ch === "
|
|
16565
|
+
if (ch === ")") {
|
|
16566
|
+
parenDepthBack++;
|
|
16567
|
+
continue;
|
|
16568
|
+
}
|
|
16569
|
+
if (ch === "(") {
|
|
16570
|
+
parenDepthBack--;
|
|
16571
|
+
continue;
|
|
16572
|
+
}
|
|
16573
|
+
if (ch === "|" || ch === "&") {
|
|
16574
|
+
isTypeSignature = true;
|
|
16562
16575
|
break;
|
|
16563
16576
|
}
|
|
16577
|
+
if (ch === "=" || ch === "{" || ch === "[") {
|
|
16578
|
+
if (parenDepthBack >= 0)
|
|
16579
|
+
break;
|
|
16580
|
+
continue;
|
|
16581
|
+
}
|
|
16564
16582
|
if (ch !== " " && ch !== "\t" && !/[\w.]/.test(ch)) {
|
|
16565
|
-
|
|
16583
|
+
if (parenDepthBack >= 0)
|
|
16584
|
+
break;
|
|
16585
|
+
}
|
|
16586
|
+
}
|
|
16587
|
+
if (!isTypeSignature) {
|
|
16588
|
+
const beforeParen = line.slice(0, openParenIdx);
|
|
16589
|
+
if (/^\s*(?:export\s+)?(?:declare\s+)?type\s+\w[\w$]*\s*(?:<[^>]*>)?\s*=\s*$/.test(beforeParen)) {
|
|
16590
|
+
isTypeSignature = true;
|
|
16591
|
+
} else if (/\bas\s+$/.test(beforeParen)) {
|
|
16592
|
+
isTypeSignature = true;
|
|
16566
16593
|
}
|
|
16567
16594
|
}
|
|
16568
16595
|
if (isTypeSignature) {
|
|
@@ -19392,6 +19419,42 @@ var init_link_image_reference_definitions = __esm(() => {
|
|
|
19392
19419
|
}
|
|
19393
19420
|
}
|
|
19394
19421
|
return issues;
|
|
19422
|
+
},
|
|
19423
|
+
fix: (text) => {
|
|
19424
|
+
const lines = text.split(/\r?\n/);
|
|
19425
|
+
const inCode = getCodeBlockLines(lines);
|
|
19426
|
+
const defLines = new Map;
|
|
19427
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19428
|
+
if (inCode.has(i))
|
|
19429
|
+
continue;
|
|
19430
|
+
const m = lines[i].match(/^\s*\[([^\]]+)\]:\s*\S+/);
|
|
19431
|
+
if (m)
|
|
19432
|
+
defLines.set(i, m[1].toLowerCase());
|
|
19433
|
+
}
|
|
19434
|
+
if (defLines.size === 0)
|
|
19435
|
+
return text;
|
|
19436
|
+
const usages = new Set;
|
|
19437
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19438
|
+
if (inCode.has(i))
|
|
19439
|
+
continue;
|
|
19440
|
+
if (defLines.has(i))
|
|
19441
|
+
continue;
|
|
19442
|
+
const line = lines[i];
|
|
19443
|
+
const refMatches = line.matchAll(/\[([^\]]+)\](?:\[([^\]]*)\])?(?!\()/g);
|
|
19444
|
+
for (const m of refMatches) {
|
|
19445
|
+
const label = (m[2] && m[2].length > 0 ? m[2] : m[1]).toLowerCase();
|
|
19446
|
+
usages.add(label);
|
|
19447
|
+
}
|
|
19448
|
+
}
|
|
19449
|
+
const toRemove = new Set;
|
|
19450
|
+
for (const [idx, label] of defLines) {
|
|
19451
|
+
if (!usages.has(label))
|
|
19452
|
+
toRemove.add(idx);
|
|
19453
|
+
}
|
|
19454
|
+
if (toRemove.size === 0)
|
|
19455
|
+
return text;
|
|
19456
|
+
return lines.filter((_, idx) => !toRemove.has(idx)).join(`
|
|
19457
|
+
`);
|
|
19395
19458
|
}
|
|
19396
19459
|
};
|
|
19397
19460
|
});
|
|
@@ -19409,19 +19472,39 @@ var init_link_image_style = __esm(() => {
|
|
|
19409
19472
|
check: (text, ctx) => {
|
|
19410
19473
|
const issues = [];
|
|
19411
19474
|
const lines = text.split(/\r?\n/);
|
|
19475
|
+
const inCode = getCodeBlockLines(lines);
|
|
19412
19476
|
const options = ctx.options || {};
|
|
19413
19477
|
const style = options.style || "consistent";
|
|
19414
|
-
let
|
|
19415
|
-
|
|
19478
|
+
let target = style === "consistent" ? null : style;
|
|
19479
|
+
if (target === null) {
|
|
19480
|
+
let inlineCount = 0;
|
|
19481
|
+
let refCount = 0;
|
|
19482
|
+
let inHtmlCommentScan = false;
|
|
19483
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19484
|
+
if (inCode.has(i))
|
|
19485
|
+
continue;
|
|
19486
|
+
const line = lines[i];
|
|
19487
|
+
if (line.includes("<!--"))
|
|
19488
|
+
inHtmlCommentScan = true;
|
|
19489
|
+
if (line.includes("-->")) {
|
|
19490
|
+
inHtmlCommentScan = false;
|
|
19491
|
+
continue;
|
|
19492
|
+
}
|
|
19493
|
+
if (inHtmlCommentScan)
|
|
19494
|
+
continue;
|
|
19495
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(line))
|
|
19496
|
+
continue;
|
|
19497
|
+
const scrubbed = stripInlineCode(line);
|
|
19498
|
+
inlineCount += (scrubbed.match(/\[[^\]]+\]\([^)]+\)/g) || []).length;
|
|
19499
|
+
refCount += (scrubbed.match(/\[[^\]]+\]\[(?:[^\]]*)\]/g) || []).length;
|
|
19500
|
+
}
|
|
19501
|
+
target = refCount > inlineCount ? "reference" : "inline";
|
|
19502
|
+
}
|
|
19416
19503
|
let inHtmlComment = false;
|
|
19417
19504
|
for (let i = 0;i < lines.length; i++) {
|
|
19418
|
-
|
|
19419
|
-
if (/^(?:`{3,}|~{3,})/.test(line.trim())) {
|
|
19420
|
-
inFence = !inFence;
|
|
19421
|
-
continue;
|
|
19422
|
-
}
|
|
19423
|
-
if (inFence)
|
|
19505
|
+
if (inCode.has(i))
|
|
19424
19506
|
continue;
|
|
19507
|
+
const line = lines[i];
|
|
19425
19508
|
if (line.includes("<!--"))
|
|
19426
19509
|
inHtmlComment = true;
|
|
19427
19510
|
if (line.includes("-->")) {
|
|
@@ -19430,64 +19513,104 @@ var init_link_image_style = __esm(() => {
|
|
|
19430
19513
|
}
|
|
19431
19514
|
if (inHtmlComment)
|
|
19432
19515
|
continue;
|
|
19433
|
-
if (line.match(/^\[(?:[^\]]+)\]:\s*\S+/))
|
|
19516
|
+
if (line.match(/^\[(?:[^\]]+)\]:\s*\S+/))
|
|
19434
19517
|
continue;
|
|
19435
|
-
}
|
|
19436
19518
|
const scrubbed = stripInlineCode(line);
|
|
19437
19519
|
const inlineMatches = scrubbed.matchAll(/\[[^\]]+\]\([^)]+\)/g);
|
|
19438
19520
|
for (const match of inlineMatches) {
|
|
19439
|
-
if (
|
|
19521
|
+
if (target === "reference") {
|
|
19440
19522
|
issues.push({
|
|
19441
19523
|
filePath: ctx.filePath,
|
|
19442
19524
|
line: i + 1,
|
|
19443
19525
|
column: match.index + 1,
|
|
19444
19526
|
ruleId: "markdown/link-image-style",
|
|
19445
|
-
message: "Expected reference style link",
|
|
19446
|
-
severity: "error"
|
|
19527
|
+
message: style === "consistent" ? "Link style should be consistent throughout document" : "Expected reference style link",
|
|
19528
|
+
severity: style === "consistent" ? "warning" : "error"
|
|
19447
19529
|
});
|
|
19448
|
-
} else if (style === "consistent") {
|
|
19449
|
-
if (detectedStyle === null) {
|
|
19450
|
-
detectedStyle = "inline";
|
|
19451
|
-
} else if (detectedStyle === "reference") {
|
|
19452
|
-
issues.push({
|
|
19453
|
-
filePath: ctx.filePath,
|
|
19454
|
-
line: i + 1,
|
|
19455
|
-
column: match.index + 1,
|
|
19456
|
-
ruleId: "markdown/link-image-style",
|
|
19457
|
-
message: "Link style should be consistent throughout document",
|
|
19458
|
-
severity: "warning"
|
|
19459
|
-
});
|
|
19460
|
-
}
|
|
19461
19530
|
}
|
|
19462
19531
|
}
|
|
19463
19532
|
const refMatches = scrubbed.matchAll(/\[[^\]]+\]\[(?:[^\]]+)\]/g);
|
|
19464
19533
|
for (const match of refMatches) {
|
|
19465
|
-
if (
|
|
19534
|
+
if (target === "inline") {
|
|
19466
19535
|
issues.push({
|
|
19467
19536
|
filePath: ctx.filePath,
|
|
19468
19537
|
line: i + 1,
|
|
19469
19538
|
column: match.index + 1,
|
|
19470
19539
|
ruleId: "markdown/link-image-style",
|
|
19471
|
-
message: "Expected inline style link",
|
|
19472
|
-
severity: "error"
|
|
19540
|
+
message: style === "consistent" ? "Link style should be consistent throughout document" : "Expected inline style link",
|
|
19541
|
+
severity: style === "consistent" ? "warning" : "error"
|
|
19473
19542
|
});
|
|
19474
|
-
} else if (style === "consistent") {
|
|
19475
|
-
if (detectedStyle === null) {
|
|
19476
|
-
detectedStyle = "reference";
|
|
19477
|
-
} else if (detectedStyle === "inline") {
|
|
19478
|
-
issues.push({
|
|
19479
|
-
filePath: ctx.filePath,
|
|
19480
|
-
line: i + 1,
|
|
19481
|
-
column: match.index + 1,
|
|
19482
|
-
ruleId: "markdown/link-image-style",
|
|
19483
|
-
message: "Link style should be consistent throughout document",
|
|
19484
|
-
severity: "warning"
|
|
19485
|
-
});
|
|
19486
|
-
}
|
|
19487
19543
|
}
|
|
19488
19544
|
}
|
|
19489
19545
|
}
|
|
19490
19546
|
return issues;
|
|
19547
|
+
},
|
|
19548
|
+
fix: (text, ctx) => {
|
|
19549
|
+
const options = ctx.options || {};
|
|
19550
|
+
const style = options.style || "consistent";
|
|
19551
|
+
const lines = text.split(/\r?\n/);
|
|
19552
|
+
const inCode = getCodeBlockLines(lines);
|
|
19553
|
+
const defs = new Map;
|
|
19554
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19555
|
+
if (inCode.has(i))
|
|
19556
|
+
continue;
|
|
19557
|
+
const m = lines[i].match(/^\s*\[([^\]]+)\]:\s*(\S+)(?:\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\)))?\s*$/);
|
|
19558
|
+
if (m) {
|
|
19559
|
+
const label = m[1].toLowerCase();
|
|
19560
|
+
const url = m[2];
|
|
19561
|
+
const title = m[3] ?? m[4] ?? m[5];
|
|
19562
|
+
if (!defs.has(label))
|
|
19563
|
+
defs.set(label, { url, title });
|
|
19564
|
+
}
|
|
19565
|
+
}
|
|
19566
|
+
if (defs.size === 0)
|
|
19567
|
+
return text;
|
|
19568
|
+
let target = style === "reference" ? "reference" : "inline";
|
|
19569
|
+
if (style === "consistent") {
|
|
19570
|
+
let inlineCount = 0;
|
|
19571
|
+
let refCount = 0;
|
|
19572
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19573
|
+
if (inCode.has(i))
|
|
19574
|
+
continue;
|
|
19575
|
+
const line = lines[i];
|
|
19576
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(line))
|
|
19577
|
+
continue;
|
|
19578
|
+
const scrubbed = stripInlineCode(line);
|
|
19579
|
+
inlineCount += (scrubbed.match(/\[[^\]]+\]\([^)]+\)/g) || []).length;
|
|
19580
|
+
refCount += (scrubbed.match(/\[[^\]]+\]\[(?:[^\]]*)\]/g) || []).length;
|
|
19581
|
+
}
|
|
19582
|
+
target = refCount > inlineCount ? "reference" : "inline";
|
|
19583
|
+
}
|
|
19584
|
+
if (target !== "inline")
|
|
19585
|
+
return text;
|
|
19586
|
+
let changed = false;
|
|
19587
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19588
|
+
if (inCode.has(i))
|
|
19589
|
+
continue;
|
|
19590
|
+
const original = lines[i];
|
|
19591
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(original))
|
|
19592
|
+
continue;
|
|
19593
|
+
let rewritten = original;
|
|
19594
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
19595
|
+
const next = rewritten.replace(/(!?)\[((?:[^[\]]|\[[^\]]*\]\([^)]*\))+)\]\[([^\]]*)\]/g, (whole, bang, textPart, labelPart) => {
|
|
19596
|
+
const labelKey = (labelPart.trim() === "" ? textPart : labelPart).toLowerCase();
|
|
19597
|
+
const def = defs.get(labelKey);
|
|
19598
|
+
if (!def)
|
|
19599
|
+
return whole;
|
|
19600
|
+
const titlePart = def.title ? ` "${def.title}"` : "";
|
|
19601
|
+
return `${bang}[${textPart}](${def.url}${titlePart})`;
|
|
19602
|
+
});
|
|
19603
|
+
if (next === rewritten)
|
|
19604
|
+
break;
|
|
19605
|
+
rewritten = next;
|
|
19606
|
+
}
|
|
19607
|
+
if (rewritten !== original) {
|
|
19608
|
+
lines[i] = rewritten;
|
|
19609
|
+
changed = true;
|
|
19610
|
+
}
|
|
19611
|
+
}
|
|
19612
|
+
return changed ? lines.join(`
|
|
19613
|
+
`) : text;
|
|
19491
19614
|
}
|
|
19492
19615
|
};
|
|
19493
19616
|
});
|
|
@@ -20891,24 +21014,18 @@ var init_single_title = __esm(() => {
|
|
|
20891
21014
|
check: (text, ctx) => {
|
|
20892
21015
|
const issues = [];
|
|
20893
21016
|
const lines = text.split(/\r?\n/);
|
|
21017
|
+
const inCode = getCodeBlockLines(lines);
|
|
20894
21018
|
let firstH1Line = -1;
|
|
20895
|
-
let inFencedCodeBlock = false;
|
|
20896
21019
|
for (let i = 0;i < lines.length; i++) {
|
|
21020
|
+
if (inCode.has(i))
|
|
21021
|
+
continue;
|
|
20897
21022
|
const line = lines[i];
|
|
20898
21023
|
const nextLine = i + 1 < lines.length ? lines[i + 1] : "";
|
|
20899
|
-
if (/^(?:`{3,}|~{3,})/.test(line.trim())) {
|
|
20900
|
-
inFencedCodeBlock = !inFencedCodeBlock;
|
|
20901
|
-
continue;
|
|
20902
|
-
}
|
|
20903
|
-
if (inFencedCodeBlock)
|
|
20904
|
-
continue;
|
|
20905
21024
|
let isH1 = false;
|
|
20906
|
-
if (/^#\s/.test(line))
|
|
21025
|
+
if (/^#\s/.test(line))
|
|
20907
21026
|
isH1 = true;
|
|
20908
|
-
|
|
20909
|
-
if (/^=+\s*$/.test(nextLine) && line.trim().length > 0) {
|
|
21027
|
+
if (/^=+\s*$/.test(nextLine) && line.trim().length > 0 && !inCode.has(i + 1))
|
|
20910
21028
|
isH1 = true;
|
|
20911
|
-
}
|
|
20912
21029
|
if (isH1) {
|
|
20913
21030
|
if (firstH1Line === -1) {
|
|
20914
21031
|
firstH1Line = i + 1;
|
|
@@ -20925,6 +21042,47 @@ var init_single_title = __esm(() => {
|
|
|
20925
21042
|
}
|
|
20926
21043
|
}
|
|
20927
21044
|
return issues;
|
|
21045
|
+
},
|
|
21046
|
+
fix: (text) => {
|
|
21047
|
+
const lines = text.split(/\r?\n/);
|
|
21048
|
+
const inCode = getCodeBlockLines(lines);
|
|
21049
|
+
const result = [];
|
|
21050
|
+
let seenH1 = false;
|
|
21051
|
+
let changed = false;
|
|
21052
|
+
for (let i = 0;i < lines.length; i++) {
|
|
21053
|
+
if (inCode.has(i)) {
|
|
21054
|
+
result.push(lines[i]);
|
|
21055
|
+
continue;
|
|
21056
|
+
}
|
|
21057
|
+
const line = lines[i];
|
|
21058
|
+
const nextLine = i + 1 < lines.length ? lines[i + 1] : "";
|
|
21059
|
+
const atxH1 = /^#\s/.test(line);
|
|
21060
|
+
const setextH1 = /^=+\s*$/.test(nextLine) && line.trim().length > 0 && !inCode.has(i + 1);
|
|
21061
|
+
if (atxH1) {
|
|
21062
|
+
if (!seenH1) {
|
|
21063
|
+
seenH1 = true;
|
|
21064
|
+
result.push(line);
|
|
21065
|
+
} else {
|
|
21066
|
+
result.push(`#${line}`);
|
|
21067
|
+
changed = true;
|
|
21068
|
+
}
|
|
21069
|
+
continue;
|
|
21070
|
+
}
|
|
21071
|
+
if (setextH1) {
|
|
21072
|
+
if (!seenH1) {
|
|
21073
|
+
seenH1 = true;
|
|
21074
|
+
result.push(line);
|
|
21075
|
+
continue;
|
|
21076
|
+
}
|
|
21077
|
+
result.push(`## ${line.trim()}`);
|
|
21078
|
+
i++;
|
|
21079
|
+
changed = true;
|
|
21080
|
+
continue;
|
|
21081
|
+
}
|
|
21082
|
+
result.push(line);
|
|
21083
|
+
}
|
|
21084
|
+
return changed ? result.join(`
|
|
21085
|
+
`) : text;
|
|
20928
21086
|
}
|
|
20929
21087
|
};
|
|
20930
21088
|
});
|
|
@@ -21525,6 +21683,13 @@ function splitFrontmatter(content) {
|
|
|
21525
21683
|
}
|
|
21526
21684
|
return { header: null, body: content };
|
|
21527
21685
|
}
|
|
21686
|
+
function markdownOnlyWholeFile(rule) {
|
|
21687
|
+
return {
|
|
21688
|
+
meta: rule.meta,
|
|
21689
|
+
check: (content, context) => context.filePath.endsWith(".md") ? rule.check(content, context) : [],
|
|
21690
|
+
fix: rule.fix ? (content, context) => context.filePath.endsWith(".md") ? rule.fix(content, context) : content : undefined
|
|
21691
|
+
};
|
|
21692
|
+
}
|
|
21528
21693
|
function markdownOnly(rule) {
|
|
21529
21694
|
return {
|
|
21530
21695
|
meta: rule.meta,
|
|
@@ -21632,7 +21797,7 @@ var init_markdown = __esm(() => {
|
|
|
21632
21797
|
"no-multiple-space-blockquote": markdownOnly(noMultipleSpaceBlockquoteRule),
|
|
21633
21798
|
"no-blanks-blockquote": markdownOnly(noBlanksBlockquoteRule),
|
|
21634
21799
|
"blanks-around-fences": markdownOnly(blanksAroundFencesRule),
|
|
21635
|
-
"single-trailing-newline":
|
|
21800
|
+
"single-trailing-newline": markdownOnlyWholeFile(singleTrailingNewlineRule),
|
|
21636
21801
|
"blanks-around-tables": markdownOnly(blanksAroundTablesRule),
|
|
21637
21802
|
"no-reversed-links": markdownOnly(noReversedLinksRule),
|
|
21638
21803
|
"no-bare-urls": markdownOnly(noBareUrlsRule),
|
|
@@ -37920,7 +38085,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
37920
38085
|
module.exports = {
|
|
37921
38086
|
name: "pickier",
|
|
37922
38087
|
type: "module",
|
|
37923
|
-
version: "0.1.
|
|
38088
|
+
version: "0.1.25",
|
|
37924
38089
|
description: "Format, lint and more in a fraction of seconds.",
|
|
37925
38090
|
author: "Chris Breuer <chris@stacksjs.org>",
|
|
37926
38091
|
license: "MIT",
|
package/dist/src/index.js
CHANGED
|
@@ -16153,6 +16153,7 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16153
16153
|
if (openParenIdx !== -1) {
|
|
16154
16154
|
let isTypeSignature = false;
|
|
16155
16155
|
let angleDepthBack = 0;
|
|
16156
|
+
let parenDepthBack = 0;
|
|
16156
16157
|
for (let k = openParenIdx - 1;k >= 0; k--) {
|
|
16157
16158
|
const ch = line[k];
|
|
16158
16159
|
if (ch === ">") {
|
|
@@ -16164,10 +16165,13 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16164
16165
|
angleDepthBack--;
|
|
16165
16166
|
continue;
|
|
16166
16167
|
}
|
|
16167
|
-
|
|
16168
|
-
|
|
16168
|
+
if (parenDepthBack === 0) {
|
|
16169
|
+
isTypeSignature = true;
|
|
16170
|
+
break;
|
|
16171
|
+
}
|
|
16172
|
+
continue;
|
|
16169
16173
|
}
|
|
16170
|
-
if (ch === ":" && angleDepthBack === 0) {
|
|
16174
|
+
if (ch === ":" && angleDepthBack === 0 && parenDepthBack === 0) {
|
|
16171
16175
|
isTypeSignature = true;
|
|
16172
16176
|
break;
|
|
16173
16177
|
}
|
|
@@ -16175,11 +16179,34 @@ ${lines.slice(bodyRange.from + 1, bodyRange.to + 1).join(`
|
|
|
16175
16179
|
continue;
|
|
16176
16180
|
if (ch === ",")
|
|
16177
16181
|
continue;
|
|
16178
|
-
if (ch === "
|
|
16182
|
+
if (ch === ")") {
|
|
16183
|
+
parenDepthBack++;
|
|
16184
|
+
continue;
|
|
16185
|
+
}
|
|
16186
|
+
if (ch === "(") {
|
|
16187
|
+
parenDepthBack--;
|
|
16188
|
+
continue;
|
|
16189
|
+
}
|
|
16190
|
+
if (ch === "|" || ch === "&") {
|
|
16191
|
+
isTypeSignature = true;
|
|
16179
16192
|
break;
|
|
16180
16193
|
}
|
|
16194
|
+
if (ch === "=" || ch === "{" || ch === "[") {
|
|
16195
|
+
if (parenDepthBack >= 0)
|
|
16196
|
+
break;
|
|
16197
|
+
continue;
|
|
16198
|
+
}
|
|
16181
16199
|
if (ch !== " " && ch !== "\t" && !/[\w.]/.test(ch)) {
|
|
16182
|
-
|
|
16200
|
+
if (parenDepthBack >= 0)
|
|
16201
|
+
break;
|
|
16202
|
+
}
|
|
16203
|
+
}
|
|
16204
|
+
if (!isTypeSignature) {
|
|
16205
|
+
const beforeParen = line.slice(0, openParenIdx);
|
|
16206
|
+
if (/^\s*(?:export\s+)?(?:declare\s+)?type\s+\w[\w$]*\s*(?:<[^>]*>)?\s*=\s*$/.test(beforeParen)) {
|
|
16207
|
+
isTypeSignature = true;
|
|
16208
|
+
} else if (/\bas\s+$/.test(beforeParen)) {
|
|
16209
|
+
isTypeSignature = true;
|
|
16183
16210
|
}
|
|
16184
16211
|
}
|
|
16185
16212
|
if (isTypeSignature) {
|
|
@@ -19009,6 +19036,42 @@ var init_link_image_reference_definitions = __esm(() => {
|
|
|
19009
19036
|
}
|
|
19010
19037
|
}
|
|
19011
19038
|
return issues;
|
|
19039
|
+
},
|
|
19040
|
+
fix: (text) => {
|
|
19041
|
+
const lines = text.split(/\r?\n/);
|
|
19042
|
+
const inCode = getCodeBlockLines(lines);
|
|
19043
|
+
const defLines = new Map;
|
|
19044
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19045
|
+
if (inCode.has(i))
|
|
19046
|
+
continue;
|
|
19047
|
+
const m = lines[i].match(/^\s*\[([^\]]+)\]:\s*\S+/);
|
|
19048
|
+
if (m)
|
|
19049
|
+
defLines.set(i, m[1].toLowerCase());
|
|
19050
|
+
}
|
|
19051
|
+
if (defLines.size === 0)
|
|
19052
|
+
return text;
|
|
19053
|
+
const usages = new Set;
|
|
19054
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19055
|
+
if (inCode.has(i))
|
|
19056
|
+
continue;
|
|
19057
|
+
if (defLines.has(i))
|
|
19058
|
+
continue;
|
|
19059
|
+
const line = lines[i];
|
|
19060
|
+
const refMatches = line.matchAll(/\[([^\]]+)\](?:\[([^\]]*)\])?(?!\()/g);
|
|
19061
|
+
for (const m of refMatches) {
|
|
19062
|
+
const label = (m[2] && m[2].length > 0 ? m[2] : m[1]).toLowerCase();
|
|
19063
|
+
usages.add(label);
|
|
19064
|
+
}
|
|
19065
|
+
}
|
|
19066
|
+
const toRemove = new Set;
|
|
19067
|
+
for (const [idx, label] of defLines) {
|
|
19068
|
+
if (!usages.has(label))
|
|
19069
|
+
toRemove.add(idx);
|
|
19070
|
+
}
|
|
19071
|
+
if (toRemove.size === 0)
|
|
19072
|
+
return text;
|
|
19073
|
+
return lines.filter((_, idx) => !toRemove.has(idx)).join(`
|
|
19074
|
+
`);
|
|
19012
19075
|
}
|
|
19013
19076
|
};
|
|
19014
19077
|
});
|
|
@@ -19026,19 +19089,39 @@ var init_link_image_style = __esm(() => {
|
|
|
19026
19089
|
check: (text, ctx) => {
|
|
19027
19090
|
const issues = [];
|
|
19028
19091
|
const lines = text.split(/\r?\n/);
|
|
19092
|
+
const inCode = getCodeBlockLines(lines);
|
|
19029
19093
|
const options = ctx.options || {};
|
|
19030
19094
|
const style = options.style || "consistent";
|
|
19031
|
-
let
|
|
19032
|
-
|
|
19095
|
+
let target = style === "consistent" ? null : style;
|
|
19096
|
+
if (target === null) {
|
|
19097
|
+
let inlineCount = 0;
|
|
19098
|
+
let refCount = 0;
|
|
19099
|
+
let inHtmlCommentScan = false;
|
|
19100
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19101
|
+
if (inCode.has(i))
|
|
19102
|
+
continue;
|
|
19103
|
+
const line = lines[i];
|
|
19104
|
+
if (line.includes("<!--"))
|
|
19105
|
+
inHtmlCommentScan = true;
|
|
19106
|
+
if (line.includes("-->")) {
|
|
19107
|
+
inHtmlCommentScan = false;
|
|
19108
|
+
continue;
|
|
19109
|
+
}
|
|
19110
|
+
if (inHtmlCommentScan)
|
|
19111
|
+
continue;
|
|
19112
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(line))
|
|
19113
|
+
continue;
|
|
19114
|
+
const scrubbed = stripInlineCode(line);
|
|
19115
|
+
inlineCount += (scrubbed.match(/\[[^\]]+\]\([^)]+\)/g) || []).length;
|
|
19116
|
+
refCount += (scrubbed.match(/\[[^\]]+\]\[(?:[^\]]*)\]/g) || []).length;
|
|
19117
|
+
}
|
|
19118
|
+
target = refCount > inlineCount ? "reference" : "inline";
|
|
19119
|
+
}
|
|
19033
19120
|
let inHtmlComment = false;
|
|
19034
19121
|
for (let i = 0;i < lines.length; i++) {
|
|
19035
|
-
|
|
19036
|
-
if (/^(?:`{3,}|~{3,})/.test(line.trim())) {
|
|
19037
|
-
inFence = !inFence;
|
|
19038
|
-
continue;
|
|
19039
|
-
}
|
|
19040
|
-
if (inFence)
|
|
19122
|
+
if (inCode.has(i))
|
|
19041
19123
|
continue;
|
|
19124
|
+
const line = lines[i];
|
|
19042
19125
|
if (line.includes("<!--"))
|
|
19043
19126
|
inHtmlComment = true;
|
|
19044
19127
|
if (line.includes("-->")) {
|
|
@@ -19047,64 +19130,104 @@ var init_link_image_style = __esm(() => {
|
|
|
19047
19130
|
}
|
|
19048
19131
|
if (inHtmlComment)
|
|
19049
19132
|
continue;
|
|
19050
|
-
if (line.match(/^\[(?:[^\]]+)\]:\s*\S+/))
|
|
19133
|
+
if (line.match(/^\[(?:[^\]]+)\]:\s*\S+/))
|
|
19051
19134
|
continue;
|
|
19052
|
-
}
|
|
19053
19135
|
const scrubbed = stripInlineCode(line);
|
|
19054
19136
|
const inlineMatches = scrubbed.matchAll(/\[[^\]]+\]\([^)]+\)/g);
|
|
19055
19137
|
for (const match of inlineMatches) {
|
|
19056
|
-
if (
|
|
19138
|
+
if (target === "reference") {
|
|
19057
19139
|
issues.push({
|
|
19058
19140
|
filePath: ctx.filePath,
|
|
19059
19141
|
line: i + 1,
|
|
19060
19142
|
column: match.index + 1,
|
|
19061
19143
|
ruleId: "markdown/link-image-style",
|
|
19062
|
-
message: "Expected reference style link",
|
|
19063
|
-
severity: "error"
|
|
19144
|
+
message: style === "consistent" ? "Link style should be consistent throughout document" : "Expected reference style link",
|
|
19145
|
+
severity: style === "consistent" ? "warning" : "error"
|
|
19064
19146
|
});
|
|
19065
|
-
} else if (style === "consistent") {
|
|
19066
|
-
if (detectedStyle === null) {
|
|
19067
|
-
detectedStyle = "inline";
|
|
19068
|
-
} else if (detectedStyle === "reference") {
|
|
19069
|
-
issues.push({
|
|
19070
|
-
filePath: ctx.filePath,
|
|
19071
|
-
line: i + 1,
|
|
19072
|
-
column: match.index + 1,
|
|
19073
|
-
ruleId: "markdown/link-image-style",
|
|
19074
|
-
message: "Link style should be consistent throughout document",
|
|
19075
|
-
severity: "warning"
|
|
19076
|
-
});
|
|
19077
|
-
}
|
|
19078
19147
|
}
|
|
19079
19148
|
}
|
|
19080
19149
|
const refMatches = scrubbed.matchAll(/\[[^\]]+\]\[(?:[^\]]+)\]/g);
|
|
19081
19150
|
for (const match of refMatches) {
|
|
19082
|
-
if (
|
|
19151
|
+
if (target === "inline") {
|
|
19083
19152
|
issues.push({
|
|
19084
19153
|
filePath: ctx.filePath,
|
|
19085
19154
|
line: i + 1,
|
|
19086
19155
|
column: match.index + 1,
|
|
19087
19156
|
ruleId: "markdown/link-image-style",
|
|
19088
|
-
message: "Expected inline style link",
|
|
19089
|
-
severity: "error"
|
|
19157
|
+
message: style === "consistent" ? "Link style should be consistent throughout document" : "Expected inline style link",
|
|
19158
|
+
severity: style === "consistent" ? "warning" : "error"
|
|
19090
19159
|
});
|
|
19091
|
-
} else if (style === "consistent") {
|
|
19092
|
-
if (detectedStyle === null) {
|
|
19093
|
-
detectedStyle = "reference";
|
|
19094
|
-
} else if (detectedStyle === "inline") {
|
|
19095
|
-
issues.push({
|
|
19096
|
-
filePath: ctx.filePath,
|
|
19097
|
-
line: i + 1,
|
|
19098
|
-
column: match.index + 1,
|
|
19099
|
-
ruleId: "markdown/link-image-style",
|
|
19100
|
-
message: "Link style should be consistent throughout document",
|
|
19101
|
-
severity: "warning"
|
|
19102
|
-
});
|
|
19103
|
-
}
|
|
19104
19160
|
}
|
|
19105
19161
|
}
|
|
19106
19162
|
}
|
|
19107
19163
|
return issues;
|
|
19164
|
+
},
|
|
19165
|
+
fix: (text, ctx) => {
|
|
19166
|
+
const options = ctx.options || {};
|
|
19167
|
+
const style = options.style || "consistent";
|
|
19168
|
+
const lines = text.split(/\r?\n/);
|
|
19169
|
+
const inCode = getCodeBlockLines(lines);
|
|
19170
|
+
const defs = new Map;
|
|
19171
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19172
|
+
if (inCode.has(i))
|
|
19173
|
+
continue;
|
|
19174
|
+
const m = lines[i].match(/^\s*\[([^\]]+)\]:\s*(\S+)(?:\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\)))?\s*$/);
|
|
19175
|
+
if (m) {
|
|
19176
|
+
const label = m[1].toLowerCase();
|
|
19177
|
+
const url = m[2];
|
|
19178
|
+
const title = m[3] ?? m[4] ?? m[5];
|
|
19179
|
+
if (!defs.has(label))
|
|
19180
|
+
defs.set(label, { url, title });
|
|
19181
|
+
}
|
|
19182
|
+
}
|
|
19183
|
+
if (defs.size === 0)
|
|
19184
|
+
return text;
|
|
19185
|
+
let target = style === "reference" ? "reference" : "inline";
|
|
19186
|
+
if (style === "consistent") {
|
|
19187
|
+
let inlineCount = 0;
|
|
19188
|
+
let refCount = 0;
|
|
19189
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19190
|
+
if (inCode.has(i))
|
|
19191
|
+
continue;
|
|
19192
|
+
const line = lines[i];
|
|
19193
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(line))
|
|
19194
|
+
continue;
|
|
19195
|
+
const scrubbed = stripInlineCode(line);
|
|
19196
|
+
inlineCount += (scrubbed.match(/\[[^\]]+\]\([^)]+\)/g) || []).length;
|
|
19197
|
+
refCount += (scrubbed.match(/\[[^\]]+\]\[(?:[^\]]*)\]/g) || []).length;
|
|
19198
|
+
}
|
|
19199
|
+
target = refCount > inlineCount ? "reference" : "inline";
|
|
19200
|
+
}
|
|
19201
|
+
if (target !== "inline")
|
|
19202
|
+
return text;
|
|
19203
|
+
let changed = false;
|
|
19204
|
+
for (let i = 0;i < lines.length; i++) {
|
|
19205
|
+
if (inCode.has(i))
|
|
19206
|
+
continue;
|
|
19207
|
+
const original = lines[i];
|
|
19208
|
+
if (/^\s*\[(?:[^\]]+)\]:\s*\S+/.test(original))
|
|
19209
|
+
continue;
|
|
19210
|
+
let rewritten = original;
|
|
19211
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
19212
|
+
const next = rewritten.replace(/(!?)\[((?:[^[\]]|\[[^\]]*\]\([^)]*\))+)\]\[([^\]]*)\]/g, (whole, bang, textPart, labelPart) => {
|
|
19213
|
+
const labelKey = (labelPart.trim() === "" ? textPart : labelPart).toLowerCase();
|
|
19214
|
+
const def = defs.get(labelKey);
|
|
19215
|
+
if (!def)
|
|
19216
|
+
return whole;
|
|
19217
|
+
const titlePart = def.title ? ` "${def.title}"` : "";
|
|
19218
|
+
return `${bang}[${textPart}](${def.url}${titlePart})`;
|
|
19219
|
+
});
|
|
19220
|
+
if (next === rewritten)
|
|
19221
|
+
break;
|
|
19222
|
+
rewritten = next;
|
|
19223
|
+
}
|
|
19224
|
+
if (rewritten !== original) {
|
|
19225
|
+
lines[i] = rewritten;
|
|
19226
|
+
changed = true;
|
|
19227
|
+
}
|
|
19228
|
+
}
|
|
19229
|
+
return changed ? lines.join(`
|
|
19230
|
+
`) : text;
|
|
19108
19231
|
}
|
|
19109
19232
|
};
|
|
19110
19233
|
});
|
|
@@ -20508,24 +20631,18 @@ var init_single_title = __esm(() => {
|
|
|
20508
20631
|
check: (text, ctx) => {
|
|
20509
20632
|
const issues = [];
|
|
20510
20633
|
const lines = text.split(/\r?\n/);
|
|
20634
|
+
const inCode = getCodeBlockLines(lines);
|
|
20511
20635
|
let firstH1Line = -1;
|
|
20512
|
-
let inFencedCodeBlock = false;
|
|
20513
20636
|
for (let i = 0;i < lines.length; i++) {
|
|
20637
|
+
if (inCode.has(i))
|
|
20638
|
+
continue;
|
|
20514
20639
|
const line = lines[i];
|
|
20515
20640
|
const nextLine = i + 1 < lines.length ? lines[i + 1] : "";
|
|
20516
|
-
if (/^(?:`{3,}|~{3,})/.test(line.trim())) {
|
|
20517
|
-
inFencedCodeBlock = !inFencedCodeBlock;
|
|
20518
|
-
continue;
|
|
20519
|
-
}
|
|
20520
|
-
if (inFencedCodeBlock)
|
|
20521
|
-
continue;
|
|
20522
20641
|
let isH1 = false;
|
|
20523
|
-
if (/^#\s/.test(line))
|
|
20642
|
+
if (/^#\s/.test(line))
|
|
20524
20643
|
isH1 = true;
|
|
20525
|
-
|
|
20526
|
-
if (/^=+\s*$/.test(nextLine) && line.trim().length > 0) {
|
|
20644
|
+
if (/^=+\s*$/.test(nextLine) && line.trim().length > 0 && !inCode.has(i + 1))
|
|
20527
20645
|
isH1 = true;
|
|
20528
|
-
}
|
|
20529
20646
|
if (isH1) {
|
|
20530
20647
|
if (firstH1Line === -1) {
|
|
20531
20648
|
firstH1Line = i + 1;
|
|
@@ -20542,6 +20659,47 @@ var init_single_title = __esm(() => {
|
|
|
20542
20659
|
}
|
|
20543
20660
|
}
|
|
20544
20661
|
return issues;
|
|
20662
|
+
},
|
|
20663
|
+
fix: (text) => {
|
|
20664
|
+
const lines = text.split(/\r?\n/);
|
|
20665
|
+
const inCode = getCodeBlockLines(lines);
|
|
20666
|
+
const result = [];
|
|
20667
|
+
let seenH1 = false;
|
|
20668
|
+
let changed = false;
|
|
20669
|
+
for (let i = 0;i < lines.length; i++) {
|
|
20670
|
+
if (inCode.has(i)) {
|
|
20671
|
+
result.push(lines[i]);
|
|
20672
|
+
continue;
|
|
20673
|
+
}
|
|
20674
|
+
const line = lines[i];
|
|
20675
|
+
const nextLine = i + 1 < lines.length ? lines[i + 1] : "";
|
|
20676
|
+
const atxH1 = /^#\s/.test(line);
|
|
20677
|
+
const setextH1 = /^=+\s*$/.test(nextLine) && line.trim().length > 0 && !inCode.has(i + 1);
|
|
20678
|
+
if (atxH1) {
|
|
20679
|
+
if (!seenH1) {
|
|
20680
|
+
seenH1 = true;
|
|
20681
|
+
result.push(line);
|
|
20682
|
+
} else {
|
|
20683
|
+
result.push(`#${line}`);
|
|
20684
|
+
changed = true;
|
|
20685
|
+
}
|
|
20686
|
+
continue;
|
|
20687
|
+
}
|
|
20688
|
+
if (setextH1) {
|
|
20689
|
+
if (!seenH1) {
|
|
20690
|
+
seenH1 = true;
|
|
20691
|
+
result.push(line);
|
|
20692
|
+
continue;
|
|
20693
|
+
}
|
|
20694
|
+
result.push(`## ${line.trim()}`);
|
|
20695
|
+
i++;
|
|
20696
|
+
changed = true;
|
|
20697
|
+
continue;
|
|
20698
|
+
}
|
|
20699
|
+
result.push(line);
|
|
20700
|
+
}
|
|
20701
|
+
return changed ? result.join(`
|
|
20702
|
+
`) : text;
|
|
20545
20703
|
}
|
|
20546
20704
|
};
|
|
20547
20705
|
});
|
|
@@ -21142,6 +21300,13 @@ function splitFrontmatter(content) {
|
|
|
21142
21300
|
}
|
|
21143
21301
|
return { header: null, body: content };
|
|
21144
21302
|
}
|
|
21303
|
+
function markdownOnlyWholeFile(rule) {
|
|
21304
|
+
return {
|
|
21305
|
+
meta: rule.meta,
|
|
21306
|
+
check: (content, context) => context.filePath.endsWith(".md") ? rule.check(content, context) : [],
|
|
21307
|
+
fix: rule.fix ? (content, context) => context.filePath.endsWith(".md") ? rule.fix(content, context) : content : undefined
|
|
21308
|
+
};
|
|
21309
|
+
}
|
|
21145
21310
|
function markdownOnly(rule) {
|
|
21146
21311
|
return {
|
|
21147
21312
|
meta: rule.meta,
|
|
@@ -21249,7 +21414,7 @@ var init_markdown = __esm(() => {
|
|
|
21249
21414
|
"no-multiple-space-blockquote": markdownOnly(noMultipleSpaceBlockquoteRule),
|
|
21250
21415
|
"no-blanks-blockquote": markdownOnly(noBlanksBlockquoteRule),
|
|
21251
21416
|
"blanks-around-fences": markdownOnly(blanksAroundFencesRule),
|
|
21252
|
-
"single-trailing-newline":
|
|
21417
|
+
"single-trailing-newline": markdownOnlyWholeFile(singleTrailingNewlineRule),
|
|
21253
21418
|
"blanks-around-tables": markdownOnly(blanksAroundTablesRule),
|
|
21254
21419
|
"no-reversed-links": markdownOnly(noReversedLinksRule),
|
|
21255
21420
|
"no-bare-urls": markdownOnly(noBareUrlsRule),
|