hdoc-tools 0.8.7 → 0.8.9
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.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
const {
|
|
2
|
-
stat
|
|
3
|
-
} = require('fs');
|
|
4
|
-
|
|
5
1
|
(function () {
|
|
6
2
|
'use strict';
|
|
7
3
|
|
|
8
|
-
const
|
|
4
|
+
const {
|
|
5
|
+
createHash
|
|
6
|
+
} = require('crypto'),
|
|
7
|
+
dree = require('dree'),
|
|
9
8
|
fs = require('fs-extra'),
|
|
10
9
|
mdfm = require('markdown-it-front-matter'),
|
|
11
10
|
path = require('path'),
|
|
@@ -18,13 +17,14 @@ const {
|
|
|
18
17
|
|
|
19
18
|
const h_tags_to_search = ['h1', 'h2', 'h3'],
|
|
20
19
|
index_cols = [
|
|
21
|
-
'relative_url',
|
|
20
|
+
'relative_url UNINDEXED',
|
|
22
21
|
'book_id',
|
|
23
|
-
'book_audience',
|
|
22
|
+
'book_audience UNINDEXED',
|
|
24
23
|
'book_tags',
|
|
25
24
|
'doc_title',
|
|
26
25
|
'doc_content',
|
|
27
|
-
'doc_preview'
|
|
26
|
+
'doc_preview UNINDEXED',
|
|
27
|
+
'doc_family_id'
|
|
28
28
|
];
|
|
29
29
|
|
|
30
30
|
let conversion_attempted = 0,
|
|
@@ -37,7 +37,10 @@ const {
|
|
|
37
37
|
docId = '',
|
|
38
38
|
md_files = [],
|
|
39
39
|
static_html_files = [],
|
|
40
|
-
index_records = []
|
|
40
|
+
index_records = [],
|
|
41
|
+
work_path_content = '',
|
|
42
|
+
built_relative_paths = [],
|
|
43
|
+
built_file_hashes = [];
|
|
41
44
|
|
|
42
45
|
const transform_static_html = function (file_path) {
|
|
43
46
|
if (fs.existsSync(file_path.path)) {
|
|
@@ -98,7 +101,10 @@ const {
|
|
|
98
101
|
console.log(`No frontmatter title property, or ${h_tags_to_search.join(', ')} tags detected in ${file_path.path}`);
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
|
-
index_records.push({
|
|
104
|
+
index_records.push({
|
|
105
|
+
relative_path: file_path.relativePath,
|
|
106
|
+
index_html: hdoc_index.transform_html_for_index(html_txt)
|
|
107
|
+
});
|
|
102
108
|
if (html_txt_updated) {
|
|
103
109
|
// Save HTML into HTML file
|
|
104
110
|
fs.writeFile(file_path.path, html_txt, function writeJSON(err) {
|
|
@@ -184,10 +190,13 @@ const {
|
|
|
184
190
|
fs.writeFile(target_file, html_txt, function writeJSON(err) {
|
|
185
191
|
if (err) return console.log('Error writing:', target_file, '\r\n', err);
|
|
186
192
|
});
|
|
187
|
-
|
|
188
|
-
const index_details =
|
|
189
|
-
|
|
190
|
-
index_records.push({
|
|
193
|
+
|
|
194
|
+
const index_details = hdoc_index.transform_html_for_index(html_txt);
|
|
195
|
+
|
|
196
|
+
index_records.push({
|
|
197
|
+
relative_path: relative_path,
|
|
198
|
+
index_html: index_details
|
|
199
|
+
});
|
|
191
200
|
|
|
192
201
|
// Delete MD file from _work path
|
|
193
202
|
try {
|
|
@@ -203,8 +212,8 @@ const {
|
|
|
203
212
|
return false;
|
|
204
213
|
};
|
|
205
214
|
|
|
206
|
-
// File
|
|
207
|
-
const
|
|
215
|
+
// File callback for build scan
|
|
216
|
+
const build_file_callback = function (element) {
|
|
208
217
|
if (element.extension === 'md') {
|
|
209
218
|
md_files.push(element);
|
|
210
219
|
} else {
|
|
@@ -221,16 +230,28 @@ const {
|
|
|
221
230
|
}
|
|
222
231
|
};
|
|
223
232
|
|
|
233
|
+
// File & folder callback for MD5 hash of built content
|
|
234
|
+
const hash_callback = function (element) {
|
|
235
|
+
if (element.extension !== 'db') {
|
|
236
|
+
built_file_hashes.push({
|
|
237
|
+
path: element.relativePath,
|
|
238
|
+
hash: element.hash
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
224
243
|
const dreeOptions = {
|
|
225
|
-
descendants: true,
|
|
226
|
-
depth: 10,
|
|
227
244
|
extensions: ['md', 'html', 'htm'],
|
|
228
|
-
hash: false,
|
|
229
245
|
normalize: true,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const md5DreeOptions = {
|
|
249
|
+
hash: true,
|
|
250
|
+
hashAlgorithm: 'md5',
|
|
251
|
+
hashEncoding: 'hex',
|
|
252
|
+
normalize: true,
|
|
253
|
+
size: true,
|
|
254
|
+
sorted: true
|
|
234
255
|
};
|
|
235
256
|
|
|
236
257
|
exports.run = function (source_path, verbose) {
|
|
@@ -261,7 +282,7 @@ const {
|
|
|
261
282
|
console.log(`Building: ${docId} v${hdocbook_config.version}...\r\n`);
|
|
262
283
|
|
|
263
284
|
const work_path = path.join(source_path, '_work');
|
|
264
|
-
|
|
285
|
+
work_path_content = path.join(work_path, docId);
|
|
265
286
|
// Make _work folder to copy everything into
|
|
266
287
|
if (fs.existsSync(work_path)) {
|
|
267
288
|
fs.rmSync(work_path, {
|
|
@@ -273,14 +294,14 @@ const {
|
|
|
273
294
|
|
|
274
295
|
// Copy files from book into _work-docId folder
|
|
275
296
|
try {
|
|
276
|
-
fs.copySync(path.join(source_path, docId),
|
|
297
|
+
fs.copySync(path.join(source_path, docId), work_path_content);
|
|
277
298
|
} catch (e) {
|
|
278
299
|
console.error('Error copying from source_path:\r\n', e);
|
|
279
300
|
process.exit(1);
|
|
280
301
|
}
|
|
281
302
|
|
|
282
303
|
// Get a list of MD files in work_path
|
|
283
|
-
dree.scan(work_path, dreeOptions,
|
|
304
|
+
dree.scan(work_path, dreeOptions, build_file_callback);
|
|
284
305
|
|
|
285
306
|
// Work through MD files and convert to HTML
|
|
286
307
|
md_files.forEach(function (md_file) {
|
|
@@ -336,6 +357,7 @@ const {
|
|
|
336
357
|
index_records[i].index_html.fm_props.title,
|
|
337
358
|
index_records[i].index_html.text,
|
|
338
359
|
index_records[i].index_html.preview,
|
|
360
|
+
hdocbook_config.productFamily
|
|
339
361
|
];
|
|
340
362
|
const index_response = hdoc_index.insert_record(db, table_name, index_cols, index_vals, hdocbook_config.docId, index_records[i].index_html.fm_props.title);
|
|
341
363
|
if (!index_response.success) {
|
|
@@ -350,9 +372,31 @@ const {
|
|
|
350
372
|
console.log(`\nIndex Build Complete: ${index_success_count} records created.`);
|
|
351
373
|
}
|
|
352
374
|
|
|
375
|
+
// Now create MD5 hash of built content
|
|
376
|
+
dree.scan(work_path_content, md5DreeOptions, hash_callback);
|
|
377
|
+
let concat_hash = '|';
|
|
378
|
+
for (let i = 0; i < built_file_hashes.length; i++) {
|
|
379
|
+
concat_hash += built_file_hashes[i].path + ':' + built_file_hashes[i].hash + '|';
|
|
380
|
+
}
|
|
381
|
+
if (concat_hash === '|') {
|
|
382
|
+
console.log('No hash of content has been returned.');
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const hash = createHash("md5").update(concat_hash).digest("hex");
|
|
387
|
+
const checksum_path = path.join(work_path_content, 'checksum.md5');
|
|
388
|
+
try {
|
|
389
|
+
fs.writeFileSync(checksum_path, hash);
|
|
390
|
+
console.log('\nHash file creation success:', checksum_path);
|
|
391
|
+
} catch (e) {
|
|
392
|
+
console.log('\nError creating', checksum_path, ':', e);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
|
|
353
397
|
try {
|
|
354
398
|
const zip_path = path.join(work_path, docId + '.zip');
|
|
355
|
-
zipper.sync.zip(
|
|
399
|
+
zipper.sync.zip(work_path_content).compress().save(zip_path);
|
|
356
400
|
console.log(`\nZIP Creation Success: ${zip_path}\n`);
|
|
357
401
|
console.log('Build Complete\n');
|
|
358
402
|
} catch (e) {
|
package/hdoc-db.js
CHANGED
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
let vals = 'VALUES (';
|
|
34
34
|
for (let i = 0; i < columns.length; i++) {
|
|
35
35
|
if (i === 0) {
|
|
36
|
-
cols += `${columns[i]}`;
|
|
36
|
+
cols += `${columns[i].replace('UNINDEXED', '').trim()}`;
|
|
37
37
|
vals += '?';
|
|
38
38
|
} else {
|
|
39
|
-
cols += `,${columns[i]}`;
|
|
39
|
+
cols += `,${columns[i].replace('UNINDEXED', '').trim()}`;
|
|
40
40
|
vals += ',?';
|
|
41
41
|
}
|
|
42
42
|
}
|
package/hdoc-init.js
CHANGED
|
@@ -71,9 +71,6 @@
|
|
|
71
71
|
process.exit(1);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// The file update tasks can now all be done async now
|
|
75
|
-
// we have the file and folder structure in place
|
|
76
|
-
|
|
77
74
|
// Update hdocbook-project.json
|
|
78
75
|
const hdocBookProjectFilePath = path.join(source_path, 'hdocbook-project.json');
|
|
79
76
|
const hdocBookProjectFile = require(hdocBookProjectFilePath);
|
package/package.json
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
"title": "--title--",
|
|
4
4
|
"description": "--description--",
|
|
5
5
|
"publicSource": "--publicSource--",
|
|
6
|
+
"productFamily": "docs",
|
|
6
7
|
"version": "0.0.1",
|
|
8
|
+
"audience": [
|
|
9
|
+
"public"
|
|
10
|
+
],
|
|
11
|
+
"languages": [
|
|
12
|
+
"en"
|
|
13
|
+
],
|
|
7
14
|
"navigation": {
|
|
8
15
|
"items": [
|
|
9
16
|
{
|
|
@@ -11,5 +18,6 @@
|
|
|
11
18
|
"expand": true
|
|
12
19
|
}
|
|
13
20
|
]
|
|
14
|
-
}
|
|
21
|
+
},
|
|
22
|
+
"tags": []
|
|
15
23
|
}
|
|
@@ -34,6 +34,36 @@
|
|
|
34
34
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/* nav tabs in doc content */
|
|
38
|
+
.DocContent .nav-tabs
|
|
39
|
+
{
|
|
40
|
+
padding-left: 0!important;
|
|
41
|
+
list-style: none!important;
|
|
42
|
+
}
|
|
43
|
+
.DocContent .nav-tabs li
|
|
44
|
+
{
|
|
45
|
+
margin-top: 0px !important
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
.DocContent .nav-tabs.codeblock
|
|
50
|
+
{
|
|
51
|
+
border-bottom: 1px solid #1E1E1E;
|
|
52
|
+
margin-bottom: 0px
|
|
53
|
+
}
|
|
54
|
+
.DocContent .nav-tabs.codeblock .nav-link.active
|
|
55
|
+
{
|
|
56
|
+
background-color: #1E1E1E;
|
|
57
|
+
color: #fff;
|
|
58
|
+
border-color: #1E1E1E;
|
|
59
|
+
}
|
|
60
|
+
.DocContent .nav-tabs.codeblock .nav-link:hover
|
|
61
|
+
{
|
|
62
|
+
border-bottom-color: #1E1E1E;
|
|
63
|
+
}
|
|
64
|
+
/* eof nav tabs in doc content */
|
|
65
|
+
|
|
66
|
+
|
|
37
67
|
|
|
38
68
|
|
|
39
69
|
@media (min-width: 1000px) {
|
|
@@ -68,13 +98,13 @@
|
|
|
68
98
|
/* LAYOUT MODS */
|
|
69
99
|
|
|
70
100
|
/* table-list*/
|
|
71
|
-
.DocContent.
|
|
101
|
+
.DocContent.article-wide .injected-document-content
|
|
72
102
|
{
|
|
73
103
|
/* take up max width - overrides max-width set in [.DocContent .injected-document-content] */
|
|
74
104
|
max-width:100%;
|
|
75
105
|
}
|
|
76
106
|
|
|
77
|
-
.DocContent.
|
|
107
|
+
.DocContent.article-wide .injected-document-content table
|
|
78
108
|
{
|
|
79
109
|
/* make all tables 100% */
|
|
80
110
|
width:100%;
|
package/ui/js/doc.hornbill.js
CHANGED
|
@@ -267,6 +267,44 @@ function loadContentUrl(linkRef,fromPageRefresh,fromPopState)
|
|
|
267
267
|
generateTableOfContentsFromDoc();
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
//-- find any <tabs> and andd a bootstrap tab item strip
|
|
271
|
+
$("#DocContent").find('tabs').each((idx,el) => {
|
|
272
|
+
let tabClass = el.getAttribute("tabstyle");
|
|
273
|
+
let tabMarkup = "<ul class='nav nav-tabs'>";
|
|
274
|
+
//-- for each tab we need to create a tab link
|
|
275
|
+
$(el).find("tab").each((idx,aTab) => {
|
|
276
|
+
|
|
277
|
+
let activeClass=(idx===0)?" active":"";
|
|
278
|
+
tabMarkup += `<li class='nav-item c-pointer' contentidx='${idx}'><span class='nav-link${activeClass}'>${aTab.getAttribute("name")}</span></li>`;
|
|
279
|
+
|
|
280
|
+
//-- hide the tab element if it is not the active one (first)
|
|
281
|
+
if(idx>0)$(aTab).addClass("d-none");
|
|
282
|
+
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
tabMarkup += "</ul>";
|
|
286
|
+
//-- inject markup
|
|
287
|
+
$(el).prepend(tabMarkup).find(".nav.nav-tabs").addClass(tabClass);
|
|
288
|
+
|
|
289
|
+
//-- add event handler for switching tab items
|
|
290
|
+
$(el).find("li").off("click").on("click",function()
|
|
291
|
+
{
|
|
292
|
+
let contentIdx = this.getAttribute('contentidx');
|
|
293
|
+
let tabsContainer = $(this).closest("tabs").eq(0);
|
|
294
|
+
let tabs= tabsContainer.find("tab");
|
|
295
|
+
|
|
296
|
+
//-- hide other tab content and show this tabs content
|
|
297
|
+
tabs.addClass("d-none");
|
|
298
|
+
tabs.eq(contentIdx-0).removeClass("d-none");
|
|
299
|
+
|
|
300
|
+
//-- set clicked tab item to active
|
|
301
|
+
tabsContainer.find(".nav-link").removeClass("active");
|
|
302
|
+
$(this).find(".nav-link").addClass("active");
|
|
303
|
+
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
|
|
270
308
|
//-- do any code highlighting
|
|
271
309
|
document.querySelectorAll('pre code').forEach((el) => {
|
|
272
310
|
hljs.highlightBlock(el);
|