Skip to content

Commit 024df06

Browse files
committed
Provide lint and lint:watch with VSCode config
1 parent b4004e2 commit 024df06

File tree

10 files changed

+2067
-96
lines changed

10 files changed

+2067
-96
lines changed

.vscode/tasks.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
// See https://go.microsoft.com/fwlink/?LinkId=733558
3+
// for the documentation about the tasks.json format
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"label": "Markdown lint",
8+
"type": "npm",
9+
"script": "lint",
10+
"problemMatcher": {
11+
"fileLocation": ["relative", "${workspaceFolder}"],
12+
"severity": "error",
13+
"owner": "lint-owner",
14+
"source": "lint-source",
15+
"pattern": {
16+
"regexp": "^(.*?):(\\d+)(?::(\\d+))? ((?:MD|VL)\\S+) (.*)$",
17+
"file": 1,
18+
"line": 2,
19+
"column": 3,
20+
"code": 4,
21+
"message": 5
22+
}
23+
}
24+
},
25+
{
26+
"label": "Markdown lint (watch)",
27+
"type": "npm",
28+
"script": "lint:watch",
29+
"isBackground": true,
30+
"problemMatcher": {
31+
"fileLocation": ["relative", "${workspaceFolder}"],
32+
"severity": "error",
33+
"owner": "lint-owner",
34+
"source": "lint-source",
35+
"pattern": {
36+
"regexp": "^(.*?):(\\d+)(?::(\\d+))? ((?:MD|VL)\\S+) (.*)$",
37+
"file": 1,
38+
"line": 2,
39+
"column": 3,
40+
"code": 4,
41+
"message": 5
42+
},
43+
"background": {
44+
"activeOnStart": true,
45+
"beginsPattern": "^lint START$",
46+
"endsPattern": "^lint END$"
47+
}
48+
}
49+
}
50+
]
51+
}

dist/gulpfile.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { watch } from "gulp";
2+
import { spawn } from "node:child_process";
3+
export const lint = () => new Promise((resolve, _reject) => {
4+
const child = spawn("./lint", { stdio: ["ignore", "inherit", "inherit"] });
5+
child.on("close", (_code, _signal) => {
6+
// if (code) reject(new Error(`./lint failed with exit code ${code}`));
7+
// if (signal) reject(new Error(`./lint was killed by signal ${signal}`));
8+
resolve();
9+
});
10+
});
11+
export const lintWatch = () => {
12+
watch(["**/*", "!.git/**", "!node_modules/**"], lint);
13+
lint();
14+
};
15+
export default lintWatch;

dist/parse.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
import mit from "markdown-it";
2+
const sourceLocationOf = (needle, haystack) => {
3+
const index = haystack.indexOf(needle);
4+
if (index < 0)
5+
return null;
6+
const parts = haystack.substring(0, index).split("\n");
7+
if (parts.length === 0)
8+
return null;
9+
return { line0: parts.length - 1, column0: parts[parts.length - 1].length };
10+
};
211
export const parse = (content) => {
312
const parser = mit();
413
const tokens = parser.parse(content, {});
@@ -9,20 +18,27 @@ export const parse = (content) => {
918
if (token.type === "link_open") {
1019
const indexOfNextClose = tokens.findIndex((t2, i2) => i2 > index && t2.type === "link_close");
1120
if (indexOfNextClose > index) {
21+
const target = token.attrGet("href");
22+
const sourceLocation = sourceLocationOf(`(${target})`, content);
1223
parsedLinks.push({
13-
target: token.attrGet("href"),
24+
target,
1425
content: tokens
1526
.slice(index + 1, indexOfNextClose)
1627
.map((t) => t.content)
1728
.join(""),
29+
sourceLocation,
1830
});
1931
}
2032
}
21-
if (token.type === "image")
33+
if (token.type === "image") {
34+
const src = token.attrGet("src");
35+
const sourceLocation = sourceLocationOf(`(${src})`, content);
2236
parsedImages.push({
23-
src: token.attrGet("src"),
37+
src,
2438
alt: token.content,
39+
sourceLocation,
2540
});
41+
}
2642
if (token.children)
2743
scan(token.children);
2844
});

dist/validateLinks.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ const scanForLinks = async (filenames) => {
2525
return { filename, ...parse(content) };
2626
}));
2727
};
28+
const showError = (filename, sourceLocation, code, message) => {
29+
console.log(`${filename}:${sourceLocation ? `${sourceLocation.line0 + 1}:${sourceLocation.column0 + 1}` : "0"} ${code} ${message}`);
30+
};
2831
const externalLinkPattern = /^\w+:/;
2932
const isExternalLink = (t) => externalLinkPattern.test(t);
3033
const main = async () => {
@@ -40,7 +43,7 @@ const main = async () => {
4043
const resolved = path.join(dirname(parsedFile.filename), img.src);
4144
const exists = lowercaseGitFiles.includes(resolved.toLocaleLowerCase());
4245
if (!exists) {
43-
console.log(`error BROKEN-INTERNAL-IMAGE ${parsedFile.filename}:0 Broken internal image reference ${img.src}`);
46+
showError(parsedFile.filename, img.sourceLocation, "VL002/missing-image-source", `Image source does not exist ${img.src}`);
4447
++errors;
4548
}
4649
}
@@ -65,7 +68,7 @@ const main = async () => {
6568
: `${resolved.toLocaleLowerCase()}/`;
6669
const isDirectory = lowercaseGitFiles.some((s) => s.startsWith(resolvedWithTrailingSlash));
6770
if (!isFile && !isDirectory) {
68-
console.log(`error BROKEN-INTERNAL-LINK ${parsedFile.filename}:0 Link target does not exist: ${target}`);
71+
showError(parsedFile.filename, link.sourceLocation, "VL001/missing-link-target", `Link target does not exist: ${target}`);
6972
++errors;
7073
}
7174
}

gulpfile.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { watch } from "gulp";
2+
import { spawn } from "node:child_process";
3+
4+
export const lint = () =>
5+
new Promise<void>((resolve, _reject) => {
6+
const child = spawn("./lint", { stdio: ["ignore", "inherit", "inherit"] });
7+
8+
child.on("close", (_code, _signal) => {
9+
// if (code) reject(new Error(`./lint failed with exit code ${code}`));
10+
// if (signal) reject(new Error(`./lint was killed by signal ${signal}`));
11+
resolve();
12+
});
13+
});
14+
15+
export const lintWatch = () => {
16+
watch(["**/*", "!.git/**", "!node_modules/**"], lint);
17+
lint();
18+
};
19+
20+
export default lintWatch;

lint

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ else
1010
if [ $? -ne 0 ] ; then
1111
echo "Try '\''./lint --fix'\'' to see if any automatic fixes are possible"
1212
fi
13+
echo "lint END"
1314
' 0
1415

1516
rc=0
17+
echo "lint START"
1618

1719
echo "validateLinks: ..."
1820
if npm exec -- node dist/validateLinks.js ; then

0 commit comments

Comments
 (0)