hdoc-tools 0.7.12 → 0.7.13

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.
Files changed (2) hide show
  1. package/hdoc-validate.js +147 -0
  2. package/package.json +2 -1
@@ -0,0 +1,147 @@
1
+ const parseLinkDestination = require('markdown-it/lib/helpers/parse_link_destination');
2
+
3
+ (function () {
4
+ 'use strict';
5
+
6
+ const cheerio = require('cheerio'),
7
+ dree = require('dree'),
8
+ fs = require('fs'),
9
+ path = require('path'),
10
+ URL = require("url").URL;
11
+
12
+ let errors = {},
13
+ messages = {},
14
+ errorcount = 0,
15
+ filecount = 0;
16
+
17
+ const stringIsAValidUrl = (s) => {
18
+ try {
19
+ new URL(s);
20
+ return true;
21
+ } catch (err) {
22
+ return false;
23
+ }
24
+ };
25
+
26
+ const checkLinks = function (source_path, htmlFile, links) {
27
+ for (let i = 0; i < links.length; i++) {
28
+
29
+ // Validate that link is a valid URL first
30
+ if (!stringIsAValidUrl(links[i])) {
31
+
32
+ // Could be a relative path, check
33
+ const fileExists = doesFileExist(source_path, htmlFile, links[i]);
34
+ if (!fileExists) {
35
+ errorcount++;
36
+ }
37
+ } else {
38
+ messages[htmlFile.relativePath].push(`Link is valid External URL: ${links[i]}`);
39
+ }
40
+ }
41
+ };
42
+
43
+ const dreeOptions = {
44
+ descendants: true,
45
+ depth: 10,
46
+ extensions: ['htm', 'html'],
47
+ hash: false,
48
+ normalize: true,
49
+ size: false,
50
+ sizeInBytes: false,
51
+ stat: false,
52
+ symbolicLinks: false
53
+ };
54
+
55
+ let htmlFiles = [];
56
+
57
+ // File callbacks for html file scan
58
+ const fileCallback = function (element) {
59
+ filecount++;
60
+ htmlFiles.push(element);
61
+ };
62
+
63
+ const doesFileExist = function (source_path, html_path, relative_path) {
64
+ // Remove explicit anchor links
65
+ let file_path = path.join(source_path, relative_path.split('#')[0]);
66
+
67
+ if (!fs.existsSync(file_path) && !fs.existsSync(file_path + '.htm') && !fs.existsSync(file_path + '.html')) {
68
+ errors[html_path.relativePath].push(`Book resource does not exist: ${file_path}`);
69
+ return false;
70
+ } else {
71
+ messages[html_path.relativePath].push(`Book resource exists: ${file_path}`);
72
+ }
73
+ return true;
74
+ };
75
+
76
+ // Takes a dree element, returns an object with a pair of arrays
77
+ const getLinks = function (file) {
78
+ messages[file.relativePath].push('Parsing HTML file');
79
+ const htmlBody = fs.readFileSync(file.path, 'utf8');
80
+ let links = [];
81
+ const $ = cheerio.load(htmlBody);
82
+ const hrefs = $('a').map(function (i) {
83
+ return $(this).attr('href');
84
+ }).get();
85
+ const srcs = $('img').map(function (i) {
86
+ return $(this).attr('src');
87
+ }).get();
88
+ links.push(...hrefs);
89
+ links.push(...srcs);
90
+ return links;
91
+ };
92
+
93
+
94
+ exports.run = function (source_path, verbose) {
95
+ // Get a list of HTML files in source_path
96
+ dree.scan(source_path, dreeOptions, fileCallback);
97
+
98
+ for (let i = 0; i < htmlFiles.length; i++) {
99
+
100
+ // Initiate maps for errors and verbose messages for HTML file
101
+ errors[htmlFiles[i].relativePath] = [];
102
+ messages[htmlFiles[i].relativePath] = [];
103
+
104
+ const links = getLinks(htmlFiles[i]);
105
+ if (links.length === 0) {
106
+ messages[htmlFiles[i].relativePath].push('No links found in file');
107
+ } else {
108
+ checkLinks(source_path, htmlFiles[i], links);
109
+ }
110
+
111
+ }
112
+ if (errorcount === 0) {
113
+ console.log('\r\n---------------');
114
+ console.log(' No Errors ');
115
+ console.log('---------------\r\n');
116
+ } else {
117
+ console.log('\r\n------------');
118
+ console.log(' Errors ');
119
+ console.log('------------');
120
+
121
+ for (const key in errors) {
122
+ if (errors.hasOwnProperty(key) && errors[key].length > 0) {
123
+ console.log(`\r\n${errors[key].length} error(s) in ${key}`);
124
+ for (let i = 0; i < errors[key].length; i++) {
125
+ console.log(` - ${errors[key][i]}`);
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ if (verbose) {
132
+ console.log('\r\n-------------');
133
+ console.log(' Verbose ');
134
+ console.log('-------------');
135
+ for (const key in messages) {
136
+ if (messages.hasOwnProperty(key) && messages[key].length > 0) {
137
+ console.log(`\r\nMessage output for ${key}`);
138
+ for (let i = 0; i < messages[key].length; i++) {
139
+ console.log(` - ${messages[key][i]}`);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ console.log(`\r\nValidation Errors Found: ${errorcount}\r\n`);
145
+ return errorcount === 0 ? true : false;
146
+ };
147
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.7.12",
3
+ "version": "0.7.13",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {
@@ -13,6 +13,7 @@
13
13
  "hdoc-init.js",
14
14
  "hdoc-serve.js",
15
15
  "hdoc-stats.js",
16
+ "hdoc-validate.js",
16
17
  "validateNodeVer.js",
17
18
  "ui",
18
19
  "custom_modules",