hdoc-tools 0.9.29 → 0.9.31

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
@@ -33,6 +33,7 @@
33
33
  conversion_attempted = 0,
34
34
  conversion_success = 0,
35
35
  conversion_failed = 0,
36
+ css_templates = [],
36
37
  doc_header_template = '',
37
38
  doc_header_template_non_git = '',
38
39
  pdf_created = 0,
@@ -54,6 +55,7 @@
54
55
  work_path_content = '',
55
56
  verbose = false;
56
57
 
58
+
57
59
  const pdf_path_excluded = function (relative_path) {
58
60
  if (!hdocbook_project.pdfGeneration || hdocbook_project.pdfGeneration.exclude_paths === undefined) {
59
61
  return false;
@@ -241,7 +243,7 @@
241
243
 
242
244
  // Generate PDF file from HTML
243
245
  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);
246
+ 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
247
  }
246
248
  if (pdf_size > 0) pdf_created++;
247
249
 
@@ -452,7 +454,7 @@
452
454
 
453
455
  // Generate PDF file from HTML
454
456
  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);
457
+ 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
458
  }
457
459
  if (pdf_size > 0) pdf_created++;
458
460
  html_txt = `${fm_header}\n${doc_header}\n${html_txt}`;
@@ -606,7 +608,9 @@
606
608
  if (!validate && hdocbook_project.pdfGeneration !== undefined && hdocbook_project.pdfGeneration.enable !== undefined) {
607
609
  pdf_enable = hdocbook_project.pdfGeneration.enable;
608
610
  }
609
-
611
+
612
+ console.log(`Loading hdocbook config...`);
613
+
610
614
  const book_path = path.join(source_path, doc_id),
611
615
  hdocbook_path = path.join(book_path, 'hdocbook.json'),
612
616
  work_path = path.join(source_path, '_work'),
@@ -624,6 +628,20 @@
624
628
 
625
629
  if (hdocbook_config.publicSource.endsWith('.git')) hdocbook_config.publicSource = hdocbook_config.publicSource.substring(0, hdocbook_config.publicSource.length - 4);
626
630
 
631
+ console.log('Caching CSS for PDF generation...');
632
+ const css_files = [
633
+ path.join(pdf_template_path, 'css', 'custom-block.css'),
634
+ path.join(pdf_template_path, 'css', 'hdocs-pdf.css'),
635
+ path.join(pdf_template_path, 'css', 'vars.css')
636
+ ];
637
+ for (let i = 0; i < css_files.length; i++) {
638
+ try {
639
+ css_templates.push(fs.readFileSync(css_files[i], 'utf8'));
640
+ } catch (e) {
641
+ console.log(`Error reading file [${css_files[i]}]: ${e}`);
642
+ }
643
+ }
644
+
627
645
  console.log(`Building: ${doc_id} v${hdocbook_config.version}...\n`);
628
646
 
629
647
  // Make _work folder to copy everything into
@@ -637,6 +655,7 @@
637
655
  fs.mkdirSync(work_path);
638
656
 
639
657
  // Copy files from book into _work-doc_id folder
658
+ console.log(`Copying content into work folder...`);
640
659
  try {
641
660
  fs.copySync(path.join(source_path, doc_id), work_path_content);
642
661
  } catch (e) {
@@ -644,7 +663,9 @@
644
663
  process.exit(1);
645
664
  }
646
665
 
647
- // Ccreate MD5 hash of content before build
666
+ // Create MD5 hash of content before build
667
+ console.log(`Creating Hash...`);
668
+
648
669
  dree.scan(work_path_content, md5DreeOptions, hash_callback);
649
670
  let concat_hash = '|';
650
671
  for (let i = 0; i < built_file_hashes.length; i++) {
@@ -660,13 +681,14 @@
660
681
  const checksum_path = path.join(work_path_content, 'checksum.md5');
661
682
  try {
662
683
  fs.writeFileSync(checksum_path, hash);
663
- console.log('\nHash file creation success:', checksum_path);
684
+ console.log('Hash file creation success:', checksum_path);
664
685
  } catch (e) {
665
686
  console.log('\nError creating', checksum_path, ':', e);
666
687
  process.exit(1);
667
688
  }
668
689
 
669
690
  // Load document header templates
691
+ console.log(`Loading templates...`);
670
692
  try {
671
693
  doc_header_template = fs.readFileSync(doc_header_template_path, 'utf8');
672
694
  doc_header_template_non_git = fs.readFileSync(non_git_doc_header_template_path, 'utf8');
@@ -686,27 +708,36 @@
686
708
  process.exit(1);
687
709
  }
688
710
  }
689
- console.log('Processing navigation breadcrumbs...\n');
711
+ console.log(`Processing navigation breadcrumbs...`);
690
712
  bc = hdoc.build_breadcrumbs(hdocbook_config.navigation.items);
691
713
 
692
- console.log('Processing content...');
714
+ console.log(`Processing content...`);
693
715
  // Get a list of MD files in work_path
694
716
  dree.scan(work_path, dreeOptions, build_file_callback);
695
717
 
696
718
  if (pdf_enable) {
697
- // Create a Chromium browser instance to generate PDFs with
719
+ // Create a Chromium browser instance generate PDFs with
698
720
  browser = await puppeteer.launch({headless: 'new'});
699
721
  }
700
722
 
701
723
  // Work through MD files and convert to HTML
724
+ let mdPromiseArray = [];
702
725
  for (let i = 0; i < md_files.length; i++) {
703
- await transform_markdown_and_save_html(md_files[i]);
726
+ mdPromiseArray.push(md_files[i]);
704
727
  }
728
+ await Promise.all(mdPromiseArray.map(async (file) => {
729
+ await transform_markdown_and_save_html(file);
730
+ }));
705
731
 
706
732
  // Work through Static HTML files and add Frontmatter tags
733
+ let htmlPromiseArray = [];
707
734
  for (let i = 0; i < static_html_files.length; i++) {
708
- await transform_static_html(static_html_files[i]);
735
+ htmlPromiseArray.push(static_html_files[i]);
709
736
  }
737
+ await Promise.all(htmlPromiseArray.map(async (file) => {
738
+ await transform_static_html(file);
739
+ }));
740
+
710
741
 
711
742
  if (pdf_enable) {
712
743
  // Close the Chromium browser instance
@@ -734,14 +765,17 @@
734
765
  }
735
766
 
736
767
  // Delete markdown files
768
+ console.log(`Performing Markdown Cleanup`);
769
+
770
+ let filePromiseArray = [];
737
771
  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
- }
772
+ filePromiseArray.push(md_files_delete[i]);
744
773
  }
774
+ await Promise.all(filePromiseArray.map(async (file) => {
775
+ fs.unlink(file, (err => {
776
+ if (err) console.log(`Error deleting ${file}: ${e}`);
777
+ }));
778
+ }));
745
779
 
746
780
  // Add book read timing to the hdocbook.json
747
781
  hdocbook_config.readingTime = Math.ceil(book_read_time + ((book_read_time / 100) * 10));
@@ -756,6 +790,7 @@
756
790
 
757
791
  // Build the index
758
792
  // Create the DB and tables
793
+ console.log(`Building the Index`);
759
794
  let db = hdoc_build_db.create_db(work_path, doc_id);
760
795
  if (db.error && db.error !== null) {
761
796
  console.log(db.error);
@@ -767,6 +802,9 @@
767
802
  console.log(index.error);
768
803
  process.exit(1);
769
804
  }
805
+ if (verbose) {
806
+ console.log(`Index Build Complete`);
807
+ }
770
808
 
771
809
  if (!validate) {
772
810
  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.31",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {