hdoc-tools 0.60.0 → 0.61.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/editor/dist/assets/index-Blewr90z.css +1 -1
- package/editor/dist/assets/index-BtxvGZHW.js +111 -111
- package/editor/dist/assets/spell.worker-sryEKmOj.js +13 -13
- package/editor/dist/index.html +14 -14
- package/hdoc-build.js +14 -6
- package/hdoc-bump.js +125 -123
- package/hdoc-content-routes.js +143 -83
- package/hdoc-create.js +4 -2
- package/hdoc-init.js +103 -68
- package/hdoc-module.js +35 -12
- package/hdoc-serve.js +13 -7
- package/hdoc-stats.js +9 -9
- package/hdoc-validate-config.js +26 -0
- package/hdoc-validate-interbook.js +321 -0
- package/hdoc-validate.js +82 -7
- package/hdoc-ver.js +45 -43
- package/hdoc.js +12 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/schemas/hdocbook-project.schema.json +20 -0
- package/schemas/hdocbook.schema.json +6 -2
- package/ui/js/doc.hornbill.js +31 -44
- package/ui/js/mermaid-theme.json +27 -0
- package/hdoc-build-onyx.js +0 -134
- package/templates/mermaid-theme.yaml +0 -28
- package/templates/pdf/fonts/inter-cyrillic copy.woff2 +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hdoc-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0",
|
|
4
4
|
"description": "Hornbill HDocBook Development Support Tool",
|
|
5
5
|
"main": "hdoc.js",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"hdoc-build.js",
|
|
13
13
|
"hdoc-build-db.js",
|
|
14
14
|
"hdoc-build-embeddings.js",
|
|
15
|
-
"hdoc-build-onyx.js",
|
|
16
15
|
"hdoc-build-pdf.js",
|
|
17
16
|
"hdoc-bump.js",
|
|
18
17
|
"hdoc-content-routes.js",
|
|
@@ -29,6 +28,7 @@
|
|
|
29
28
|
"hdoc-toc.js",
|
|
30
29
|
"hdoc-validate.js",
|
|
31
30
|
"hdoc-validate-config.js",
|
|
31
|
+
"hdoc-validate-interbook.js",
|
|
32
32
|
"hdoc-ver.js",
|
|
33
33
|
"validateNodeVer.js",
|
|
34
34
|
".puppeteerrc.cjs",
|
|
@@ -67,6 +67,26 @@
|
|
|
67
67
|
"external_link_warnings": {
|
|
68
68
|
"type": "boolean",
|
|
69
69
|
"description": "When true, external link failures are reported as warnings rather than errors."
|
|
70
|
+
},
|
|
71
|
+
"spellcheckDictionary": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"description": "Words to exclude from the British English spellcheck across all documents in the book.",
|
|
74
|
+
"items": { "type": "string" }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"ai": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"description": "Configuration for the hdoc edit AI assist feature.",
|
|
81
|
+
"additionalProperties": false,
|
|
82
|
+
"properties": {
|
|
83
|
+
"model": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Anthropic model ID used by the hdoc edit AI assist feature."
|
|
86
|
+
},
|
|
87
|
+
"maxTokens": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"description": "Maximum response tokens for AI assist requests."
|
|
70
90
|
}
|
|
71
91
|
}
|
|
72
92
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"title": "HDocBook Configuration",
|
|
5
5
|
"description": "Schema for hdocbook.json - book metadata, navigation, and publishing configuration",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["docId", "title", "
|
|
7
|
+
"required": ["docId", "title", "version", "productFamily", "audience", "navigation"],
|
|
8
8
|
"additionalProperties": false,
|
|
9
9
|
"properties": {
|
|
10
10
|
"docId": {
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"properties": {
|
|
99
99
|
"items": {
|
|
100
100
|
"type": "array",
|
|
101
|
-
"description": "Top-level navigation items. Maximum
|
|
101
|
+
"description": "Top-level navigation items. Maximum five levels of nesting are supported.",
|
|
102
102
|
"minItems": 1,
|
|
103
103
|
"items": { "$ref": "#/$defs/navigationItem" }
|
|
104
104
|
}
|
|
@@ -128,6 +128,10 @@
|
|
|
128
128
|
"type": "string",
|
|
129
129
|
"description": "Display text for the navigation item."
|
|
130
130
|
},
|
|
131
|
+
"id": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"description": "Opaque node identifier written by the hdoc edit navigation editor. Optional."
|
|
134
|
+
},
|
|
131
135
|
"link": {
|
|
132
136
|
"type": "string",
|
|
133
137
|
"description": "Path to the content page. Ignored when 'items' is present."
|
package/ui/js/doc.hornbill.js
CHANGED
|
@@ -7,36 +7,14 @@ let jqDocumentHeader = null;
|
|
|
7
7
|
let jqLeftNav = null;
|
|
8
8
|
const global = { stateParams: {}, lastLayoutClass: "" };
|
|
9
9
|
|
|
10
|
-
//-- Mermaid
|
|
11
|
-
//--
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
theme
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
primaryColor: "#85D2FF",
|
|
19
|
-
primaryColorLight: "#85D2FF",
|
|
20
|
-
primaryColorDark: "#0065CB",
|
|
21
|
-
secondaryColor: "#219BFF",
|
|
22
|
-
secondaryColorLight: "#85D2FF",
|
|
23
|
-
secondaryColorDark: "#0C4C8C",
|
|
24
|
-
tertiaryColor: "#219BFF",
|
|
25
|
-
tertiaryColorLight: "#85D2FF",
|
|
26
|
-
tertiaryColorDark: "#0C4C8C",
|
|
27
|
-
lineColor: "#808080",
|
|
28
|
-
border1: "#606060",
|
|
29
|
-
textColor: "#A0A0A0",
|
|
30
|
-
titleColor: "#A0A0A0",
|
|
31
|
-
labelColor: "#404040",
|
|
32
|
-
loopTextColor: "#A0A0A0",
|
|
33
|
-
nodeTextColor: "#404040",
|
|
34
|
-
labelTextColor: "#404040",
|
|
35
|
-
pieSectionTextColor: "#404040",
|
|
36
|
-
nodeBorder: "#219BFF",
|
|
37
|
-
nodeBg: "transparent",
|
|
38
|
-
},
|
|
39
|
-
};
|
|
10
|
+
//-- Mermaid theme lives in js/mermaid-theme.json — the SINGLE source shared
|
|
11
|
+
//-- with the server-side PDF SVG bake (hdoc build reads the same file). Fetch
|
|
12
|
+
//-- failure falls back to the plain base theme rather than blocking rendering.
|
|
13
|
+
function hbFetchMermaidTheme() {
|
|
14
|
+
return fetch("js/mermaid-theme.json") //-- resolves against <base href>
|
|
15
|
+
.then((r) => (r.ok ? r.json() : null))
|
|
16
|
+
.catch(() => null);
|
|
17
|
+
}
|
|
40
18
|
|
|
41
19
|
//-- Lazy-load the Mermaid bundle (~3MB) only when a page actually contains a
|
|
42
20
|
//-- diagram. Resolves to window.mermaid, initialised once.
|
|
@@ -44,20 +22,29 @@ let hbMermaidLoadPromise = null;
|
|
|
44
22
|
function hbLoadMermaid() {
|
|
45
23
|
if (window.mermaid) return Promise.resolve(window.mermaid);
|
|
46
24
|
if (hbMermaidLoadPromise) return hbMermaidLoadPromise;
|
|
47
|
-
hbMermaidLoadPromise =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
25
|
+
hbMermaidLoadPromise = hbFetchMermaidTheme().then(
|
|
26
|
+
(theme) =>
|
|
27
|
+
new Promise((resolve, reject) => {
|
|
28
|
+
const el = document.createElement("script");
|
|
29
|
+
el.src = "js/mermaid.min.js"; //-- resolves against <base href> (site root)
|
|
30
|
+
el.onload = () => {
|
|
31
|
+
try {
|
|
32
|
+
window.mermaid.initialize(
|
|
33
|
+
Object.assign(
|
|
34
|
+
{ startOnLoad: false },
|
|
35
|
+
theme || { theme: "base" },
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
resolve(window.mermaid);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
reject(e);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
el.onerror = () =>
|
|
44
|
+
reject(new Error("failed to load js/mermaid.min.js"));
|
|
45
|
+
document.head.appendChild(el);
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
61
48
|
return hbMermaidLoadPromise;
|
|
62
49
|
}
|
|
63
50
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"theme": "base",
|
|
3
|
+
"themeVariables": {
|
|
4
|
+
"background": "transparent",
|
|
5
|
+
"fontSize": "14px",
|
|
6
|
+
"primaryColor": "#85D2FF",
|
|
7
|
+
"primaryColorLight": "#85D2FF",
|
|
8
|
+
"primaryColorDark": "#0065CB",
|
|
9
|
+
"secondaryColor": "#219BFF",
|
|
10
|
+
"secondaryColorLight": "#85D2FF",
|
|
11
|
+
"secondaryColorDark": "#0C4C8C",
|
|
12
|
+
"tertiaryColor": "#219BFF",
|
|
13
|
+
"tertiaryColorLight": "#85D2FF",
|
|
14
|
+
"tertiaryColorDark": "#0C4C8C",
|
|
15
|
+
"lineColor": "#808080",
|
|
16
|
+
"border1": "#606060",
|
|
17
|
+
"textColor": "#A0A0A0",
|
|
18
|
+
"titleColor": "#A0A0A0",
|
|
19
|
+
"labelColor": "#404040",
|
|
20
|
+
"loopTextColor": "#A0A0A0",
|
|
21
|
+
"nodeTextColor": "#404040",
|
|
22
|
+
"labelTextColor": "#404040",
|
|
23
|
+
"pieSectionTextColor": "#404040",
|
|
24
|
+
"nodeBorder": "#219BFF",
|
|
25
|
+
"nodeBg": "transparent"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/hdoc-build-onyx.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
(() => {
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const path = require("node:path");
|
|
4
|
-
|
|
5
|
-
// Replicates the URL normalisation logic from populate_index so page keys match.
|
|
6
|
-
function to_page_path(file) {
|
|
7
|
-
let p = file.relative_path.replaceAll("\\", "/");
|
|
8
|
-
if (
|
|
9
|
-
p.endsWith("/index.md") ||
|
|
10
|
-
p.endsWith("/index.html") ||
|
|
11
|
-
p.endsWith("/index.htm")
|
|
12
|
-
) {
|
|
13
|
-
p = p.substring(0, p.lastIndexOf("/"));
|
|
14
|
-
}
|
|
15
|
-
return `/${p.replace(path.extname(file.relative_path), "")}`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Groups index_records into one entry per page, preserving section order.
|
|
19
|
-
function build_pages(index_records) {
|
|
20
|
-
const pages = new Map();
|
|
21
|
-
for (const file of index_records) {
|
|
22
|
-
if (file.inline) continue;
|
|
23
|
-
const page_path = to_page_path(file);
|
|
24
|
-
if (!pages.has(page_path)) {
|
|
25
|
-
pages.set(page_path, {
|
|
26
|
-
page_path,
|
|
27
|
-
title: file.index_html.fm_props.title || "",
|
|
28
|
-
keywords: file.keywords || "",
|
|
29
|
-
status: file.status || "release",
|
|
30
|
-
lastmod: file.lastmod || null,
|
|
31
|
-
sections: [],
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
const text = (file.index_html.text || "").trim();
|
|
35
|
-
if (text) pages.get(page_path).sections.push(text);
|
|
36
|
-
}
|
|
37
|
-
return Array.from(pages.values());
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Returns an ISO 8601 string, or null if the value is absent or unparseable.
|
|
41
|
-
function safe_iso(value) {
|
|
42
|
-
if (!value) return null;
|
|
43
|
-
const d = new Date(value);
|
|
44
|
-
return Number.isNaN(d.getTime()) ? null : d.toISOString();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
exports.populate_onyx_index = (
|
|
48
|
-
work_path_content,
|
|
49
|
-
doc_id,
|
|
50
|
-
book_config,
|
|
51
|
-
index_records,
|
|
52
|
-
base_url = "",
|
|
53
|
-
verbose = false,
|
|
54
|
-
) => {
|
|
55
|
-
const response = {
|
|
56
|
-
success: false,
|
|
57
|
-
document_count: 0,
|
|
58
|
-
error: "",
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const pages = build_pages(index_records);
|
|
62
|
-
const canonical_base = base_url.replace(/\/$/, "");
|
|
63
|
-
const metadata_entries = [];
|
|
64
|
-
|
|
65
|
-
for (const page of pages) {
|
|
66
|
-
// e.g. onyx/getting-started/index.txt or onyx/reference/api.txt
|
|
67
|
-
const txt_rel = `_onyx${page.page_path}.txt`;
|
|
68
|
-
const txt_abs = path.join(work_path_content, txt_rel);
|
|
69
|
-
|
|
70
|
-
fs.mkdirSync(path.dirname(txt_abs), { recursive: true });
|
|
71
|
-
|
|
72
|
-
// Plain-text body: title, keywords hint, then each section separated by
|
|
73
|
-
// a blank line so Onyx's chunker sees natural paragraph boundaries.
|
|
74
|
-
const lines = [];
|
|
75
|
-
if (page.title) lines.push(page.title, "");
|
|
76
|
-
if (page.keywords) lines.push(`Keywords: ${page.keywords}`, "");
|
|
77
|
-
for (const section of page.sections) {
|
|
78
|
-
lines.push(section, "");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
fs.writeFileSync(txt_abs, lines.join("\n").trimEnd(), "utf8");
|
|
83
|
-
} catch (e) {
|
|
84
|
-
response.error = `Failed to write ${txt_rel}: ${e.message}`;
|
|
85
|
-
return response;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (verbose) console.log(`Onyx: wrote ${txt_rel}`);
|
|
89
|
-
|
|
90
|
-
const entry = {
|
|
91
|
-
filename: txt_rel.replaceAll("\\", "/"),
|
|
92
|
-
link: canonical_base
|
|
93
|
-
? `${canonical_base}${page.page_path}`
|
|
94
|
-
: page.page_path,
|
|
95
|
-
primary_owners: [],
|
|
96
|
-
secondary_owners: [],
|
|
97
|
-
metadata: {
|
|
98
|
-
book_id: doc_id,
|
|
99
|
-
product_family: book_config.productFamily || "",
|
|
100
|
-
audience: Array.isArray(book_config.audience)
|
|
101
|
-
? book_config.audience.join(",")
|
|
102
|
-
: "",
|
|
103
|
-
tags: Array.isArray(book_config.tags)
|
|
104
|
-
? book_config.tags.join(",")
|
|
105
|
-
: "",
|
|
106
|
-
status: page.status,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
const updated_at = safe_iso(page.lastmod);
|
|
110
|
-
if (updated_at) entry.doc_updated_at = updated_at;
|
|
111
|
-
metadata_entries.push(entry);
|
|
112
|
-
|
|
113
|
-
response.document_count++;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const meta_path = path.join(work_path_content, ".onyx_metadata.json");
|
|
117
|
-
try {
|
|
118
|
-
fs.writeFileSync(
|
|
119
|
-
meta_path,
|
|
120
|
-
JSON.stringify(metadata_entries, null, 2),
|
|
121
|
-
"utf8",
|
|
122
|
-
);
|
|
123
|
-
} catch (e) {
|
|
124
|
-
response.error = `Failed to write .onyx_metadata.json: ${e.message}`;
|
|
125
|
-
return response;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
response.success = true;
|
|
129
|
-
console.log(
|
|
130
|
-
`\nOnyx Index Build Complete: ${response.document_count} document records created.`,
|
|
131
|
-
);
|
|
132
|
-
return response;
|
|
133
|
-
};
|
|
134
|
-
})();
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
config:
|
|
2
|
-
theme: 'base'
|
|
3
|
-
themeVariables:
|
|
4
|
-
background: transparent
|
|
5
|
-
fontSize: 14px
|
|
6
|
-
primaryColor: "#85D2FF" # Medium blue
|
|
7
|
-
primaryColorLight: "#85D2FF" # Light accent blue
|
|
8
|
-
primaryColorDark: "#0065CB" # Medium-dark blue
|
|
9
|
-
|
|
10
|
-
secondaryColor: "#219BFF" # Medium blue
|
|
11
|
-
secondaryColorLight: "#85D2FF" # Light accent blue
|
|
12
|
-
secondaryColorDark: "#0C4C8C" # Medium-dark blue
|
|
13
|
-
|
|
14
|
-
tertiaryColor: "#219BFF" # Medium blue
|
|
15
|
-
tertiaryColorLight: "#85D2FF" # Light accent blue
|
|
16
|
-
tertiaryColorDark: "#0C4C8C" # Medium-dark blue
|
|
17
|
-
|
|
18
|
-
lineColor: "#808080" # Medium grey for lines
|
|
19
|
-
border1: "#606060" # Darker grey for borders
|
|
20
|
-
textColor: "#A0A0A0" # Light grey text (visible on both)
|
|
21
|
-
titleColor: "#A0A0A0"
|
|
22
|
-
labelColor: "#404040"
|
|
23
|
-
loopTextColor: "#A0A0A0"
|
|
24
|
-
nodeTextColor: "#404040"
|
|
25
|
-
labelTextColor: "#404040"
|
|
26
|
-
pieSectionTextColor: "#404040"
|
|
27
|
-
nodeBorder: "#219BFF" # Match node border to primary blue
|
|
28
|
-
nodeBg: transparent
|
|
Binary file
|