hdoc-tools 0.7.12 → 0.7.14

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/hdoc-serve.js CHANGED
@@ -112,6 +112,7 @@
112
112
 
113
113
  function expand_variables(text) {
114
114
  // For debug mode our base path is our root??
115
+ text = text.replaceAll('{{BASE_PATH}}', '/' + docId);
115
116
  text = text.replaceAll('{{DOC_ID}}', docId);
116
117
  text = text.replaceAll('{{BUILD_NUMBER}}', '0');
117
118
 
@@ -324,14 +325,31 @@
324
325
 
325
326
  // Return a 404 error here
326
327
  send_content_resource_404(req, res);
327
- });
328
+ });
328
329
 
329
330
  // Catch all
330
331
  app.get('/*', function (req, res) {
331
332
 
332
- let ui_file_path = path.join(ui_path, req.url);
333
+ let segs = req.url.split('/');
334
+ if (segs.length > 2 && segs[1] === docId) {
335
+ // In this case we are looking for static content within the book
336
+ // Create the file path
337
+ let url = req.url.replace('/content/', '/');
338
+ console.log('URL Requested:', url);
339
+ let file_path = path.join(source_path, url);
340
+
341
+ // If the file exists, send it.
342
+ if (fs.existsSync(file_path) == true) {
343
+ send_file(req, res, file_path);
344
+ return;
345
+ }
333
346
 
334
- console.log('URL Root:', req.url);
347
+ // All else fails, we have not file to return, so return a 404 error here
348
+ send_content_resource_404(req, res);
349
+ return;
350
+ }
351
+
352
+ let ui_file_path = path.join(ui_path, req.url);
335
353
 
336
354
  // To support the SPA application behavior, if there is no file extension present, then
337
355
  // we simply return the /index.html file content to the client
@@ -0,0 +1,160 @@
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
+ htmlFiles = [];
17
+
18
+ const stringIsAValidUrl = (s) => {
19
+ try {
20
+ new URL(s);
21
+ return true;
22
+ } catch (err) {
23
+ return false;
24
+ }
25
+ };
26
+
27
+ const checkLinks = function (source_path, htmlFile, links) {
28
+ for (let i = 0; i < links.length; i++) {
29
+
30
+ // Validate that link is a valid URL first
31
+ if (!stringIsAValidUrl(links[i])) {
32
+
33
+ // Could be a relative path, check
34
+ const fileExists = doesFileExist(source_path, htmlFile, links[i]);
35
+ if (!fileExists) {
36
+ errorcount++;
37
+ }
38
+ } else {
39
+ messages[htmlFile.relativePath].push(`Link is valid External URL: ${links[i]}`);
40
+ }
41
+ }
42
+ };
43
+
44
+ const dreeOptions = {
45
+ descendants: true,
46
+ depth: 10,
47
+ extensions: ['htm', 'html'],
48
+ hash: false,
49
+ normalize: true,
50
+ size: false,
51
+ sizeInBytes: false,
52
+ stat: false,
53
+ symbolicLinks: false
54
+ };
55
+
56
+ // File callbacks for html file scan
57
+ const fileCallback = function (element) {
58
+ filecount++;
59
+ htmlFiles.push(element);
60
+ };
61
+
62
+ const doesFileExist = function (source_path, html_path, relative_path) {
63
+ // Remove explicit anchor links
64
+ let file_path = path.join(source_path, relative_path.split('#')[0]);
65
+
66
+ if (!fs.existsSync(file_path) && !fs.existsSync(file_path + '.htm') && !fs.existsSync(file_path + '.html')) {
67
+ errors[html_path.relativePath].push(`Book resource does not exist: ${file_path}`);
68
+ return false;
69
+ } else {
70
+ messages[html_path.relativePath].push(`Book resource exists: ${file_path}`);
71
+ }
72
+ return true;
73
+ };
74
+
75
+ // Takes a dree element, returns an object with a pair of arrays
76
+ const getLinks = function (file) {
77
+ messages[file.relativePath].push('Parsing HTML file');
78
+ const htmlBody = fs.readFileSync(file.path, 'utf8');
79
+ let links = [];
80
+ const $ = cheerio.load(htmlBody);
81
+ const hrefs = $('a').map(function (i) {
82
+ return $(this).attr('href');
83
+ }).get();
84
+ const srcs = $('img').map(function (i) {
85
+ return $(this).attr('src');
86
+ }).get();
87
+ links.push(...hrefs);
88
+ links.push(...srcs);
89
+ return links;
90
+ };
91
+
92
+
93
+ exports.run = function (source_path, verbose) {
94
+ // Get a list of HTML files in source_path
95
+ dree.scan(source_path, dreeOptions, fileCallback);
96
+
97
+ let listContent = '';
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
+ // Build list content for Google
112
+ listContent += `/${htmlFiles[i].relativePath}`;
113
+ if (i < htmlFiles.length - 1) {
114
+ listContent += '\r\n';
115
+ }
116
+ }
117
+ try {
118
+ // Write list
119
+ const listFile = path.join(source_path, 'list.txt');
120
+ fs.writeFileSync(listFile, listContent);
121
+ console.log(`${listFile} created successfully`);
122
+ } catch (err) {
123
+ console.error(err);
124
+ }
125
+ if (errorcount === 0) {
126
+ console.log('\r\n---------------');
127
+ console.log(' No Errors ');
128
+ console.log('---------------\r\n');
129
+ } else {
130
+ console.log('\r\n------------');
131
+ console.log(' Errors ');
132
+ console.log('------------');
133
+
134
+ for (const key in errors) {
135
+ if (errors.hasOwnProperty(key) && errors[key].length > 0) {
136
+ console.log(`\r\n${errors[key].length} error(s) in ${key}`);
137
+ for (let i = 0; i < errors[key].length; i++) {
138
+ console.log(` - ${errors[key][i]}`);
139
+ }
140
+ }
141
+ }
142
+ }
143
+
144
+ if (verbose) {
145
+ console.log('\r\n-------------');
146
+ console.log(' Verbose ');
147
+ console.log('-------------');
148
+ for (const key in messages) {
149
+ if (messages.hasOwnProperty(key) && messages[key].length > 0) {
150
+ console.log(`\r\nMessage output for ${key}`);
151
+ for (let i = 0; i < messages[key].length; i++) {
152
+ console.log(` - ${messages[key][i]}`);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ console.log(`\r\nValidation Errors Found: ${errorcount}\r\n`);
158
+ return errorcount === 0 ? true : false;
159
+ };
160
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.7.12",
3
+ "version": "0.7.14",
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",