hdoc-tools 0.9.29 → 0.9.30

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-build-db.js CHANGED
@@ -79,68 +79,71 @@
79
79
 
80
80
  if (!book_config.tags) book_config.tags = [];
81
81
 
82
+ let indexPromises = [];
82
83
  for (let i = 0; i < index_records.length; i++) {
83
- let index_path_name = index_records[i].relative_path.replace('\\', '/');
84
- index_path_name = '/' + index_path_name.replace(path.extname(index_records[i].relative_path), '');
84
+ indexPromises.push(index_records[i]);
85
+ }
86
+ await Promise.all(indexPromises.map(async (file) => {
87
+ let index_path_name = file.relative_path.replace('\\', '/');
88
+ index_path_name = '/' + index_path_name.replace(path.extname(file.relative_path), '');
85
89
  const index_vals = [
86
90
  index_path_name,
87
91
  doc_id,
88
92
  book_config.audience.join(','),
89
93
  book_config.tags.join(','),
90
- index_records[i].index_html.fm_props.title,
91
- index_records[i].index_html.text,
92
- index_records[i].index_html.preview,
94
+ file.index_html.fm_props.title,
95
+ file.index_html.text,
96
+ file.index_html.preview,
93
97
  book_config.productFamily,
94
- index_records[i].md5
98
+ file.md5
95
99
  ];
96
- const index_response = await hdoc_index.insert_record(db, 'hdoc_index', db_schema.hdoc_index, index_vals);
100
+ const index_response = hdoc_index.insert_record(db, 'hdoc_index', db_schema.hdoc_index, index_vals);
97
101
  if (!index_response.success) {
98
- console.log(`Index record creation failed - ${doc_id}/${index_records[i].index_html.fm_props.title}: ${index_response.error}`);
99
- continue;
100
- }
101
-
102
- // Now add metadata
103
- const meta_vals = [
104
- index_path_name,
105
- doc_id,
106
- index_records[i].metadata.contributor_count,
107
- index_records[i].metadata.edit_url,
108
- index_records[i].metadata.last_commit,
109
- index_records[i].pdf_size
110
- ];
111
- const meta_response = await hdoc_index.insert_record(db, 'hdoc_meta', db_schema.hdoc_meta, meta_vals);
112
- if (!meta_response.success) {
113
- console.log(`Index metadata record creation failed - ${doc_id}/${index_response.row_id}/${index_records[i].index_html.fm_props.title}: ${meta_response.error}`);
114
- continue;
115
- }
116
- if (verbose) {
117
- console.log(`Inserted index record ${index_response.row_id}: ${doc_id} - ${index_records[i].index_html.fm_props.title}`);
118
- console.log(`Inserted index metadata record for index ID: ${meta_response.row_id}`);
119
- }
120
-
121
- // Now add contributor records
122
- for (let j = 0; j < index_records[i].contributors.length; j++) {
123
- const contrib_vals = [
102
+ console.log(`Index record creation failed - ${doc_id}/${file.index_html.fm_props.title}: ${index_response.error}`);
103
+ } else {
104
+ // Now add metadata
105
+ const meta_vals = [
124
106
  index_path_name,
125
107
  doc_id,
126
- index_records[i].contributors[j].login,
127
- index_records[i].contributors[j].name,
128
- index_records[i].contributors[j].avatar_url,
129
- index_records[i].contributors[j].html_url
108
+ file.metadata.contributor_count,
109
+ file.metadata.edit_url,
110
+ file.metadata.last_commit,
111
+ file.pdf_size
130
112
  ];
131
- const cont_response = await hdoc_index.insert_record(db, 'hdoc_contributors', db_schema.hdoc_contributors, contrib_vals);
132
- if (!cont_response.success) {
133
- console.log(`Index document contributor record creation failed - ${doc_id}/${index_response.row_id}/${index_records[i].index_html.fm_props.title}: ${cont_response.error}`);
134
- continue;
113
+ const meta_response = await hdoc_index.insert_record(db, 'hdoc_meta', db_schema.hdoc_meta, meta_vals);
114
+ if (!meta_response.success) {
115
+ console.log(`Index metadata record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${meta_response.error}`);
116
+ } else {
117
+ if (verbose) {
118
+ console.log(`Inserted index record ${index_response.row_id}: ${doc_id} - ${file.index_html.fm_props.title}`);
119
+ console.log(`Inserted index metadata record for index ID: ${meta_response.row_id}`);
120
+ }
121
+
122
+ // Now add contributor records
123
+ for (let j = 0; j < file.contributors.length; j++) {
124
+ const contrib_vals = [
125
+ index_path_name,
126
+ doc_id,
127
+ file.contributors[j].login,
128
+ file.contributors[j].name,
129
+ file.contributors[j].avatar_url,
130
+ file.contributors[j].html_url
131
+ ];
132
+ const cont_response = await hdoc_index.insert_record(db, 'hdoc_contributors', db_schema.hdoc_contributors, contrib_vals);
133
+ if (!cont_response.success) {
134
+ console.log(`Index document contributor record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${cont_response.error}`);
135
+ continue;
136
+ }
137
+ if (verbose) {
138
+ console.log(`Inserted document contributor recordL ${cont_response.row_id}`);
139
+ }
140
+ }
141
+ response.index_success_count++;
135
142
  }
136
- if (verbose) {
137
- console.log(`Inserted document contributor recordL ${cont_response.row_id}`);
138
- }
139
143
  }
140
144
 
141
- response.index_success_count++;
142
-
143
- }
145
+ }));
146
+
144
147
  response.success = true;
145
148
  console.log(`\nIndex Build Complete: ${response.index_success_count} document index records created.`);
146
149
  return response;
package/hdoc-build-pdf.js CHANGED
@@ -9,20 +9,10 @@
9
9
  path = require('path'),
10
10
  hdoc = require(path.join(__dirname, 'hdoc-module.js'));
11
11
 
12
- const dree_options = {
13
- extensions: ['css'],
14
- normalize: true,
15
- };
16
-
17
- let css_files = [],
18
- hb_logo = '',
12
+ let hb_logo = '',
19
13
  footer = '',
20
14
  header = '';
21
15
 
22
- const file_callback = function (element) {
23
- css_files.push(element.path);
24
- };
25
-
26
16
  const get_footer = function (template_path) {
27
17
  let footer_content = null;
28
18
  try {
@@ -109,9 +99,11 @@
109
99
  return html_source;
110
100
  };
111
101
 
112
- exports.generate_pdf = async function (browser, pdf_template_path, pdf_template_content, book_config, html_source, target_file, verbose = false) {
113
- if (verbose) console.log(`Generating PDF: ${target_file}`);
102
+ exports.generate_pdf = async function (browser, pdf_template_path, pdf_template_content, book_config, html_source, target_file, css_templates, verbose = false) {
114
103
  let pdf_size = 0;
104
+
105
+ //dree.scan(pdf_template_path, dree_options_css, file_callback_css);
106
+
115
107
  // Cache footer
116
108
  if (footer === '') footer = get_footer(pdf_template_path);
117
109
 
@@ -135,37 +127,28 @@
135
127
 
136
128
  html_source = pdf_template_content.replace('{{book_title}}', book_config.title).replace('{{document_content}}', html_source);
137
129
 
138
- // Create a new page
139
130
  const page = await browser.newPage();
140
131
 
132
+ // To reflect CSS used for screens instead of print
133
+ await page.emulateMediaType('screen');
134
+
141
135
  // Set HTML content from HTML source
142
136
  await page.setContent(html_source, {
143
137
  waitUntil: 'domcontentloaded'
144
138
  });
145
-
146
- // To reflect CSS used for screens instead of print
147
- await page.emulateMediaType('screen');
148
-
149
- if (css_files.length === 0) {
150
- // Get a list of CSS files
151
- dree.scan(pdf_template_path, dree_options, file_callback);
152
- }
153
-
154
- for (let i = 0; i < css_files.length; i++) {
155
- await page.addStyleTag({
156
- path: css_files[i]
157
- });
139
+ for (let i = 0; i < css_templates.length; i++) {
140
+ try {
141
+ await page.addStyleTag({
142
+ content: css_templates[i]
143
+ });
144
+ } catch (e) {
145
+ console.log(`Error applying template for [${target_file}]: ${e}`);
146
+ }
158
147
  }
159
148
 
160
149
  try {
161
150
  const pdf_gen = await page.pdf({
162
151
  path: target_file,
163
- margin: {
164
- top: '30px',
165
- right: '35px',
166
- bottom: '80px',
167
- left: '35px'
168
- },
169
152
  printBackground: true,
170
153
  format: 'A4',
171
154
  displayHeaderFooter: true,
@@ -178,7 +161,9 @@
178
161
  left: "30px"
179
162
  }
180
163
  });
181
- if (verbose) console.log('PDF generation success.');
164
+ let currdate = new Date;
165
+ let datetime = currdate.toISOString();
166
+ if (verbose) console.log(`[${datetime}] PDF generation success: ${target_file}`);
182
167
 
183
168
  pdf_size = pdf_gen.byteLength;
184
169
  } catch (err) {
package/hdoc-build.js CHANGED
@@ -1,3 +1,5 @@
1
+ const { files } = require('jszip');
2
+
1
3
  (function () {
2
4
  'use strict';
3
5
 
@@ -33,6 +35,7 @@
33
35
  conversion_attempted = 0,
34
36
  conversion_success = 0,
35
37
  conversion_failed = 0,
38
+ css_templates = [],
36
39
  doc_header_template = '',
37
40
  doc_header_template_non_git = '',
38
41
  pdf_created = 0,
@@ -54,6 +57,7 @@
54
57
  work_path_content = '',
55
58
  verbose = false;
56
59
 
60
+
57
61
  const pdf_path_excluded = function (relative_path) {
58
62
  if (!hdocbook_project.pdfGeneration || hdocbook_project.pdfGeneration.exclude_paths === undefined) {
59
63
  return false;
@@ -241,7 +245,7 @@
241
245
 
242
246
  // Generate PDF file from HTML
243
247
  const pdf_file_path = file_path.path.replace(path.extname(file_path.path), '.pdf');
244
- pdf_size = await hdoc_build_pdf.generate_pdf(browser, pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, verbose);
248
+ pdf_size = await hdoc_build_pdf.generate_pdf(browser, pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, css_templates, verbose);
245
249
  }
246
250
  if (pdf_size > 0) pdf_created++;
247
251
 
@@ -452,7 +456,7 @@
452
456
 
453
457
  // Generate PDF file from HTML
454
458
  const pdf_file_path = file_path.path.replace(path.extname(file_path.path), '.pdf');
455
- pdf_size = await hdoc_build_pdf.generate_pdf(browser, pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, verbose);
459
+ pdf_size = await hdoc_build_pdf.generate_pdf(browser, pdf_template_path, pdf_template, hdocbook_config, pdf_txt, pdf_file_path, css_templates, verbose);
456
460
  }
457
461
  if (pdf_size > 0) pdf_created++;
458
462
  html_txt = `${fm_header}\n${doc_header}\n${html_txt}`;
@@ -606,7 +610,9 @@
606
610
  if (!validate && hdocbook_project.pdfGeneration !== undefined && hdocbook_project.pdfGeneration.enable !== undefined) {
607
611
  pdf_enable = hdocbook_project.pdfGeneration.enable;
608
612
  }
609
-
613
+
614
+ console.log(`Loading hdocbook config...`);
615
+
610
616
  const book_path = path.join(source_path, doc_id),
611
617
  hdocbook_path = path.join(book_path, 'hdocbook.json'),
612
618
  work_path = path.join(source_path, '_work'),
@@ -624,6 +630,20 @@
624
630
 
625
631
  if (hdocbook_config.publicSource.endsWith('.git')) hdocbook_config.publicSource = hdocbook_config.publicSource.substring(0, hdocbook_config.publicSource.length - 4);
626
632
 
633
+ console.log('Caching CSS for PDF generation...');
634
+ const css_files = [
635
+ path.join(pdf_template_path, 'css', 'custom-block.css'),
636
+ path.join(pdf_template_path, 'css', 'hdocs-pdf.css'),
637
+ path.join(pdf_template_path, 'css', 'vars.css')
638
+ ];
639
+ for (let i = 0; i < css_files.length; i++) {
640
+ try {
641
+ css_templates.push(fs.readFileSync(css_files[i], 'utf8'));
642
+ } catch (e) {
643
+ console.log(`Error reading file [${css_files[i]}]: ${e}`);
644
+ }
645
+ }
646
+
627
647
  console.log(`Building: ${doc_id} v${hdocbook_config.version}...\n`);
628
648
 
629
649
  // Make _work folder to copy everything into
@@ -637,6 +657,7 @@
637
657
  fs.mkdirSync(work_path);
638
658
 
639
659
  // Copy files from book into _work-doc_id folder
660
+ console.log(`Copying content into work folder...`);
640
661
  try {
641
662
  fs.copySync(path.join(source_path, doc_id), work_path_content);
642
663
  } catch (e) {
@@ -644,7 +665,9 @@
644
665
  process.exit(1);
645
666
  }
646
667
 
647
- // Ccreate MD5 hash of content before build
668
+ // Create MD5 hash of content before build
669
+ console.log(`Creating Hash...`);
670
+
648
671
  dree.scan(work_path_content, md5DreeOptions, hash_callback);
649
672
  let concat_hash = '|';
650
673
  for (let i = 0; i < built_file_hashes.length; i++) {
@@ -660,13 +683,14 @@
660
683
  const checksum_path = path.join(work_path_content, 'checksum.md5');
661
684
  try {
662
685
  fs.writeFileSync(checksum_path, hash);
663
- console.log('\nHash file creation success:', checksum_path);
686
+ console.log('Hash file creation success:', checksum_path);
664
687
  } catch (e) {
665
688
  console.log('\nError creating', checksum_path, ':', e);
666
689
  process.exit(1);
667
690
  }
668
691
 
669
692
  // Load document header templates
693
+ console.log(`Loading templates...`);
670
694
  try {
671
695
  doc_header_template = fs.readFileSync(doc_header_template_path, 'utf8');
672
696
  doc_header_template_non_git = fs.readFileSync(non_git_doc_header_template_path, 'utf8');
@@ -686,27 +710,36 @@
686
710
  process.exit(1);
687
711
  }
688
712
  }
689
- console.log('Processing navigation breadcrumbs...\n');
713
+ console.log(`Processing navigation breadcrumbs...`);
690
714
  bc = hdoc.build_breadcrumbs(hdocbook_config.navigation.items);
691
715
 
692
- console.log('Processing content...');
716
+ console.log(`Processing content...`);
693
717
  // Get a list of MD files in work_path
694
718
  dree.scan(work_path, dreeOptions, build_file_callback);
695
719
 
696
720
  if (pdf_enable) {
697
- // Create a Chromium browser instance to generate PDFs with
721
+ // Create a Chromium browser instance generate PDFs with
698
722
  browser = await puppeteer.launch({headless: 'new'});
699
723
  }
700
724
 
701
725
  // Work through MD files and convert to HTML
726
+ let mdPromiseArray = [];
702
727
  for (let i = 0; i < md_files.length; i++) {
703
- await transform_markdown_and_save_html(md_files[i]);
728
+ mdPromiseArray.push(md_files[i]);
704
729
  }
730
+ await Promise.all(mdPromiseArray.map(async (file) => {
731
+ await transform_markdown_and_save_html(file);
732
+ }));
705
733
 
706
734
  // Work through Static HTML files and add Frontmatter tags
735
+ let htmlPromiseArray = [];
707
736
  for (let i = 0; i < static_html_files.length; i++) {
708
- await transform_static_html(static_html_files[i]);
737
+ htmlPromiseArray.push(static_html_files[i]);
709
738
  }
739
+ await Promise.all(htmlPromiseArray.map(async (file) => {
740
+ await transform_static_html(file);
741
+ }));
742
+
710
743
 
711
744
  if (pdf_enable) {
712
745
  // Close the Chromium browser instance
@@ -734,14 +767,17 @@
734
767
  }
735
768
 
736
769
  // Delete markdown files
770
+ console.log(`Performing Markdown Cleanup`);
771
+
772
+ let filePromiseArray = [];
737
773
  for (let i = 0; i < md_files_delete.length; i++) {
738
- // Delete MD file from _work path
739
- try {
740
- fs.unlinkSync(md_files_delete[i]);
741
- } catch (e) {
742
- console.log(`Error deleting ${md_files_delete[i]}: ${e}`);
743
- }
774
+ filePromiseArray.push(md_files_delete[i]);
744
775
  }
776
+ await Promise.all(filePromiseArray.map(async (file) => {
777
+ fs.unlink(file, (err => {
778
+ if (err) console.log(`Error deleting ${file}: ${e}`);
779
+ }));
780
+ }));
745
781
 
746
782
  // Add book read timing to the hdocbook.json
747
783
  hdocbook_config.readingTime = Math.ceil(book_read_time + ((book_read_time / 100) * 10));
@@ -756,6 +792,7 @@
756
792
 
757
793
  // Build the index
758
794
  // Create the DB and tables
795
+ console.log(`Building the Index`);
759
796
  let db = hdoc_build_db.create_db(work_path, doc_id);
760
797
  if (db.error && db.error !== null) {
761
798
  console.log(db.error);
@@ -767,6 +804,9 @@
767
804
  console.log(index.error);
768
805
  process.exit(1);
769
806
  }
807
+ if (verbose) {
808
+ console.log(`Index Build Complete`);
809
+ }
770
810
 
771
811
  if (!validate) {
772
812
  try {
package/hdoc-db.js CHANGED
@@ -25,7 +25,7 @@
25
25
  }
26
26
  };
27
27
 
28
- exports.insert_record = async function (db, table, columns, values) {
28
+ exports.insert_record = function (db, table, columns, values) {
29
29
  let response = {
30
30
  success: false,
31
31
  row_id: 0,
package/hdoc-validate.js CHANGED
@@ -405,51 +405,59 @@
405
405
 
406
406
  // Do spellchecking on markdown files
407
407
  let md_files_spellchecked = {};
408
+ let mdPromiseArray = [];
408
409
  for (let i = 0; i < md_to_validate.length; i++) {
409
- // Initiate maps for errors and verbose messages for markdown file
410
- errors[md_to_validate[i].relativePath] = [];
411
- messages[md_to_validate[i].relativePath] = [];
412
- warnings[md_to_validate[i].relativePath] = [];
413
-
414
- await spellcheckContent(md_to_validate[i], exclude_spellcheck);
415
- md_files_spellchecked[md_to_validate[i].relativePath.replace('.' + md_to_validate[i].extension, '')] = true;
410
+ mdPromiseArray.push(md_to_validate[i]);
416
411
  }
412
+ await Promise.all(mdPromiseArray.map(async (file) => {
413
+ //await transform_markdown_and_save_html(file);
414
+ // Initiate maps for errors and verbose messages for markdown file
415
+ errors[file.relativePath] = [];
416
+ messages[file.relativePath] = [];
417
+ warnings[file.relativePath] = [];
418
+
419
+ await spellcheckContent(file, exclude_spellcheck);
420
+ md_files_spellchecked[file.relativePath.replace('.' + file.extension, '')] = true;
421
+ }));
417
422
 
418
423
  // Perform rest of validation against HTML files
419
424
  let listContent = '';
425
+ let htmlPromiseArray = [];
420
426
  for (let i = 0; i < html_to_validate.length; i++) {
421
-
427
+ htmlPromiseArray.push(html_to_validate[i]);
428
+ }
429
+ await Promise.all(mdPromiseArray.map(async (file) => {
422
430
  // Initiate maps for errors and verbose messages for HTML file
423
- errors[html_to_validate[i].relativePath] = [];
424
- messages[html_to_validate[i].relativePath] = [];
425
- warnings[html_to_validate[i].relativePath] = [];
431
+ errors[file.relativePath] = [];
432
+ messages[file.relativePath] = [];
433
+ warnings[file.relativePath] = [];
426
434
 
427
435
  // Check for British spellings in static HTML content
428
- if (!md_files_spellchecked[html_to_validate[i].relativePath.replace('.' + html_to_validate[i].extension, '')]) {
429
- await spellcheckContent(html_to_validate[i], exclude_spellcheck);
436
+ if (!md_files_spellchecked[file.relativePath.replace('.' + file.extension, '')]) {
437
+ await spellcheckContent(file, exclude_spellcheck);
430
438
  }
431
439
 
432
- const links = getLinks(html_to_validate[i]);
440
+ const links = getLinks(file);
433
441
  if (links.href.length === 0) {
434
- messages[html_to_validate[i].relativePath].push('No links found in file');
442
+ messages[file.relativePath].push('No links found in file');
435
443
  } else {
436
- await checkLinks(source_path, html_to_validate[i], links.href, hdocbook_config);
444
+ await checkLinks(source_path, file, links.href, hdocbook_config);
437
445
  }
438
446
  if (links.img.length === 0) {
439
- messages[html_to_validate[i].relativePath].push('No images found in file');
447
+ messages[file.relativePath].push('No images found in file');
440
448
  } else {
441
- await checkImages(source_path, html_to_validate[i], links.img);
449
+ await checkImages(source_path, file, links.img);
442
450
  }
443
451
 
444
452
  // Check for multiple H1 tags
445
- await checkTags(html_to_validate[i]);
453
+ await checkTags(file);
446
454
 
447
455
  // Build list content for Google
448
- listContent += `/${html_to_validate[i].relativePath.replace(path.extname(html_to_validate[i].relativePath), '')}`;
449
- if (i < html_to_validate.length - 1) {
450
- listContent += '\r\n';
451
- }
452
- }
456
+ listContent += `/${file.relativePath.replace(path.extname(file.relativePath), '')}`;
457
+ listContent += '\r\n';
458
+ }));
459
+
460
+
453
461
  try {
454
462
  // Write list
455
463
  const listFile = path.join(source_path, doc_id, 'links.txt');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.9.29",
3
+ "version": "0.9.30",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {