markdown_link_checker_sc 0.0.136 → 0.0.138

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 CHANGED
@@ -12,25 +12,36 @@ Current version only does internal link checking
12
12
  Usage: markdown_link_checker_sc [options]
13
13
 
14
14
  Options:
15
- -r, --root <path> Root directory of your docs source, such as <repo>/docs (the folder which contains all your docs, assets, etc). Use -d as well to restrict search to a
16
- particular subfolder. Defaults to current directory. (default: "D:\\github\\hamishwillee\\markdown_link_checker_sc")
17
- -d, --directory [directory] A subfolder or the root to search for markdown and html files. Such as: `en` for an English subfolder. Default empty (same as -r directory) (default:
18
- "")
19
- -i, --imagedir [directory] The directory to search for all image files for global orphan checking, relative to root - such as: `assets` or `en`. Default empty if not explicitly
20
- set, and global orphan checking will not be done (default: "")
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). Paths are relative relative to -d by default, but -r can be used to set a different
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
  ```
33
32
 
33
+ ## Ignore file
34
+
35
+ You can create a `_link_checker_sc\ignorefile.json` in the docs (path specified by `-d`) that lists any files you want to avoid parsing.
36
+ This is a JSON array of file paths relative the the docsroot.
37
+
38
+ For example, to not parse `en/_sidebar.md` your ignore file would have this pattern:
39
+
40
+ ```
41
+ ["en/_sidebar.md"]
42
+ ```
43
+
44
+ Note that a missing ignorefile is not an error.
34
45
 
35
46
  ## What link formats can it match
36
47
 
package/index.js CHANGED
@@ -3,9 +3,7 @@
3
3
  import fs from "fs";
4
4
  import path from "path";
5
5
  import { sharedData } from "./src/shared_data.js";
6
- //const path = require("path");
7
6
  import { program } from "commander";
8
- //const { program } = require("commander");
9
7
  import {
10
8
  logFunction,
11
9
  logToFile,
@@ -30,19 +28,23 @@ import { filterErrors, filterIgnoreErrors } from "./src/filters.js";
30
28
 
31
29
  program
32
30
  .option(
33
- "-r, --root <path>",
34
- "Root directory of your docs source, such as <repo>/docs (the folder which contains all your docs, assets, etc). Use -d as well to restrict search to a particular subfolder. Defaults to current directory.",
31
+ "-r, --repo <path>",
32
+ "Repo root directory. Defaults to current directory. Everything resolved relative to this.)",
33
+ ""
34
+ )
35
+ .option(
36
+ "-d, --doc [directory]",
37
+ "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
38
  process.cwd()
36
39
  )
37
40
  .option(
38
- "-d, --directory [directory]",
39
- "A subfolder or the docs root to search for markdown and html files. Such as: `en` for an English subfolder. Default empty (same as -r directory)",
41
+ "-e, --subdir [directory]",
42
+ "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
43
  ""
41
44
  )
42
-
43
45
  .option(
44
46
  "-i, --imagedir [directory]",
45
- "The directory to search for all image files for global orphan checking, relative to root - such as: `assets` or `en`. Default empty if not explicitly set, and global orphan checking will not be done",
47
+ "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",
46
48
  ""
47
49
  )
48
50
  .option(
@@ -61,12 +63,7 @@ program
61
63
  )
62
64
  .option(
63
65
  "-f, --files <path>",
64
- "JSON file with array of files to report on (default is all files). JSON paths are usually relative to git root. Resolved to absolute file paths using `-g`.",
65
- ""
66
- )
67
- .option(
68
- "-g, --repo [directory]",
69
- "Repo root directory. Files in -f JSON are resolved to absolute paths relative to this dir. Defaults to current directory.)",
66
+ "JSON file with array of files to report on (default is all files). JSON paths are usually relative to git repo root `-r`.",
70
67
  ""
71
68
  )
72
69
  .option(
@@ -80,7 +77,7 @@ program
80
77
  .option("-o, --logtofile [value]", "Output logs to file", true)
81
78
  .option(
82
79
  "-p, --interactive [value]",
83
- "Interactively add errors to the ignore list at _link_checker_sc/ignore_errors.json",
80
+ "Interactively add errors to the ignore list at <repo>/_link_checker_sc/ignore_errors.json",
84
81
  false
85
82
  )
86
83
  .option(
@@ -102,11 +99,40 @@ sharedData.allHTMLFiles = new Set([]);
102
99
  sharedData.allImageFiles = new Set([]);
103
100
  sharedData.allOtherFiles = new Set([]);
104
101
 
105
- const markdownDirectory = path.join(
106
- sharedData.options.root,
107
- sharedData.options.directory
102
+ function resolveRepoPath(repoOption) {
103
+ // This gets the path from CWD by default, or resolves path up.
104
+ if (!repoOption || repoOption === ".") {
105
+ return process.cwd(); // Current working directory (Node.js)
106
+ }
107
+
108
+ if (repoOption === "..") {
109
+ return path.resolve(process.cwd(), ".."); // One directory up
110
+ }
111
+
112
+ return path.resolve(repoOption); // Resolve to absolute path
113
+ }
114
+
115
+ sharedData.options.repo = resolveRepoPath(sharedData.options.repo);
116
+
117
+ sharedData.options.docsroot = path.join(
118
+ sharedData.options.repo,
119
+ sharedData.options.doc
108
120
  );
109
121
 
122
+ // Markdown directory we are actually checking
123
+ sharedData.options.markdownroot = path.join(
124
+ sharedData.options.docsroot,
125
+ sharedData.options.subdir
126
+ );
127
+
128
+ //console.log(`debug: sharedData.options.repo: ${sharedData.options.repo}`);
129
+ //console.log(`debug: sharedData.options.doc: ${sharedData.options.doc}`);
130
+ //console.log(`debug: sharedData.options.subdir: ${sharedData.options.subdir}`);
131
+ //console.log(`debug: sharedData.options.docsroot: ${sharedData.options.docsroot}`);
132
+ //console.log(`debug: sharedData.options.markdownroot: ${sharedData.options.markdownroot}`);
133
+
134
+ //process.exit(1);
135
+
110
136
  // Function for loading JSON file that contains files to report on
111
137
  async function loadJSONFileToReportOn(filePath) {
112
138
  sharedData.options.log.includes("functions")
@@ -150,9 +176,9 @@ async function loadJSONFileToIgnore(filePath) {
150
176
  if (filesArray.length == 0) {
151
177
  return [];
152
178
  } else {
153
- // Array relative to root, so update to have full path
179
+ // Array relative to repo root, so update to have full path
154
180
  filesArray = filesArray.map((str) =>
155
- path.join(sharedData.options.root, str)
181
+ path.join(sharedData.options.docsroot, str)
156
182
  );
157
183
  }
158
184
 
@@ -162,8 +188,8 @@ async function loadJSONFileToIgnore(filePath) {
162
188
 
163
189
  return filesArray;
164
190
  } catch (error) {
165
- //console.error(`Error reading file: ${error.message}`);
166
- console.log(`Error reading ignore file: ${error.message}`);
191
+ //console.log(`Error reading ignore file: ${error.message}`);
192
+ //Note, ignore file is private really.
167
193
  return [];
168
194
  //process.exit(1);
169
195
  }
@@ -215,7 +241,7 @@ const processDirectory = async (dir) => {
215
241
  results.push(...subResults);
216
242
  } else if (sharedData.options.ignoreFiles.includes(file)) {
217
243
  // do nothing
218
- // console.log(`XxxxXignorelist: file: ${file}`);
244
+ //console.log(`XxxxXignorelist: file: ${file}`);
219
245
  } else if (isMarkdown(file)) {
220
246
  sharedData.allMarkdownFiles.add(file);
221
247
  const result = await processFile(file);
@@ -246,7 +272,8 @@ const processDirectory = async (dir) => {
246
272
  : (sharedData.options.files = []);
247
273
 
248
274
  const pathToJsonIgnoreFile = path.join(
249
- sharedData.options.root,
275
+ sharedData.options.repo,
276
+ sharedData.options.doc,
250
277
  "_link_checker_sc/ignorefile.json"
251
278
  );
252
279
  //console.log(`debug: pathToJsonIgnoreFile: ${pathToJsonIgnoreFile}`);
@@ -255,7 +282,7 @@ const processDirectory = async (dir) => {
255
282
  );
256
283
 
257
284
  // process containing markdown, return results which includes links, headings, id anchors
258
- const results = await processDirectory(markdownDirectory);
285
+ const results = await processDirectory(sharedData.options.markdownroot);
259
286
 
260
287
  if (!results.allErrors) {
261
288
  results.allErrors = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdown_link_checker_sc",
3
- "version": "0.0.136",
3
+ "version": "0.0.138",
4
4
  "description": "Markdown Link Checker",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/errors.js CHANGED
@@ -11,14 +11,18 @@ class LinkError {
11
11
  this.link = link;
12
12
  this.file = this.link.page;
13
13
  this.fileRelativeToRoot = this.link.fileRelativeToRoot;
14
+ //console.log(`debugX: fileRelativeToRoot: ${this.fileRelativeToRoot}`);
14
15
  } else {
15
16
  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.root)[1];
17
+ this.fileRelativeToRoot = this.file.split(sharedData.options.docsroot)[1];
18
+ //console.log( `debug: sharedData.options.docsroot: ${sharedData.options.docsroot}` );
19
+ //console.log(`debug: fileRelativeToRoot: ${this.fileRelativeToRoot}`);
17
20
  this.fileRelativeToRoot =
18
21
  this.fileRelativeToRoot.startsWith("/") ||
19
22
  this.fileRelativeToRoot.startsWith("\\")
20
23
  ? this.fileRelativeToRoot.substring(1)
21
24
  : this.fileRelativeToRoot;
25
+ //console.log(`debug: 2fileRelativeToRoot: ${this.fileRelativeToRoot}`);
22
26
  }
23
27
  }
24
28
 
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 'normalize-path';
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.root,
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) === normalize(ignorableError.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.root)[1];
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) {
@@ -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.root) {
41
- pageFromRoot = page.split(sharedData.options.root)[1];
40
+ if (sharedData.options.docsroot) {
41
+ pageFromRoot = page.split(sharedData.options.docsroot)[1];
42
42
  } else {
43
- pageFromRoot = page.split(sharedData.options.directory)[1];
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.root,
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.root: ${sharedData.options.root}`);
20
- //console.log(`sharedData.options.directory: ${sharedData.options.directory}`);
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