hdoc-tools 0.21.0 → 0.22.0

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
@@ -1,260 +1,262 @@
1
- (() => {
2
- const path = require("node:path");
3
- const hdoc_index = require(path.join(__dirname, "hdoc-db.js"));
4
- const database = require("better-sqlite3");
5
-
6
- const db_schema = {
7
- hdoc_index: [
8
- "resource_url UNINDEXED",
9
- "book_id",
10
- "book_audience UNINDEXED",
11
- "book_tags",
12
- "doc_title",
13
- "doc_content",
14
- "doc_preview UNINDEXED",
15
- "doc_family_id",
16
- "doc_md5_hash UNINDEXED",
17
- "doc_lastmod",
18
- ],
19
- hdoc_meta: [
20
- "resource_url",
21
- "book_id",
22
- "contributor_count INTEGER UNINDEXED",
23
- "edit_url UNINDEXED",
24
- "last_commit UNINDEXED",
25
- "pdf_size INTEGER UNINDEXED",
26
- ],
27
- hdoc_contributors: [
28
- "resource_url",
29
- "book_id",
30
- "login",
31
- "name",
32
- "avatar UNINDEXED",
33
- "url UNINDEXED",
34
- ],
35
- hdoc_redirects: [
36
- "resource_url",
37
- "location_url",
38
- "http_code INTEGER UNINDEXED",
39
- ],
40
- };
41
-
42
- exports.create_table = (db, table, cols, virtual, fts5) => {
43
- const table_created = hdoc_index.create_table(
44
- db,
45
- table,
46
- cols,
47
- virtual,
48
- fts5,
49
- );
50
- if (table_created !== null) {
51
- return `\nError creating table: ${table_created}`;
52
- }
53
- console.log(`\nTable created: ${table}`);
54
- return null;
55
- };
56
-
57
- exports.create_db = function (db_path, doc_id) {
58
- const response = {
59
- error: null,
60
- db: null,
61
- };
62
- console.log("\nPerforming SQlite index creation...");
63
- const db_name = path.join(db_path, doc_id, "index.db");
64
- response.db = new database(db_name);
65
- response.db.pragma('encoding="UTF-8"');
66
- console.log(`\nDatabase created: ${db_name}`);
67
-
68
- // Create tables
69
- for (const key in db_schema) {
70
- if (Object.hasOwn(db_schema, key)) {
71
- const virtual = key === "hdoc_index";
72
- const fts5 = key === "hdoc_index";
73
- const table_created_error = this.create_table(
74
- response.db,
75
- key,
76
- db_schema[key],
77
- virtual,
78
- fts5,
79
- );
80
- if (table_created_error !== null) {
81
- console.error(table_created_error);
82
- }
83
- }
84
- }
85
- return response;
86
- };
87
-
88
- exports.populate_redirects = (db, redirect_records, verbose = false) => {
89
- const response = {
90
- success: true,
91
- errors: [],
92
- index_success_count: 0,
93
- };
94
-
95
- for (let i = 0; i < redirect_records.length; i++) {
96
- const index_vals = [
97
- redirect_records[i].url,
98
- redirect_records[i].location ? redirect_records[i].location : "",
99
- redirect_records[i].code,
100
- ];
101
- const index_response = hdoc_index.insert_record(
102
- db,
103
- "hdoc_redirects",
104
- db_schema.hdoc_redirects,
105
- index_vals,
106
- );
107
- if (!index_response.success) {
108
- response.success = false;
109
- response.errors.push(
110
- `Redirect record creation failed - ${redirect_records[i].url}: ${index_response.error}`,
111
- );
112
- } else {
113
- response.index_success_count++;
114
- }
115
- }
116
- console.log(
117
- `\nRedirect Index Build Complete: ${response.index_success_count} document records created.`,
118
- );
119
- return response;
120
- };
121
-
122
- exports.populate_index = async (
123
- db,
124
- doc_id,
125
- book_config,
126
- index_records,
127
- verbose = false,
128
- ) => {
129
- const response = {
130
- success: false,
131
- index_success_count: 0,
132
- error: "",
133
- };
134
-
135
- if (!book_config.tags) book_config.tags = [];
136
-
137
- const indexPromises = [];
138
- for (let i = 0; i < index_records.length; i++) {
139
- indexPromises.push(index_records[i]);
140
- }
141
- let curr_file = "";
142
- await Promise.all(
143
- indexPromises.map(async (file) => {
144
- let index_path_name = file.relative_path.replaceAll("\\", "/");
145
- if (
146
- index_path_name.endsWith("/index.md") ||
147
- index_path_name.endsWith("/index.html") ||
148
- index_path_name.endsWith("/index.htm")
149
- ) {
150
- index_path_name = index_path_name.substring(
151
- 0,
152
- index_path_name.lastIndexOf("/"),
153
- );
154
- }
155
- index_path_name = `/${index_path_name.replace(path.extname(file.relative_path), "")}`;
156
-
157
- let index_response = {
158
- success: true,
159
- row_id: 0,
160
- };
161
- let index_content_path = index_path_name;
162
- if (file.index_html.id !== null)
163
- index_content_path += `#${file.index_html.id}`;
164
- if (!file.inline) {
165
- const index_vals = [
166
- index_content_path,
167
- doc_id,
168
- book_config.audience.join(","),
169
- book_config.tags.join(","),
170
- file.index_html.fm_props.title,
171
- file.index_html.text,
172
- file.index_html.preview,
173
- book_config.productFamily,
174
- file.md5,
175
- file.lastmod,
176
- ];
177
- index_response = hdoc_index.insert_record(
178
- db,
179
- "hdoc_index",
180
- db_schema.hdoc_index,
181
- index_vals,
182
- );
183
- }
184
- if (!index_response.success) {
185
- console.error(
186
- `Index record creation failed - ${doc_id}/${file.index_html.fm_props.title}: ${index_response.error}`,
187
- );
188
- } else {
189
- if (curr_file === index_path_name) return;
190
- curr_file = index_path_name;
191
- // Now add metadata
192
- const meta_vals = [
193
- index_path_name,
194
- doc_id,
195
- file.metadata.contributor_count,
196
- file.metadata.edit_url,
197
- file.metadata.last_commit,
198
- file.pdf_size,
199
- ];
200
- const meta_response = await hdoc_index.insert_record(
201
- db,
202
- "hdoc_meta",
203
- db_schema.hdoc_meta,
204
- meta_vals,
205
- );
206
- if (!meta_response.success) {
207
- console.error(
208
- `Index metadata record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${meta_response.error}`,
209
- );
210
- } else {
211
- if (verbose) {
212
- console.log(
213
- `Inserted index record ${index_response.row_id}: ${doc_id} - ${file.index_html.fm_props.title}`,
214
- );
215
- console.log(
216
- `Inserted index metadata record for index ID: ${meta_response.row_id}`,
217
- );
218
- }
219
-
220
- // Now add contributor records
221
- for (let j = 0; j < file.contributors.length; j++) {
222
- const contrib_vals = [
223
- index_path_name,
224
- doc_id,
225
- file.contributors[j].login,
226
- file.contributors[j].name,
227
- file.contributors[j].avatar_url,
228
- file.contributors[j].html_url,
229
- ];
230
- const cont_response = await hdoc_index.insert_record(
231
- db,
232
- "hdoc_contributors",
233
- db_schema.hdoc_contributors,
234
- contrib_vals,
235
- );
236
- if (!cont_response.success) {
237
- console.error(
238
- `Index document contributor record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${cont_response.error}`,
239
- );
240
- continue;
241
- }
242
- if (verbose) {
243
- console.log(
244
- `Inserted document contributor record ${cont_response.row_id}`,
245
- );
246
- }
247
- }
248
- response.index_success_count++;
249
- }
250
- }
251
- }),
252
- );
253
-
254
- response.success = true;
255
- console.log(
256
- `\nIndex Build Complete: ${response.index_success_count} document index records created.`,
257
- );
258
- return response;
259
- };
260
- })();
1
+ (() => {
2
+ const path = require("node:path");
3
+ const hdoc_index = require(path.join(__dirname, "hdoc-db.js"));
4
+ const database = require("better-sqlite3");
5
+
6
+ const db_schema = {
7
+ hdoc_index: [
8
+ "resource_url UNINDEXED",
9
+ "book_id",
10
+ "book_audience UNINDEXED",
11
+ "book_tags",
12
+ "doc_title",
13
+ "doc_content",
14
+ "doc_preview UNINDEXED",
15
+ "doc_family_id",
16
+ "doc_md5_hash UNINDEXED",
17
+ "doc_lastmod",
18
+ "doc_status",
19
+ ],
20
+ hdoc_meta: [
21
+ "resource_url",
22
+ "book_id",
23
+ "contributor_count INTEGER UNINDEXED",
24
+ "edit_url UNINDEXED",
25
+ "last_commit UNINDEXED",
26
+ "pdf_size INTEGER UNINDEXED",
27
+ ],
28
+ hdoc_contributors: [
29
+ "resource_url",
30
+ "book_id",
31
+ "login",
32
+ "name",
33
+ "avatar UNINDEXED",
34
+ "url UNINDEXED",
35
+ ],
36
+ hdoc_redirects: [
37
+ "resource_url",
38
+ "location_url",
39
+ "http_code INTEGER UNINDEXED",
40
+ ],
41
+ };
42
+
43
+ exports.create_table = (db, table, cols, virtual, fts5) => {
44
+ const table_created = hdoc_index.create_table(
45
+ db,
46
+ table,
47
+ cols,
48
+ virtual,
49
+ fts5,
50
+ );
51
+ if (table_created !== null) {
52
+ return `\nError creating table: ${table_created}`;
53
+ }
54
+ console.log(`\nTable created: ${table}`);
55
+ return null;
56
+ };
57
+
58
+ exports.create_db = function (db_path, doc_id) {
59
+ const response = {
60
+ error: null,
61
+ db: null,
62
+ };
63
+ console.log("\nPerforming SQlite index creation...");
64
+ const db_name = path.join(db_path, doc_id, "index.db");
65
+ response.db = new database(db_name);
66
+ response.db.pragma('encoding="UTF-8"');
67
+ console.log(`\nDatabase created: ${db_name}`);
68
+
69
+ // Create tables
70
+ for (const key in db_schema) {
71
+ if (Object.hasOwn(db_schema, key)) {
72
+ const virtual = key === "hdoc_index";
73
+ const fts5 = key === "hdoc_index";
74
+ const table_created_error = this.create_table(
75
+ response.db,
76
+ key,
77
+ db_schema[key],
78
+ virtual,
79
+ fts5,
80
+ );
81
+ if (table_created_error !== null) {
82
+ console.error(table_created_error);
83
+ }
84
+ }
85
+ }
86
+ return response;
87
+ };
88
+
89
+ exports.populate_redirects = (db, redirect_records, verbose = false) => {
90
+ const response = {
91
+ success: true,
92
+ errors: [],
93
+ index_success_count: 0,
94
+ };
95
+
96
+ for (let i = 0; i < redirect_records.length; i++) {
97
+ const index_vals = [
98
+ redirect_records[i].url,
99
+ redirect_records[i].location ? redirect_records[i].location : "",
100
+ redirect_records[i].code,
101
+ ];
102
+ const index_response = hdoc_index.insert_record(
103
+ db,
104
+ "hdoc_redirects",
105
+ db_schema.hdoc_redirects,
106
+ index_vals,
107
+ );
108
+ if (!index_response.success) {
109
+ response.success = false;
110
+ response.errors.push(
111
+ `Redirect record creation failed - ${redirect_records[i].url}: ${index_response.error}`,
112
+ );
113
+ } else {
114
+ response.index_success_count++;
115
+ }
116
+ }
117
+ console.log(
118
+ `\nRedirect Index Build Complete: ${response.index_success_count} document records created.`,
119
+ );
120
+ return response;
121
+ };
122
+
123
+ exports.populate_index = async (
124
+ db,
125
+ doc_id,
126
+ book_config,
127
+ index_records,
128
+ verbose = false,
129
+ ) => {
130
+ const response = {
131
+ success: false,
132
+ index_success_count: 0,
133
+ error: "",
134
+ };
135
+
136
+ if (!book_config.tags) book_config.tags = [];
137
+
138
+ const indexPromises = [];
139
+ for (let i = 0; i < index_records.length; i++) {
140
+ indexPromises.push(index_records[i]);
141
+ }
142
+ let curr_file = "";
143
+ await Promise.all(
144
+ indexPromises.map(async (file) => {
145
+ let index_path_name = file.relative_path.replaceAll("\\", "/");
146
+ if (
147
+ index_path_name.endsWith("/index.md") ||
148
+ index_path_name.endsWith("/index.html") ||
149
+ index_path_name.endsWith("/index.htm")
150
+ ) {
151
+ index_path_name = index_path_name.substring(
152
+ 0,
153
+ index_path_name.lastIndexOf("/"),
154
+ );
155
+ }
156
+ index_path_name = `/${index_path_name.replace(path.extname(file.relative_path), "")}`;
157
+
158
+ let index_response = {
159
+ success: true,
160
+ row_id: 0,
161
+ };
162
+ let index_content_path = index_path_name;
163
+ if (file.index_html.id !== null)
164
+ index_content_path += `#${file.index_html.id}`;
165
+ if (!file.inline) {
166
+ const index_vals = [
167
+ index_content_path,
168
+ doc_id,
169
+ book_config.audience.join(","),
170
+ book_config.tags.join(","),
171
+ file.index_html.fm_props.title,
172
+ file.index_html.text,
173
+ file.index_html.preview,
174
+ book_config.productFamily,
175
+ file.md5,
176
+ file.lastmod,
177
+ file.status,
178
+ ];
179
+ index_response = hdoc_index.insert_record(
180
+ db,
181
+ "hdoc_index",
182
+ db_schema.hdoc_index,
183
+ index_vals,
184
+ );
185
+ }
186
+ if (!index_response.success) {
187
+ console.error(
188
+ `Index record creation failed - ${doc_id}/${file.index_html.fm_props.title}: ${index_response.error}`,
189
+ );
190
+ } else {
191
+ if (curr_file === index_path_name) return;
192
+ curr_file = index_path_name;
193
+ // Now add metadata
194
+ const meta_vals = [
195
+ index_path_name,
196
+ doc_id,
197
+ file.metadata.contributor_count,
198
+ file.metadata.edit_url,
199
+ file.metadata.last_commit,
200
+ file.pdf_size,
201
+ ];
202
+ const meta_response = await hdoc_index.insert_record(
203
+ db,
204
+ "hdoc_meta",
205
+ db_schema.hdoc_meta,
206
+ meta_vals,
207
+ );
208
+ if (!meta_response.success) {
209
+ console.error(
210
+ `Index metadata record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${meta_response.error}`,
211
+ );
212
+ } else {
213
+ if (verbose) {
214
+ console.log(
215
+ `Inserted index record ${index_response.row_id}: ${doc_id} - ${file.index_html.fm_props.title}`,
216
+ );
217
+ console.log(
218
+ `Inserted index metadata record for index ID: ${meta_response.row_id}`,
219
+ );
220
+ }
221
+
222
+ // Now add contributor records
223
+ for (let j = 0; j < file.contributors.length; j++) {
224
+ const contrib_vals = [
225
+ index_path_name,
226
+ doc_id,
227
+ file.contributors[j].login,
228
+ file.contributors[j].name,
229
+ file.contributors[j].avatar_url,
230
+ file.contributors[j].html_url,
231
+ ];
232
+ const cont_response = await hdoc_index.insert_record(
233
+ db,
234
+ "hdoc_contributors",
235
+ db_schema.hdoc_contributors,
236
+ contrib_vals,
237
+ );
238
+ if (!cont_response.success) {
239
+ console.error(
240
+ `Index document contributor record creation failed - ${doc_id}/${index_response.row_id}/${file.index_html.fm_props.title}: ${cont_response.error}`,
241
+ );
242
+ continue;
243
+ }
244
+ if (verbose) {
245
+ console.log(
246
+ `Inserted document contributor record ${cont_response.row_id}`,
247
+ );
248
+ }
249
+ }
250
+ response.index_success_count++;
251
+ }
252
+ }
253
+ }),
254
+ );
255
+
256
+ response.success = true;
257
+ console.log(
258
+ `\nIndex Build Complete: ${response.index_success_count} document index records created.`,
259
+ );
260
+ return response;
261
+ };
262
+ })();
package/hdoc-build.js CHANGED
@@ -5,7 +5,6 @@
5
5
  const mdfm = require("markdown-it-front-matter");
6
6
  const path = require("node:path");
7
7
  const puppeteer = require("puppeteer");
8
- const URL = require("node:url").URL;
9
8
  const hdoc_validate = require(path.join(__dirname, "hdoc-validate.js"));
10
9
  const hdoc = require(path.join(__dirname, "hdoc-module.js"));
11
10
  const hdoc_build_db = require(path.join(__dirname, "hdoc-build-db.js"));
@@ -46,7 +45,6 @@
46
45
  const built_file_hashes = [];
47
46
  const css_templates = [];
48
47
  const draft_links = [];
49
- const draft_files_removed = [];
50
48
  const errors_filename = [];
51
49
  const index_records = [];
52
50
  const md_files = [];
@@ -121,9 +119,18 @@
121
119
 
122
120
  // Check if we have a frontmatter comment
123
121
  const fm_header = hdoc.getHTMLFrontmatterHeader(html_txt);
122
+
123
+ let rel_path = file_path.relativePath.replace(path.extname(file_path.relativePath), '');
124
+ if (rel_path.endsWith('/index')) rel_path = rel_path.substring(0, rel_path.length - 6);
125
+ const is_draft = draft_links.indexOf(rel_path) !== -1;
126
+
127
+ let fm_status = false;
124
128
  if (Object.keys(fm_header.fm_properties).length > 0) {
125
129
  existing_fm_headers = true;
126
130
 
131
+ if (fm_header.fm_properties?.status) {
132
+ fm_status = true;
133
+ }
127
134
  // We have some frontmatter headers, check if title is one of them
128
135
  let fm_title_found = false;
129
136
  if (
@@ -270,6 +277,14 @@
270
277
  value: doc_type,
271
278
  });
272
279
 
280
+ // Add status if we don't have one defined and the nav tree defines the document as draft
281
+ if (!fm_status && is_draft) {
282
+ fm_headers.push({
283
+ id: "status",
284
+ value: "draft"
285
+ });
286
+ }
287
+
273
288
  const metadata = {};
274
289
 
275
290
  // Remove the first <h1>title</h1> from the HTML as we'll add that in the document header
@@ -445,6 +460,7 @@
445
460
  md5: file_path.hash,
446
461
  lastmod: last_commit !== null ? last_commit : file_path.hb_lastmod,
447
462
  inline: inline_content,
463
+ status: index_data.fm_props.status ? index_data.fm_props.status : 'release',
448
464
  });
449
465
  }
450
466
 
@@ -508,7 +524,6 @@
508
524
  });
509
525
 
510
526
  // Tidy up ```json and ```xml code tags
511
-
512
527
  if (md_txt.includes("```json") || md_txt.includes("```xml"))
513
528
  md_txt = tidy_code_tags(md_txt, file_path.relativePath);
514
529
 
@@ -525,6 +540,11 @@
525
540
  let doc_title = "";
526
541
  let doc_type = "Article";
527
542
 
543
+ let rel_path = file_path.relativePath.replace(path.extname(file_path.relativePath), '');
544
+ if (rel_path.endsWith('/index')) rel_path = rel_path.substring(0, rel_path.length - 6);
545
+ const is_draft = draft_links.indexOf(rel_path) !== -1;
546
+ let fm_status = false;
547
+
528
548
  if (fm_content.length >= 0) {
529
549
  for (fm_prop of fm_content) {
530
550
  const fm_id = fm_prop.slice(0, fm_prop.indexOf(":"));
@@ -545,6 +565,9 @@
545
565
  fm_contains_title = true;
546
566
  doc_title = fm_val.trim();
547
567
  }
568
+ if (fm_id.trim() === "status") {
569
+ fm_status = true;
570
+ }
548
571
  if (fm_id.trim() === "type") {
549
572
  doc_type = fm_val.trim();
550
573
  }
@@ -565,6 +588,14 @@
565
588
  value: doc_type,
566
589
  });
567
590
 
591
+ // Add status if we don't have one defined and the nav tree defines the document as draft
592
+ if (!fm_status && is_draft) {
593
+ fm_headers.push({
594
+ id: "status",
595
+ value: "draft"
596
+ });
597
+ }
598
+
568
599
  // Does frontmatter tag contain a title property
569
600
  if (!fm_contains_title) {
570
601
  // Frontmatter tags don't contain a title property - go pull the first one from the html heading tags
@@ -793,7 +824,6 @@
793
824
  }
794
825
 
795
826
  const index_data = hdoc_index.transform_html_for_index(html_txt);
796
-
797
827
  for (section of index_data.sections) {
798
828
  index_records.push({
799
829
  relative_path: relative_path,
@@ -809,6 +839,7 @@
809
839
  md5: file_path.hash,
810
840
  lastmod: last_commit !== null ? last_commit : file_path.hb_lastmod,
811
841
  inline: inline_content,
842
+ status: index_data.fm_props.status ? index_data.fm_props.status : 'release',
812
843
  });
813
844
  }
814
845
 
@@ -973,15 +1004,6 @@
973
1004
 
974
1005
  // File callback for build scan
975
1006
  const build_file_callback = (element) => {
976
- let rel_path = element.relativePath.replace(path.extname(element.relativePath), '');
977
- if (rel_path.endsWith('/index')) rel_path = rel_path.substring(0, rel_path.length - 6);
978
-
979
- if (draft_links.indexOf(rel_path) !== -1) {
980
- draft_files_removed.push(element.relativePath);
981
- fs.rmSync(element.path);
982
- return;
983
- }
984
-
985
1007
  if (element.extension === "md") {
986
1008
  element.hb_source_path = path.join(
987
1009
  global_source_path,
@@ -1343,7 +1365,6 @@
1343
1365
 
1344
1366
  // Output to console
1345
1367
  console.log(`\n MD files found: ${conversion_attempted}`);
1346
- console.log(` Draft Files Excluded: ${draft_files_removed.length}`);
1347
1368
  console.log(`Successfully converted to HTML: ${conversion_success}`);
1348
1369
  if (conversion_failed > 0)
1349
1370
  console.error(` Failed to convert: ${conversion_failed}\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {