hdoc-tools 0.65.0 → 0.66.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.
@@ -329,10 +329,20 @@ exports.validate_page = async (args) => {
329
329
  const warnings = [];
330
330
  const skipped = [];
331
331
 
332
- // 1) filename convention (mirrors hdoc-build.js; _-prefixed and *_ext.md
333
- // files never reach here resolve_page_md refuses them)
332
+ // _inline pages get the build pipeline's relaxed rules: no filename
333
+ // convention, fully-qualified Hornbill Docs links allowed, and links
334
+ // need not be root-relative.
335
+ const is_inline = rel.includes("/_inline/");
336
+
337
+ // 1) filename convention (mirrors hdoc-build.js; _inline and *_ext.md
338
+ // files are exempt, as in the full build)
334
339
  const stem = path.basename(rel).replace(/\.md$/i, "");
335
- if (!DOC_FILENAME_RE.test(stem) && stem !== "index") {
340
+ if (
341
+ !is_inline &&
342
+ !stem.endsWith("_ext") &&
343
+ !DOC_FILENAME_RE.test(stem) &&
344
+ stem !== "index"
345
+ ) {
336
346
  errors.push(
337
347
  `Filename does not meet naming standards (^[a-z]+[-a-z0-9]+$): ${path.basename(rel)}`,
338
348
  );
@@ -422,6 +432,18 @@ exports.validate_page = async (args) => {
422
432
  lower.includes("docs.hornbill.com") ||
423
433
  lower.includes("docs-internal.hornbill.com")
424
434
  ) {
435
+ // _inline content is embedded in the app, so fully-qualified
436
+ // docs links are permitted there (build behavior); whether a
437
+ // docs-internal link is allowed depends on the repo being
438
+ // private, which only the full validate knows
439
+ if (is_inline) {
440
+ skipped.push(
441
+ lower.includes("docs-internal.hornbill.com")
442
+ ? `docs-internal link not checked (public-repo rule runs in full validate): ${href}`
443
+ : `Hornbill Docs link not checked (run a full validate): ${href}`,
444
+ );
445
+ return;
446
+ }
425
447
  errors.push(
426
448
  `Hornbill Docs links should not be fully-qualified: ${href}`,
427
449
  );
@@ -433,6 +455,12 @@ exports.validate_page = async (args) => {
433
455
  }
434
456
 
435
457
  if (!href.startsWith("/")) {
458
+ // the root-relative rule does not apply inside _inline (build
459
+ // behavior); the target cannot be resolved the same way, so skip
460
+ if (is_inline) {
461
+ skipped.push(`Relative link not checked (inline content): ${href}`);
462
+ return;
463
+ }
436
464
  errors.push(
437
465
  `Root relative links should start with a forward-slash: ${href}`,
438
466
  );
package/hdoc-toc.js CHANGED
@@ -263,8 +263,13 @@ class TocModel {
263
263
  if (segs.includes("..") || segs.includes(".")) {
264
264
  throw new Error("Invalid path");
265
265
  }
266
- if (segs.some((s) => s.startsWith("_"))) {
267
- throw new Error("Cannot operate inside special (_) folders");
266
+ // Special "_" folders are off-limits, with one exception: _inline
267
+ // directly under the book root holds real, editable inline-help pages
268
+ // (they render in serve/build and are exempt from the nav tree).
269
+ for (let i = 0; i < segs.length; i++) {
270
+ if (segs[i].startsWith("_") && !(i === 1 && segs[i] === "_inline")) {
271
+ throw new Error("Cannot operate inside special (_) folders");
272
+ }
268
273
  }
269
274
  if (!dir && exts) {
270
275
  const lower = norm.toLowerCase();
@@ -293,32 +298,43 @@ class TocModel {
293
298
  return set;
294
299
  }
295
300
 
296
- // Every file on disk under the book (excluding "_" folders), each tagged with
301
+ // Every file on disk under the book (excluding "_" folders, except _inline
302
+ // at the book root — those are real inline-help pages), each tagged with
297
303
  // its kind (page/image/other). Pages also carry a linked flag (in nav or not).
298
304
  list_files() {
299
305
  const linked = this.linked_files();
300
306
  const root = path.join(this.source_path, this.docId);
301
307
  const files = [];
302
308
  const dirs = [];
303
- const walk = (absDir) => {
309
+ const walk = (absDir, in_inline) => {
304
310
  for (const e of fs.readdirSync(absDir, { withFileTypes: true })) {
305
- if (e.name.startsWith("_")) continue; // skip special folders/files
311
+ if (e.name.startsWith("_")) {
312
+ // _inline at the book root is editable content; every other
313
+ // _ entry stays hidden (and blocked by _safe_rel)
314
+ if (!(absDir === root && e.name === "_inline" && e.isDirectory()))
315
+ continue;
316
+ }
306
317
  const abs = path.join(absDir, e.name);
307
318
  const rel = path.relative(this.source_path, abs).split(path.sep).join("/");
319
+ const inline = in_inline || e.name === "_inline";
308
320
  if (e.isDirectory()) {
309
321
  dirs.push(rel);
310
- walk(abs);
322
+ walk(abs, inline);
311
323
  } else {
312
324
  const kind = kind_of(e.name);
313
325
  files.push({
314
326
  file: rel,
315
327
  kind,
316
- linked: kind === "page" ? linked.has(rel) : false,
328
+ // _inline pages are referenced from app help contexts, never
329
+ // the contents tree — report them linked so the unlinked
330
+ // badge/filter stays meaningful
331
+ linked:
332
+ kind === "page" ? (inline ? true : linked.has(rel)) : false,
317
333
  });
318
334
  }
319
335
  }
320
336
  };
321
- if (fs.existsSync(root)) walk(root);
337
+ if (fs.existsSync(root)) walk(root, false);
322
338
  files.sort((a, b) => a.file.localeCompare(b.file));
323
339
  dirs.sort((a, b) => a.localeCompare(b));
324
340
  return { docId: this.docId, dirs, files };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdoc-tools",
3
- "version": "0.65.0",
3
+ "version": "0.66.0",
4
4
  "description": "Hornbill HDocBook Development Support Tool",
5
5
  "main": "hdoc.js",
6
6
  "bin": {