hdoc-tools 0.9.5 → 0.9.7

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Hornbill Docs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -39,6 +39,12 @@ Performs a local build of the book, validates the links and static content are p
39
39
 
40
40
  If the -v switch is provided, then a more verbose output is provided, which includes a list of all HTML files created and checked for embedded links and static content.
41
41
 
42
+ ### build
43
+
44
+ Performs a minimum local build of the book, then validates the links and static content are present and correct.
45
+
46
+ If the -v switch is provided, then a more verbose output is provided, which includes a list of all HTML files created and checked for embedded links and static content.
47
+
42
48
  ### serve
43
49
 
44
50
  Starts a local web server on port 3000, serving the book content.
package/hdoc-build.js CHANGED
@@ -570,10 +570,6 @@
570
570
  const nav_a = nav_items[a];
571
571
  const parent_a = nav_a.text;
572
572
  if (nav_a.link) {
573
- if (nav_a.link.includes('\\')) {
574
- console.log(`Navigation items should not contain backslashes: ${nav_a.link}`);
575
- process.exit(1);
576
- }
577
573
  bc[nav_a.link] = [{
578
574
  text: nav_a.text,
579
575
  link: nav_a.link
@@ -584,10 +580,6 @@
584
580
  const nav_b = nav_a.items[b];
585
581
  const parent_b = nav_b.text;
586
582
  if (nav_b.link) {
587
- if (nav_b.link.includes('\\')) {
588
- console.log(`Navigation items should not contain backslashes: ${nav_b.link}`);
589
- process.exit(1);
590
- }
591
583
  if (bc[nav_a.link]) {
592
584
  bc[nav_b.link] = bc[nav_a.link];
593
585
  } else {
@@ -607,10 +599,6 @@
607
599
  const nav_c = nav_b.items[c];
608
600
  const parent_c = nav_c.text;
609
601
  if (nav_c.link) {
610
- if (nav_c.link.includes('\\')) {
611
- console.log(`Navigation items should not contain backslashes: ${nav_c.link}`);
612
- process.exit(1);
613
- }
614
602
  if (bc[nav_b.link]) {
615
603
  bc[nav_c.link] = bc[nav_b.link];
616
604
  } else {
@@ -633,10 +621,6 @@
633
621
  for (let d = 0; d < nav_c.items.length; d++) {
634
622
  const nav_d = nav_c.items[d];
635
623
  if (nav_d.link) {
636
- if (nav_d.link.includes('\\')) {
637
- console.log(`Navigation items should not contain backslashes: ${nav_d.link}`);
638
- process.exit(1);
639
- }
640
624
  if (bc[nav_c.link]) {
641
625
  bc[nav_d.link] = bc[nav_c.link];
642
626
  } else {
@@ -690,7 +674,13 @@
690
674
  // Load the hdocbook-project.json file to get the docId
691
675
  // use the docId to get the book config
692
676
  const hdocbook_project_config_path = path.join(source_path, 'hdocbook-project.json');
693
- hdocbook_project = require(hdocbook_project_config_path);
677
+ try {
678
+ hdocbook_project = require(hdocbook_project_config_path);
679
+ } catch (e) {
680
+ console.log('File not found: hdocbook-project.json\n');
681
+ console.log('hdoc build/validate needs to be run in the root of a HDoc Book.\n');
682
+ process.exit(1);
683
+ }
694
684
  doc_id = hdocbook_project.docId;
695
685
 
696
686
  if (!validate && hdocbook_project.pdfGeneration !== undefined && hdocbook_project.pdfGeneration.enable !== undefined) {
@@ -703,6 +693,7 @@
703
693
  work_hdocbook_path = path.join(work_path, doc_id, 'hdocbook.json');
704
694
 
705
695
  hdocbook_config = require(hdocbook_path);
696
+ if (hdocbook_config.publicSource.endsWith('.git')) hdocbook_config.publicSource = hdocbook_config.publicSource.substring(0, hdocbook_config.publicSource.length - 4);
706
697
 
707
698
  console.log(`Building: ${doc_id} v${hdocbook_config.version}...\n`);
708
699
 
@@ -833,6 +824,8 @@
833
824
  } catch (e) {
834
825
  console.log('\nError creating ZIP: ' + e);
835
826
  }
827
+ } else {
828
+ console.log('\nValidation Complete\n');
836
829
  }
837
830
  };
838
831
  })();
package/hdoc-help.js CHANGED
@@ -11,20 +11,23 @@ Command Line Usage
11
11
 
12
12
  Commands
13
13
 
14
+ - build
15
+ Performs a local build of the book, and outputs as a ZIP file
16
+
14
17
  - help
15
18
  Outputs available arguments and switches
16
19
 
17
20
  - init
18
21
  Initializes a new HDocBook project from a template, using runtime input variables
19
22
 
23
+ - serve
24
+ Starts a local web server on port 3000, serving the content. Supports a -port N to use a different port
25
+
20
26
  - stats
21
27
  Returns statistics regarding the book you are working on. Supports a -v switch for verbose output
22
28
 
23
- - build
24
- Performs a local build of the book, and outputs as a ZIP file.
25
-
26
- - serve
27
- Starts a local web server on port 3000, serving the content. Supports a -port N to use a different port
29
+ - validate
30
+ Validates the book content
28
31
 
29
32
  Example
30
33
 
package/hdoc-init.js CHANGED
@@ -123,7 +123,12 @@
123
123
  // those files into place, with a few variable replacements.
124
124
 
125
125
  console.log('Hornbill HDocBook Init', '\r\n');
126
+
127
+ const curr_dirs = source_path.split(path.sep);
128
+ let doc_id = curr_dirs[curr_dirs.length - 1];
129
+
126
130
  prompt.start();
131
+ promptProps[0].default = doc_id;
127
132
  prompt.get(promptProps, function (err, result) {
128
133
  if (err) {
129
134
  console.error(err);
package/hdoc-validate.js CHANGED
@@ -11,9 +11,14 @@
11
11
  hdoc = require(path.join(__dirname, 'hdoc-module.js')),
12
12
  translator = require('american-british-english-translator');
13
13
 
14
- const agent = new https.Agent({
15
- rejectUnauthorized: false
16
- });
14
+ const agent = new https.Agent({
15
+ rejectUnauthorized: false
16
+ }),
17
+ spellcheck_options = {
18
+ british: true,
19
+ spelling: true
20
+ },
21
+ regex_nav_paths = /[a-z-\/]+/g;
17
22
 
18
23
  let prod_families = {};
19
24
 
@@ -34,27 +39,21 @@
34
39
  throw `Unexpected Status ${prods.status}`;
35
40
  }
36
41
  } catch (e) {
37
- // Handle errors
38
42
  console.log(`Error returning product families: ${e}`);
39
43
  return false;
40
44
  }
41
45
  return true;
42
46
  };
43
47
 
44
- const checkBritishSpelling = async function(source, excludes, text) {
45
- if (!errors[source]) errors[source] = [];
46
- var options = {
47
- british: true,
48
- spelling: true
49
- };
50
-
51
- let rel_source = source.replaceAll('\\', '/');
52
- rel_source = rel_source.substring(0, rel_source.length - path.extname(source).length);
53
- if (rel_source.includes('/_work/')) {
54
- rel_source = rel_source.split('/_work/')[1];
55
- }
56
-
57
- const translate_output = translator.translate(text, options);
48
+ const spellcheckHTML = async function (htmlFile, excludes) {
49
+ const htmlBody = fs.readFileSync(htmlFile.path, 'utf8');
50
+ const text = html2text.convert(htmlBody, {
51
+ wordwrap: null,
52
+ selectors: [
53
+ { selector: 'code', format: 'skip'}
54
+ ]
55
+ });
56
+ const translate_output = translator.translate(text, spellcheck_options);
58
57
  if(Object.keys(translate_output).length){
59
58
  for (const key in translate_output) {
60
59
  if (translate_output.hasOwnProperty(key)) {
@@ -62,10 +61,10 @@
62
61
  for (let i = 0; i < translate_output[key].length; i++) {
63
62
  for (const spelling in translate_output[key][i]) {
64
63
  if (translate_output[key][i].hasOwnProperty(spelling)) {
65
- if (!excludes[rel_source]) {
66
- errors[source].push(`${error_message} ${spelling} should be ${translate_output[key][i][spelling].details}`);
67
- } else if (!excludes[rel_source].includes(spelling.toLowerCase())) {
68
- errors[source].push(`${error_message} ${spelling} should be ${translate_output[key][i][spelling].details}`);
64
+ if (!excludes[htmlFile.relativePath]) {
65
+ errors[htmlFile.relativePath].push(`${error_message} ${spelling} should be ${translate_output[key][i][spelling].details}`);
66
+ } else if (!excludes[htmlFile.relativePath].includes(spelling.toLowerCase())) {
67
+ errors[htmlFile.relativePath].push(`${error_message} ${spelling} should be ${translate_output[key][i][spelling].details}`);
69
68
  }
70
69
  }
71
70
  }
@@ -75,15 +74,59 @@
75
74
  }
76
75
  };
77
76
 
78
- const checkBritishSpellings = async function (htmlFile, excludes) {
79
- const htmlBody = fs.readFileSync(htmlFile.path, 'utf8');
80
- const text = html2text.convert(htmlBody, {
81
- wordwrap: null,
82
- selectors: [
83
- { selector: 'code', format: 'skip'}
84
- ]
85
- });
86
- checkBritishSpelling(htmlFile.path, excludes, text);
77
+ const checkNavigation = async function (doc_id, flat_nav) {
78
+ let nav_errors = [];
79
+ for (const key in flat_nav) {
80
+ if (flat_nav.hasOwnProperty(key)) {
81
+ // doc paths should only contain a-z - characters
82
+ const invalid_chars = key.replace(regex_nav_paths, '');
83
+ if (invalid_chars !== '') {
84
+ nav_errors.push(`Navigation path [${key}] contains the following invalid characters: [${[...invalid_chars].join('] [')}]`);
85
+ }
86
+
87
+ //Validate path
88
+ const paths = key.split('/');
89
+ for (let i = 0; i < paths.length; i++) {
90
+ const path_words = paths[i].split('-');
91
+ for (let j = 0; j < path_words.length; j++) {
92
+ const translate_output = translator.translate(path_words[j], spellcheck_options);
93
+ if(Object.keys(translate_output).length){
94
+ for (const spell_val in translate_output) {
95
+ if (translate_output.hasOwnProperty(spell_val)) {
96
+ for (const spelling in translate_output[spell_val][0]) {
97
+ if (translate_output[spell_val][0].hasOwnProperty(spelling)) {
98
+ nav_errors.push(`Navigation path [${key}] key contains a British English spelling: ${spelling} should be ${translate_output[spell_val][0][spelling].details}`);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ // Validate display names/bookmarks
108
+ for (let i = 0; i < flat_nav[key].length; i++) {
109
+ if (flat_nav[key][i].link === key) {
110
+ const translate_output = translator.translate(flat_nav[key][i].text, spellcheck_options);
111
+ if(Object.keys(translate_output).length){
112
+ for (const spell_val in translate_output) {
113
+ if (translate_output.hasOwnProperty(spell_val)) {
114
+ for (let j = 0; j < translate_output[spell_val].length; j++) {
115
+ for (const spelling in translate_output[spell_val][j]) {
116
+ if (translate_output[spell_val][j].hasOwnProperty(spelling)) {
117
+ nav_errors.push(`Navigation path [${key}] display text contains a British English spelling: ${spelling} should be ${translate_output[spell_val][j][spelling].details}`);
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+
127
+ }
128
+ }
129
+ return nav_errors;
87
130
  };
88
131
 
89
132
  const checkLinks = async function (source_path, htmlFile, links, hdocbook_config) {
@@ -163,7 +206,7 @@
163
206
  symbolicLinks: false
164
207
  };
165
208
 
166
- // File callbacks for html file scan
209
+ // File scan callback
167
210
  const fileCallback = function (element) {
168
211
  html_files.push(element);
169
212
  };
@@ -256,31 +299,43 @@
256
299
 
257
300
  // Check product family
258
301
  let valid_product = false;
302
+ let meta_errors = [];
259
303
  for (let i = 0; i < prod_families.products.length; i++) {
260
304
  if (prod_families.products[i].id === hdocbook_config.productFamily) {
261
305
  valid_product = true;
262
306
  }
263
307
  }
264
308
  if (!valid_product) {
309
+ meta_errors.push(`Incorrect productFamily: ${hdocbook_config.productFamily}`)
310
+ }
311
+
312
+ // Check navigation spellings
313
+ const nav_errors = await checkNavigation(doc_id, nav_items);
314
+ if (nav_errors.length > 0) meta_errors.push(...nav_errors);
315
+
316
+ if (meta_errors.length > 0) {
265
317
  console.log('\r\n-----------------------');
266
318
  console.log(' Validation Output ');
267
- console.log('-----------------------\r\n');
268
- console.log(`- Incorrect productFamily: ${hdocbook_config.productFamily}`)
269
- console.log(`\r\n1 Validation Errors Found\r\n`);
319
+ console.log('-----------------------');
320
+ console.log()
321
+ console.log(`\r\n${meta_errors.length} Validation Errors Found\r\n`);
322
+ for (let i = 0; i < meta_errors.length; i++) {
323
+ console.log(`- ${meta_errors[i]}`);
324
+ }
270
325
  return false;
271
326
  }
272
327
 
273
328
  if (hdocbook_project.validation) {
274
329
  if (hdocbook_project.validation.exclude_links && hdocbook_project.validation.exclude_links instanceof Array) {
275
- hdocbook_project.validation.exclude_links.forEach(function(excl_link) {
330
+ hdocbook_project.validation.exclude_links.forEach(function(excl_link) {
276
331
  exclude_links[excl_link] = true;
277
332
  });
278
- }
279
- if (hdocbook_project.validation.exclude_spellcheck && hdocbook_project.validation.exclude_spellcheck instanceof Array) {
280
- hdocbook_project.validation.exclude_spellcheck.forEach(function(excl_sc) {
281
- exclude_spellcheck[excl_sc.document_path] = excl_sc.words;
282
- });
283
- }
333
+ }
334
+ if (hdocbook_project.validation.exclude_spellcheck && hdocbook_project.validation.exclude_spellcheck instanceof Array) {
335
+ hdocbook_project.validation.exclude_spellcheck.forEach(function(excl_sc) {
336
+ exclude_spellcheck[excl_sc.document_path] = excl_sc.words;
337
+ });
338
+ }
284
339
  }
285
340
 
286
341
  let listContent = '';
@@ -292,7 +347,7 @@
292
347
  warnings[html_files[i].relativePath] = [];
293
348
 
294
349
  // Check for Britishisms
295
- await checkBritishSpellings(html_files[i], exclude_spellcheck);
350
+ await spellcheckHTML(html_files[i], exclude_spellcheck);
296
351
 
297
352
  const links = getLinks(html_files[i]);
298
353
  if (links.href.length === 0) {
package/hdoc.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  (async function () {
3
3
  'use strict';
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {
@@ -21,7 +21,8 @@
21
21
  "validateNodeVer.js",
22
22
  "ui",
23
23
  "custom_modules",
24
- "templates"
24
+ "templates",
25
+ "templates/init/.gitignore"
25
26
  ],
26
27
  "scripts": {
27
28
  "preinstall": "node validateNodeVer",
@@ -0,0 +1,7 @@
1
+ _work/
2
+ node_modules/
3
+ package-lock.json
4
+ .wsuo
5
+ VSWorkspaceState.json
6
+ slnx.state
7
+ slnx.sqlite
package/ui/index.html CHANGED
@@ -224,7 +224,7 @@
224
224
  (n) minutes to read
225
225
  </li>
226
226
  <li class="ps-0 mt-0 nav-bar-item">
227
- <a class="link c-pointer">(n) contributers</a>
227
+ <a class="link c-pointer">(n) contributors</a>
228
228
  </li>
229
229
  </ul>
230
230
  </div>