markdown_link_checker_sc 0.0.135 → 0.0.137
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/README.md +8 -9
- package/index.js +41 -18
- package/package.json +1 -1
- package/src/errors.js +1 -1
- package/src/filters.js +4 -3
- package/src/links.js +2 -2
- package/src/output_errors.js +3 -3
- package/src/process_image_orphans.js +4 -4
- package/src/process_local_image_links.js +2 -2
package/README.md
CHANGED
|
@@ -12,21 +12,20 @@ Current version only does internal link checking
|
|
|
12
12
|
Usage: markdown_link_checker_sc [options]
|
|
13
13
|
|
|
14
14
|
Options:
|
|
15
|
-
-r, --
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-i, --imagedir [directory] The directory to search for all image files for global orphan checking, relative
|
|
20
|
-
|
|
15
|
+
-r, --repo <path> Repo root directory. Defaults to current directory. Everything resolved relative to this.) (default: "")
|
|
16
|
+
-d, --doc [directory] Docs root directory, relative to -g (such as `docs`). Defaults to '' (all docs in root of repo). Use -d as well to restrict search to a particular subfolder. Defaults to current directory. (default:
|
|
17
|
+
"D:\\github\\hamishwillee\\markdown_link_checker_sc")
|
|
18
|
+
-e, --subdir [directory] A subfolder of the docs root (-d) to search for markdown and html files. Such as: `en` for an English subfolder. Default empty (same as -d directory) (default: "")
|
|
19
|
+
-i, --imagedir [directory] The directory to search for all image files for global orphan checking, relative docs root (-d) - such as: `assets` or `en`. Default empty if not explicitly set, and global orphan checking will not be done
|
|
20
|
+
(default: "")
|
|
21
21
|
-c, --headingAnchorSlugify [value] Slugify approach for turning markdown headings into heading anchors. Currently support vuepress only and always (default: "vuepress")
|
|
22
22
|
-t, --tryMarkdownforHTML [value] Try a markdown file extension check if a link to HTML fails. (default: true)
|
|
23
23
|
-l, --log <types...> Types of console logs to display logs for debugging. Types: functions, todo etc.
|
|
24
|
-
-f, --files <path> JSON file with array of files to report on (default is all files).
|
|
25
|
-
root. (default: "")
|
|
24
|
+
-f, --files <path> JSON file with array of files to report on (default is all files). JSON paths are usually relative to git repo root `-r`. (default: "")
|
|
26
25
|
-s, --toc [value] full filename of TOC/Summary file in file system. If not specified, inferred from file with most links to other files
|
|
27
26
|
-u, --site_url [value] Site base url in form dev.example.com (used to catch absolute urls to local files)
|
|
28
27
|
-o, --logtofile [value] Output logs to file (default: true)
|
|
29
|
-
-p, --interactive [value] Interactively add errors to the ignore list at _link_checker_sc/ignore_errors.json (default: false)
|
|
28
|
+
-p, --interactive [value] Interactively add errors to the ignore list at <repo>/_link_checker_sc/ignore_errors.json (default: false)
|
|
30
29
|
-c, --anchor_in_heading [value] Detect anchors in heading such as: # Heading {#anchor} (default: true)
|
|
31
30
|
-h, --help display help for command
|
|
32
31
|
```
|
package/index.js
CHANGED
|
@@ -30,18 +30,23 @@ import { filterErrors, filterIgnoreErrors } from "./src/filters.js";
|
|
|
30
30
|
|
|
31
31
|
program
|
|
32
32
|
.option(
|
|
33
|
-
"-r, --
|
|
34
|
-
"
|
|
33
|
+
"-r, --repo <path>",
|
|
34
|
+
"Repo root directory. Defaults to current directory. Everything resolved relative to this.)",
|
|
35
|
+
""
|
|
36
|
+
)
|
|
37
|
+
.option(
|
|
38
|
+
"-d, --doc [directory]",
|
|
39
|
+
"Docs root directory, relative to -g (such as `docs`). Defaults to '' (all docs in root of repo). Use -d as well to restrict search to a particular subfolder. Defaults to current directory.",
|
|
35
40
|
process.cwd()
|
|
36
41
|
)
|
|
37
42
|
.option(
|
|
38
|
-
"-
|
|
39
|
-
"A subfolder
|
|
43
|
+
"-e, --subdir [directory]",
|
|
44
|
+
"A subfolder of the docs root (-d) to search for markdown and html files. Such as: `en` for an English subfolder. Default empty (same as -d directory)",
|
|
40
45
|
""
|
|
41
46
|
)
|
|
42
47
|
.option(
|
|
43
48
|
"-i, --imagedir [directory]",
|
|
44
|
-
"The directory to search for all image files for global orphan checking, relative
|
|
49
|
+
"The directory to search for all image files for global orphan checking, relative docs root (-d) - such as: `assets` or `en`. Default empty if not explicitly set, and global orphan checking will not be done",
|
|
45
50
|
""
|
|
46
51
|
)
|
|
47
52
|
.option(
|
|
@@ -60,10 +65,9 @@ program
|
|
|
60
65
|
)
|
|
61
66
|
.option(
|
|
62
67
|
"-f, --files <path>",
|
|
63
|
-
"JSON file with array of files to report on (default is all files).
|
|
68
|
+
"JSON file with array of files to report on (default is all files). JSON paths are usually relative to git repo root `-r`.",
|
|
64
69
|
""
|
|
65
70
|
)
|
|
66
|
-
|
|
67
71
|
.option(
|
|
68
72
|
"-s, --toc [value]",
|
|
69
73
|
"full filename of TOC/Summary file in file system. If not specified, inferred from file with most links to other files"
|
|
@@ -75,7 +79,7 @@ program
|
|
|
75
79
|
.option("-o, --logtofile [value]", "Output logs to file", true)
|
|
76
80
|
.option(
|
|
77
81
|
"-p, --interactive [value]",
|
|
78
|
-
"Interactively add errors to the ignore list at _link_checker_sc/ignore_errors.json",
|
|
82
|
+
"Interactively add errors to the ignore list at <repo>/_link_checker_sc/ignore_errors.json",
|
|
79
83
|
false
|
|
80
84
|
)
|
|
81
85
|
.option(
|
|
@@ -97,11 +101,29 @@ sharedData.allHTMLFiles = new Set([]);
|
|
|
97
101
|
sharedData.allImageFiles = new Set([]);
|
|
98
102
|
sharedData.allOtherFiles = new Set([]);
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
//console.log(`debug: sharedData.options.repo: ${sharedData.options.repo}`);
|
|
105
|
+
//console.log(`debug: sharedData.options.doc: ${sharedData.options.doc}`);
|
|
106
|
+
//console.log(`debug: sharedData.options.subdir: ${sharedData.options.subdir}`);
|
|
107
|
+
|
|
108
|
+
sharedData.options.docsroot = path.join(
|
|
109
|
+
sharedData.options.repo,
|
|
110
|
+
sharedData.options.doc
|
|
103
111
|
);
|
|
104
112
|
|
|
113
|
+
// Markdown directory we are actually checking
|
|
114
|
+
sharedData.options.markdownroot = path.join(
|
|
115
|
+
sharedData.options.docsroot,
|
|
116
|
+
sharedData.options.subdir
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
//console.log(`debug: sharedData.options.repo: ${sharedData.options.repo}`);
|
|
120
|
+
//console.log(`debug: sharedData.options.doc: ${sharedData.options.doc}`);
|
|
121
|
+
//console.log(`debug: sharedData.options.subdir: ${sharedData.options.subdir}`);
|
|
122
|
+
//console.log(`debug: sharedData.options.docsroot: ${sharedData.options.docsroot}`);
|
|
123
|
+
//console.log(`debug: sharedData.options.markdownroot: ${sharedData.options.markdownroot}`);
|
|
124
|
+
|
|
125
|
+
//process.exit(1);
|
|
126
|
+
|
|
105
127
|
// Function for loading JSON file that contains files to report on
|
|
106
128
|
async function loadJSONFileToReportOn(filePath) {
|
|
107
129
|
sharedData.options.log.includes("functions")
|
|
@@ -115,7 +137,7 @@ async function loadJSONFileToReportOn(filePath) {
|
|
|
115
137
|
let filesArray = JSON.parse(fileContent);
|
|
116
138
|
// Array relative to root, so update to have full path
|
|
117
139
|
filesArray = filesArray.map((str) =>
|
|
118
|
-
path.join(sharedData.options.
|
|
140
|
+
path.join(sharedData.options.repo, str)
|
|
119
141
|
);
|
|
120
142
|
|
|
121
143
|
sharedData.options.log.includes("quick")
|
|
@@ -125,7 +147,7 @@ async function loadJSONFileToReportOn(filePath) {
|
|
|
125
147
|
return filesArray;
|
|
126
148
|
} catch (error) {
|
|
127
149
|
console.error(`Error reading file: ${error.message}`);
|
|
128
|
-
console.log(`Error reading file: ${error.message}`);
|
|
150
|
+
//console.log(`Error reading file: ${error.message}`);
|
|
129
151
|
process.exit(1);
|
|
130
152
|
}
|
|
131
153
|
}
|
|
@@ -145,9 +167,9 @@ async function loadJSONFileToIgnore(filePath) {
|
|
|
145
167
|
if (filesArray.length == 0) {
|
|
146
168
|
return [];
|
|
147
169
|
} else {
|
|
148
|
-
// Array relative to root, so update to have full path
|
|
170
|
+
// Array relative to repo root, so update to have full path
|
|
149
171
|
filesArray = filesArray.map((str) =>
|
|
150
|
-
path.join(sharedData.options.
|
|
172
|
+
path.join(sharedData.options.docsroot, str)
|
|
151
173
|
);
|
|
152
174
|
}
|
|
153
175
|
|
|
@@ -210,7 +232,7 @@ const processDirectory = async (dir) => {
|
|
|
210
232
|
results.push(...subResults);
|
|
211
233
|
} else if (sharedData.options.ignoreFiles.includes(file)) {
|
|
212
234
|
// do nothing
|
|
213
|
-
//
|
|
235
|
+
//console.log(`XxxxXignorelist: file: ${file}`);
|
|
214
236
|
} else if (isMarkdown(file)) {
|
|
215
237
|
sharedData.allMarkdownFiles.add(file);
|
|
216
238
|
const result = await processFile(file);
|
|
@@ -241,7 +263,8 @@ const processDirectory = async (dir) => {
|
|
|
241
263
|
: (sharedData.options.files = []);
|
|
242
264
|
|
|
243
265
|
const pathToJsonIgnoreFile = path.join(
|
|
244
|
-
sharedData.options.
|
|
266
|
+
sharedData.options.repo,
|
|
267
|
+
sharedData.options.doc,
|
|
245
268
|
"_link_checker_sc/ignorefile.json"
|
|
246
269
|
);
|
|
247
270
|
//console.log(`debug: pathToJsonIgnoreFile: ${pathToJsonIgnoreFile}`);
|
|
@@ -250,7 +273,7 @@ const processDirectory = async (dir) => {
|
|
|
250
273
|
);
|
|
251
274
|
|
|
252
275
|
// process containing markdown, return results which includes links, headings, id anchors
|
|
253
|
-
const results = await processDirectory(
|
|
276
|
+
const results = await processDirectory(sharedData.options.markdownroot);
|
|
254
277
|
|
|
255
278
|
if (!results.allErrors) {
|
|
256
279
|
results.allErrors = [];
|
package/package.json
CHANGED
package/src/errors.js
CHANGED
|
@@ -13,7 +13,7 @@ class LinkError {
|
|
|
13
13
|
this.fileRelativeToRoot = this.link.fileRelativeToRoot;
|
|
14
14
|
} else {
|
|
15
15
|
this.file = file; // i.e. infer file from link, but if link not specified then can take passed value
|
|
16
|
-
this.fileRelativeToRoot = this.file.split(sharedData.options.
|
|
16
|
+
this.fileRelativeToRoot = this.file.split(sharedData.options.docsroot)[1];
|
|
17
17
|
this.fileRelativeToRoot =
|
|
18
18
|
this.fileRelativeToRoot.startsWith("/") ||
|
|
19
19
|
this.fileRelativeToRoot.startsWith("\\")
|
package/src/filters.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { sharedData } from "./shared_data.js";
|
|
4
4
|
import { logFunction } from "./helpers.js";
|
|
5
|
-
import normalize from
|
|
5
|
+
import normalize from "normalize-path";
|
|
6
6
|
|
|
7
7
|
function filterIgnoreErrors(errors) {
|
|
8
8
|
// This method removes any errors that are in the ignore errors list
|
|
@@ -11,7 +11,7 @@ function filterIgnoreErrors(errors) {
|
|
|
11
11
|
// Currently it is the pages to output, as listed in the options.files to output.
|
|
12
12
|
logFunction(`Function: filterIgnoreErrors(${errors})`);
|
|
13
13
|
const errorFile = path.join(
|
|
14
|
-
sharedData.options.
|
|
14
|
+
sharedData.options.docsroot,
|
|
15
15
|
"./_link_checker_sc/ignore_errors.json"
|
|
16
16
|
);
|
|
17
17
|
|
|
@@ -33,7 +33,8 @@ function filterIgnoreErrors(errors) {
|
|
|
33
33
|
sharedData.IgnoreErrors.forEach((ignorableError) => {
|
|
34
34
|
if (
|
|
35
35
|
error.type === ignorableError.type &&
|
|
36
|
-
normalize(error.fileRelativeToRoot) ===
|
|
36
|
+
normalize(error.fileRelativeToRoot) ===
|
|
37
|
+
normalize(ignorableError.fileRelativeToRoot)
|
|
37
38
|
) {
|
|
38
39
|
// Same file and type, so probably filter out.
|
|
39
40
|
if (!(error.link && ignorableError.link)) {
|
package/src/links.js
CHANGED
|
@@ -42,9 +42,9 @@ class Link {
|
|
|
42
42
|
} else {
|
|
43
43
|
throw new Error("Link: page argument is required.");
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
//console.log(`debug: page: ${page}, sharedData.options.docsroot: ${sharedData.options.docsroot}`);
|
|
46
46
|
// Create a relative file link for comparison
|
|
47
|
-
this.fileRelativeToRoot = this.page.split(sharedData.options.
|
|
47
|
+
this.fileRelativeToRoot = this.page.split(sharedData.options.docsroot)[1];
|
|
48
48
|
this.fileRelativeToRoot = (this.fileRelativeToRoot.startsWith('/') || this.fileRelativeToRoot.startsWith('\\')) ? this.fileRelativeToRoot.substring(1) : this.fileRelativeToRoot
|
|
49
49
|
|
|
50
50
|
if (url) {
|
package/src/output_errors.js
CHANGED
|
@@ -37,10 +37,10 @@ function outputErrors(results) {
|
|
|
37
37
|
//console.log(sortedByPageErrors);
|
|
38
38
|
for (const page in sortedByPageErrors) {
|
|
39
39
|
let pageFromRoot;
|
|
40
|
-
if (sharedData.options.
|
|
41
|
-
pageFromRoot = page.split(sharedData.options.
|
|
40
|
+
if (sharedData.options.docsroot) {
|
|
41
|
+
pageFromRoot = page.split(sharedData.options.docsroot)[1];
|
|
42
42
|
} else {
|
|
43
|
-
pageFromRoot = page.split(sharedData.options.
|
|
43
|
+
pageFromRoot = page.split(sharedData.options.markdownroot)[1];
|
|
44
44
|
}
|
|
45
45
|
//console.log(`\nXX${page}`); //Root needs to full path - not '.' or whatever
|
|
46
46
|
console.log(`\n${pageFromRoot}`); //Root needs to full path - not '.' or whatever
|
|
@@ -15,7 +15,7 @@ var otherFileTypes = []; // Just used for logging in function below.
|
|
|
15
15
|
|
|
16
16
|
// Gets all image files in a directory.
|
|
17
17
|
async function getAllImageFilesInDirectory(dir) {
|
|
18
|
-
logFunction(`Function: getAllImageFilesInDirectory(${dir})`)
|
|
18
|
+
logFunction(`Function: getAllImageFilesInDirectory(${dir})`);
|
|
19
19
|
|
|
20
20
|
// TODO put this all in a try catch and return a better error.
|
|
21
21
|
// Or perhaps put around parent.
|
|
@@ -42,14 +42,14 @@ async function getAllImageFilesInDirectory(dir) {
|
|
|
42
42
|
|
|
43
43
|
// Checks if any images in the options.directory
|
|
44
44
|
async function checkImageOrphansGlobal(results) {
|
|
45
|
-
logFunction(`Function: checkImageOrphansGlobal()`)
|
|
46
|
-
|
|
45
|
+
logFunction(`Function: checkImageOrphansGlobal()`);
|
|
46
|
+
|
|
47
47
|
const errors = [];
|
|
48
48
|
let allImagesFound = [];
|
|
49
49
|
|
|
50
50
|
if (sharedData.options.imagedir !== "") {
|
|
51
51
|
const imagePath = path.resolve(
|
|
52
|
-
sharedData.options.
|
|
52
|
+
sharedData.options.docsroot,
|
|
53
53
|
sharedData.options.imagedir
|
|
54
54
|
);
|
|
55
55
|
|
|
@@ -16,8 +16,8 @@ async function checkLocalImageLinks(results) {
|
|
|
16
16
|
|
|
17
17
|
page.relativeImageLinks.forEach((link, index, array) => {
|
|
18
18
|
//console.log(`XYYXLINK: ${JSON.stringify(link, null, 2)}`);
|
|
19
|
-
//console.log(`sharedData.options.
|
|
20
|
-
//console.log(`sharedData.options.
|
|
19
|
+
//console.log(`sharedData.options.repo: ${sharedData.options.repo}`);
|
|
20
|
+
//console.log(`sharedData.options.subdir: ${sharedData.options.subdir}`);
|
|
21
21
|
//console.log(`link.linkUrlt: ${link.url}`);
|
|
22
22
|
//console.log(`dirname: ${path.dirname(page.page_file)}`);
|
|
23
23
|
|