@dogsbay/format-gitbook 0.2.0-beta.101

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/dist/cli.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { FormatPlugin, ExportPage, NavItem } from "@dogsbay/types";
2
+ export interface GitbookImportResult {
3
+ pages: ExportPage[];
4
+ nav: NavItem[];
5
+ redirects: Record<string, string>;
6
+ spaces: string[];
7
+ /** Docs roots to mirror non-`.md` assets from (dir + slug prefix). */
8
+ assetRoots: {
9
+ dir: string;
10
+ prefix: string;
11
+ }[];
12
+ }
13
+ export declare function importGitbook(source: string, opts: Record<string, unknown>): Promise<GitbookImportResult>;
14
+ export declare const plugin: FormatPlugin;
15
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAW,MAAM,gBAAgB,CAAC;AAajF,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sEAAsE;IACtE,UAAU,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAwD9B;AAED,eAAO,MAAM,MAAM,EAAE,YAiBpB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * FormatPlugin for GitBook as a source format.
3
+ *
4
+ * Orchestrates: detect corpus → loadGitbook (config + SUMMARY + pages) →
5
+ * translate each page (parseGitbook) → assemble ExportPage[] + NavItem[].
6
+ * Fragments (`.gitbook/includes/*`) are emitted with `fragment: true` so
7
+ * the CLI writes them as `{% include %}` targets, not routable pages —
8
+ * the same fragment model AsciiBinder/Antora use.
9
+ *
10
+ * The redirects from `.gitbook.yaml` are surfaced on the result so
11
+ * `migrate-gitbook` can carry them into the site config.
12
+ */
13
+ import { existsSync, readFileSync } from "node:fs";
14
+ import { basename } from "node:path";
15
+ import { extractHeadings } from "@dogsbay/format-dogsbay-md";
16
+ import { parseGitbook } from "./parse.js";
17
+ import { loadGitbook, detectGitbook } from "./loaders/load.js";
18
+ function prettify(slug) {
19
+ return slug
20
+ .split(/[-_/]/)
21
+ .filter(Boolean)
22
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
23
+ .join(" ");
24
+ }
25
+ export async function importGitbook(source, opts) {
26
+ if (!existsSync(source)) {
27
+ throw new Error(`Source directory not found: ${source}`);
28
+ }
29
+ const space = typeof opts.space === "string" ? opts.space : undefined;
30
+ const hrefPrefix = typeof opts.hrefPrefix === "string" ? opts.hrefPrefix : "";
31
+ const { pages: pageSources, nav, redirects, spaces, assetRoots } = loadGitbook(source, {
32
+ space,
33
+ hrefPrefix,
34
+ });
35
+ const pages = [];
36
+ let failed = 0;
37
+ let ledgerTotal = 0;
38
+ for (const ps of pageSources) {
39
+ try {
40
+ const content = readFileSync(ps.filePath, "utf-8");
41
+ const { tree, frontmatter, body, ledger } = parseGitbook(content);
42
+ ledgerTotal += ledger.length;
43
+ const headings = extractHeadings(tree);
44
+ const h1 = headings.find((h) => h.depth === 1);
45
+ // A whitespace-only source `title:` must not win — `.trim()` so a
46
+ // blank falls through to the H1 / slug (review #6).
47
+ const fmTitle = typeof frontmatter.title === "string" && frontmatter.title.trim()
48
+ ? frontmatter.title
49
+ : undefined;
50
+ const title = fmTitle || h1?.text || prettify(basename(ps.slug));
51
+ pages.push({
52
+ slug: ps.slug,
53
+ title,
54
+ tree,
55
+ headings,
56
+ frontmatter,
57
+ meta: {},
58
+ ...(ps.fragment ? { fragment: true } : {}),
59
+ // Translated Dogsbay-MD body — what migrate-gitbook writes to disk.
60
+ bodyMarkdown: body,
61
+ });
62
+ }
63
+ catch (err) {
64
+ failed += 1;
65
+ const msg = err instanceof Error ? err.message : String(err);
66
+ console.warn(`gitbook import: failed to convert ${ps.filePath} (slug "${ps.slug}"), skipping: ${msg}`);
67
+ }
68
+ }
69
+ if (failed > 0) {
70
+ console.warn(`gitbook import: ${failed} of ${pageSources.length} page(s) failed and were skipped`);
71
+ }
72
+ if (ledgerTotal > 0) {
73
+ console.warn(`gitbook import: ${ledgerTotal} construct(s) mapped with caveats (see per-page ledger)`);
74
+ }
75
+ return { pages, nav, redirects, spaces, assetRoots };
76
+ }
77
+ export const plugin = {
78
+ name: "gitbook",
79
+ canImport: true,
80
+ canExport: false,
81
+ detectSource: (path) => detectGitbook(path),
82
+ importOptions: [
83
+ {
84
+ flags: "--space <dir>",
85
+ description: "Import a single space (subdirectory containing SUMMARY.md) from a multi-space GitBook repo. Omit to import every space as a top-level section.",
86
+ },
87
+ ],
88
+ exportOptions: [],
89
+ async import(source, opts) {
90
+ const { pages, nav } = await importGitbook(source, opts);
91
+ return { pages, nav };
92
+ },
93
+ };
94
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE/D,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI;SACR,KAAK,CAAC,OAAO,CAAC;SACd,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,IAA6B;IAE7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9E,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE;QACrF,KAAK;QACL,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YAClE,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;YAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAc,CAAC;YACpD,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;YAC/C,kEAAkE;YAClE,oDAAoD;YACpD,MAAM,OAAO,GACX,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/D,CAAC,CAAC,WAAW,CAAC,KAAK;gBACnB,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,KAAK,GAAG,OAAO,IAAI,EAAE,EAAE,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACjE,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,KAAK;gBACL,IAAI;gBACJ,QAAQ;gBACR,WAAW;gBACX,IAAI,EAAE,EAAE;gBACR,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1C,oEAAoE;gBACpE,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,CAAC;YACZ,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CACV,qCAAqC,EAAE,CAAC,QAAQ,WAAW,EAAE,CAAC,IAAI,iBAAiB,GAAG,EAAE,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mBAAmB,MAAM,OAAO,WAAW,CAAC,MAAM,kCAAkC,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,mBAAmB,WAAW,yDAAyD,CAAC,CAAC;IACxG,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAiB;IAClC,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,CAAC,IAAY,EAAW,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;IAC5D,aAAa,EAAE;QACb;YACE,KAAK,EAAE,eAAe;YACtB,WAAW,EACT,gJAAgJ;SACnJ;KACF;IACD,aAAa,EAAE,EAAE;IACjB,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,IAA6B;QACxD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @dogsbay/format-gitbook — GitBook (Git Sync + legacy gitbook-cli)
3
+ * format plugin. Imports GitBook corpora into TreeNode[] by translating
4
+ * the Git Sync markdown dialect to Dogsbay-MD, then parsing with the
5
+ * canonical dogsbay-md parser.
6
+ *
7
+ * See plans/format-gitbook.md.
8
+ */
9
+ export { parseGitbook, type ParseGitbookResult } from "./parse.js";
10
+ export { gitbookToDogsbayMd, type TranslateResult, type TranslateLedgerEntry, } from "./translate.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @dogsbay/format-gitbook — GitBook (Git Sync + legacy gitbook-cli)
3
+ * format plugin. Imports GitBook corpora into TreeNode[] by translating
4
+ * the Git Sync markdown dialect to Dogsbay-MD, then parsing with the
5
+ * canonical dogsbay-md parser.
6
+ *
7
+ * See plans/format-gitbook.md.
8
+ */
9
+ export { parseGitbook } from "./parse.js";
10
+ export { gitbookToDogsbayMd, } from "./translate.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAA2B,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,kBAAkB,GAGnB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface GitbookConfig {
2
+ root: string;
3
+ readme: string;
4
+ summary: string;
5
+ redirects: Record<string, string>;
6
+ }
7
+ /** Read `.gitbook.yaml` from `dir` if present; else return defaults. */
8
+ export declare function readGitbookConfig(dir: string): GitbookConfig;
9
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/loaders/config.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AASD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAwB5D"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `.gitbook.yaml` reader.
3
+ *
4
+ * Documented schema (verified against GitBook docs + real corpora):
5
+ * root: ./docs/ # lookup dir, default ./ ; other paths relative to it
6
+ * structure:
7
+ * readme: README.md # landing page, default README.md
8
+ * summary: SUMMARY.md # table of contents, default SUMMARY.md
9
+ * redirects:
10
+ * old/path: new/page.md # old URL → target md file
11
+ */
12
+ import { existsSync, readFileSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import YAML from "yaml";
15
+ const DEFAULTS = {
16
+ root: "./",
17
+ readme: "README.md",
18
+ summary: "SUMMARY.md",
19
+ redirects: {},
20
+ };
21
+ /** Read `.gitbook.yaml` from `dir` if present; else return defaults. */
22
+ export function readGitbookConfig(dir) {
23
+ const p = join(dir, ".gitbook.yaml");
24
+ if (!existsSync(p))
25
+ return { ...DEFAULTS };
26
+ let parsed;
27
+ try {
28
+ parsed = YAML.parse(readFileSync(p, "utf-8"));
29
+ }
30
+ catch {
31
+ return { ...DEFAULTS };
32
+ }
33
+ if (!parsed || typeof parsed !== "object")
34
+ return { ...DEFAULTS };
35
+ const o = parsed;
36
+ const structure = (o.structure ?? {});
37
+ const redirects = {};
38
+ if (o.redirects && typeof o.redirects === "object") {
39
+ for (const [k, v] of Object.entries(o.redirects)) {
40
+ if (typeof v === "string")
41
+ redirects[k] = v;
42
+ }
43
+ }
44
+ return {
45
+ root: typeof o.root === "string" ? o.root : DEFAULTS.root,
46
+ readme: typeof structure.readme === "string" ? structure.readme : DEFAULTS.readme,
47
+ summary: typeof structure.summary === "string" ? structure.summary : DEFAULTS.summary,
48
+ redirects,
49
+ };
50
+ }
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/loaders/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB,MAAM,QAAQ,GAAkB;IAC9B,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClE,MAAM,CAAC,GAAG,MAAiC,CAAC;IAC5C,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAA4B,CAAC;IACjE,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACnD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAoC,CAAC,EAAE,CAAC;YAC5E,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;QACzD,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM;QACjF,OAAO,EAAE,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;QACrF,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { NavItem } from "@dogsbay/types";
2
+ export interface GitbookPageSource {
3
+ filePath: string;
4
+ slug: string;
5
+ /** True for `.gitbook/includes/*` — mirrored as a fragment, not a page. */
6
+ fragment?: boolean;
7
+ }
8
+ /** A resolved docs root to mirror assets from, and its slug prefix. */
9
+ export interface GitbookAssetRoot {
10
+ /** Absolute docs directory (space dir + `.gitbook.yaml` `root:`). */
11
+ dir: string;
12
+ /** Slug prefix for pages/assets under this root ("" or "<space>/"). */
13
+ prefix: string;
14
+ }
15
+ export interface GitbookLoadResult {
16
+ pages: GitbookPageSource[];
17
+ nav: NavItem[];
18
+ redirects: Record<string, string>;
19
+ /** Space directories detected (relative to source); ≥2 ⇒ multi-space. */
20
+ spaces: string[];
21
+ /** Docs roots to mirror non-`.md` assets from, with their slug prefix. */
22
+ assetRoots: GitbookAssetRoot[];
23
+ }
24
+ export interface GitbookLoadOptions {
25
+ /** Restrict to a single space directory (relative to source root). */
26
+ space?: string;
27
+ /** URL prefix applied to nav hrefs. */
28
+ hrefPrefix?: string;
29
+ }
30
+ /** Does this directory look like a GitBook corpus? */
31
+ export declare function detectGitbook(sourceDir: string): boolean;
32
+ export declare function loadGitbook(sourceDir: string, opts?: GitbookLoadOptions): GitbookLoadResult;
33
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/loaders/load.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAI9C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,yEAAyE;IACzE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAYxD;AAsFD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,iBAAiB,CA4D/F"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * GitBook corpus loader — discover the docs root, read `.gitbook.yaml`,
3
+ * parse `SUMMARY.md` for nav, enumerate every page (including orphans not
4
+ * in the summary), and surface redirects + include fragments.
5
+ *
6
+ * Multi-space corpora (e.g. snyk/user-docs holds six spaces, each a dir
7
+ * with its own SUMMARY.md) are detected: when the caller doesn't point at
8
+ * a single space, every dir containing a SUMMARY.md is a space. The
9
+ * default import concatenates all spaces (each summary's nav becomes a
10
+ * top-level section); `--space <dir>` selects one.
11
+ */
12
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
13
+ import { basename, join, relative } from "node:path";
14
+ import { readGitbookConfig } from "./config.js";
15
+ import { parseSummary, pathToSlug } from "./summary.js";
16
+ /** Does this directory look like a GitBook corpus? */
17
+ export function detectGitbook(sourceDir) {
18
+ if (!existsSync(sourceDir))
19
+ return false;
20
+ try {
21
+ if (!statSync(sourceDir).isDirectory())
22
+ return false;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ // A .gitbook.yaml anywhere near the top, or a SUMMARY.md, is the signal.
28
+ if (existsSync(join(sourceDir, ".gitbook.yaml")))
29
+ return true;
30
+ if (existsSync(join(sourceDir, "SUMMARY.md")))
31
+ return true;
32
+ // Or a single-level space dir carrying either marker.
33
+ return findSpaces(sourceDir).length > 0;
34
+ }
35
+ /**
36
+ * Directories (relative) that contain a SUMMARY.md — each is a space.
37
+ *
38
+ * If the ROOT itself has a SUMMARY.md, the corpus is single-space and we
39
+ * return just `["."]` — we do NOT also scan subdirectories, because a
40
+ * nested `SUMMARY.md` (e.g. a stray one under `api/`) would otherwise be
41
+ * misread as a second space, duplicating that subtree's pages and adding
42
+ * a phantom top-level nav section (review #8). Multi-space is the
43
+ * monorepo shape where the root has NO SUMMARY.md but ≥1 subdir does.
44
+ */
45
+ function findSpaces(sourceDir) {
46
+ if (existsSync(join(sourceDir, "SUMMARY.md")) || existsSync(join(sourceDir, ".gitbook.yaml"))) {
47
+ return ["."];
48
+ }
49
+ const out = [];
50
+ const seen = new Set();
51
+ const consider = (dir) => {
52
+ if (existsSync(join(dir, "SUMMARY.md"))) {
53
+ const rel = relative(sourceDir, dir) || ".";
54
+ if (!seen.has(rel)) {
55
+ seen.add(rel);
56
+ out.push(rel);
57
+ }
58
+ }
59
+ };
60
+ // One level down (the snyk monorepo shape: docs/, platform-administration/…).
61
+ let entries = [];
62
+ try {
63
+ entries = readdirSync(sourceDir);
64
+ }
65
+ catch {
66
+ return out;
67
+ }
68
+ for (const name of entries) {
69
+ if (name.startsWith(".") || name === "node_modules")
70
+ continue;
71
+ const full = join(sourceDir, name);
72
+ try {
73
+ if (statSync(full).isDirectory())
74
+ consider(full);
75
+ }
76
+ catch {
77
+ /* ignore */
78
+ }
79
+ }
80
+ return out;
81
+ }
82
+ /** Walk `spaceDir` for every `.md` file; classify includes as fragments. */
83
+ function walkPages(spaceDir, sourceDir) {
84
+ const out = [];
85
+ const walk = (dir) => {
86
+ let entries;
87
+ try {
88
+ entries = readdirSync(dir);
89
+ }
90
+ catch {
91
+ return;
92
+ }
93
+ for (const name of entries) {
94
+ if (name === "node_modules")
95
+ continue;
96
+ const full = join(dir, name);
97
+ let st;
98
+ try {
99
+ st = statSync(full);
100
+ }
101
+ catch {
102
+ continue;
103
+ }
104
+ if (st.isDirectory()) {
105
+ // Hidden dirs are skipped EXCEPT `.gitbook` (holds includes).
106
+ if (name.startsWith(".") && name !== ".gitbook")
107
+ continue;
108
+ walk(full);
109
+ continue;
110
+ }
111
+ if (!name.toLowerCase().endsWith(".md"))
112
+ continue;
113
+ if (name === "SUMMARY.md" || name === "GLOSSARY.md")
114
+ continue;
115
+ const relFromSpace = relative(spaceDir, full).replace(/\\/g, "/");
116
+ const isInclude = relFromSpace.includes(".gitbook/includes/");
117
+ out.push({
118
+ filePath: full,
119
+ slug: pathToSlug(relFromSpace),
120
+ ...(isInclude ? { fragment: true } : {}),
121
+ });
122
+ }
123
+ };
124
+ walk(spaceDir);
125
+ return out;
126
+ }
127
+ export function loadGitbook(sourceDir, opts = {}) {
128
+ const hrefPrefix = opts.hrefPrefix ?? "";
129
+ const allSpaces = findSpaces(sourceDir);
130
+ // Which spaces to load: an explicit --space, else all detected (or the
131
+ // root itself if none matched).
132
+ let spaces = opts.space ? [opts.space] : allSpaces;
133
+ if (spaces.length === 0)
134
+ spaces = ["."];
135
+ const pages = [];
136
+ const nav = [];
137
+ const redirects = {};
138
+ const assetRoots = [];
139
+ const multi = spaces.length > 1;
140
+ for (const space of spaces) {
141
+ const spaceDir = space === "." ? sourceDir : join(sourceDir, space);
142
+ if (!existsSync(spaceDir))
143
+ continue;
144
+ const config = readGitbookConfig(spaceDir);
145
+ // `root:` relocates the docs dir within the space.
146
+ const docsDir = config.root && config.root !== "./" ? join(spaceDir, config.root) : spaceDir;
147
+ // Page prefix so multi-space slugs don't collide (space dir name).
148
+ const slugPrefix = multi && space !== "." ? `${space}/` : "";
149
+ assetRoots.push({ dir: docsDir, prefix: slugPrefix });
150
+ for (const p of walkPages(docsDir, docsDir)) {
151
+ pages.push({ ...p, slug: `${slugPrefix}${p.slug}`.replace(/\/+/g, "/") });
152
+ }
153
+ // Nav from SUMMARY.md (under docsDir per config.summary).
154
+ const summaryPath = join(docsDir, config.summary);
155
+ const navPrefix = `${hrefPrefix}${slugPrefix ? "/" + slugPrefix.replace(/\/$/, "") : ""}`;
156
+ if (existsSync(summaryPath)) {
157
+ const parsed = parseSummary(readFileSync(summaryPath, "utf-8"), navPrefix);
158
+ if (multi) {
159
+ nav.push({ label: prettify(space), children: parsed.nav });
160
+ }
161
+ else {
162
+ nav.push(...parsed.nav);
163
+ }
164
+ }
165
+ else {
166
+ // No SUMMARY.md — infer nav from folder structure (paths → slugs).
167
+ const inferred = inferNavFromPages(pages.filter((p) => !p.fragment && p.slug.startsWith(slugPrefix)));
168
+ if (multi)
169
+ nav.push({ label: prettify(space), children: inferred });
170
+ else
171
+ nav.push(...inferred);
172
+ }
173
+ // Redirect keys (old URL) AND values (target .md) are relative to the
174
+ // space, so BOTH get the space slug prefix in a multi-space import —
175
+ // else a redirect in space `docs` would point at an unprefixed target
176
+ // that doesn't exist under `docs/`.
177
+ for (const [k, v] of Object.entries(config.redirects)) {
178
+ const key = slugPrefix ? `${slugPrefix}${k}` : k;
179
+ const val = slugPrefix ? `${slugPrefix}${v.replace(/^\.\//, "")}` : v;
180
+ redirects[key] = val;
181
+ }
182
+ }
183
+ return { pages, nav, redirects, spaces: allSpaces, assetRoots };
184
+ }
185
+ /** Fallback nav: flat list from page slugs when there's no SUMMARY.md. */
186
+ function inferNavFromPages(pages) {
187
+ return pages
188
+ .filter((p) => p.slug !== "index")
189
+ .map((p) => ({ label: prettify(basename(p.slug)), href: `/${p.slug}` }))
190
+ .sort((a, b) => a.label.localeCompare(b.label));
191
+ }
192
+ function prettify(s) {
193
+ return s
194
+ .split(/[-_/]/)
195
+ .filter(Boolean)
196
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
197
+ .join(" ");
198
+ }
199
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/loaders/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SUMMARY.md → NavItem[] + referenced page paths.
3
+ *
4
+ * GitBook's table of contents is a markdown file:
5
+ * - `# Table of contents` / `# Summary` header → ignored
6
+ * - `## Group title` (optionally trailing `<a href id>`) → a nav group
7
+ * - `* [Title](path.md)` list items; nesting by indentation
8
+ * - external `* [Title](https://…)` → external link leaf
9
+ * - `folder/README.md` links → the folder's landing page
10
+ *
11
+ * Slug convention (matches Dogsbay's directory-landing model):
12
+ * - `README.md` → `index`
13
+ * - `folder/README.md` → `folder/index`
14
+ * - `folder/page.md` → `folder/page`
15
+ * so a folder group with a linked landing page serves at `/folder`.
16
+ *
17
+ * See dogsbay-research/content/formats/gitbook-import-support.md §1.
18
+ */
19
+ import type { NavItem } from "@dogsbay/types";
20
+ export interface ParsedSummary {
21
+ nav: NavItem[];
22
+ /** Every local page path referenced by the summary (posix, .md kept). */
23
+ referenced: string[];
24
+ }
25
+ /** Normalize a GitBook page path to a Dogsbay slug (README → index). */
26
+ export declare function pathToSlug(relPath: string): string;
27
+ export declare function parseSummary(content: string, hrefPrefix?: string): ParsedSummary;
28
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/loaders/summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,yEAAyE;IACzE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKlD;AAaD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,aAAa,CA6C5E"}
@@ -0,0 +1,95 @@
1
+ /** Normalize a GitBook page path to a Dogsbay slug (README → index). */
2
+ export function pathToSlug(relPath) {
3
+ let p = relPath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\.md$/i, "");
4
+ if (p === "README" || p === "readme")
5
+ return "index";
6
+ p = p.replace(/\/README$/i, "/index");
7
+ return p;
8
+ }
9
+ const HEADING_RE = /^(#{1,6})\s+(.*?)\s*$/;
10
+ const ITEM_RE = /^(\s*)[*+-]\s+(.*)$/;
11
+ // [Label](target) — target either `<dest with spaces>` (CommonMark
12
+ // angle form; GitBook uses it for exported filenames like
13
+ // `<README (1).md>`) or a bare `dest`. Trailing markup after the link
14
+ // is tolerated.
15
+ const LINK_RE = /^\[([^\]]*)\]\(\s*(?:<([^>]*)>|([^)\s]+))[^)]*\)/;
16
+ const EXTERNAL_RE = /^(https?:\/\/|mailto:|tel:)/i;
17
+ // Strip a trailing `<a href id>` anchor GitBook adds to group headings.
18
+ const ANCHOR_TAIL_RE = /\s*<a\b[^>]*><\/a>\s*$/;
19
+ export function parseSummary(content, hrefPrefix = "") {
20
+ const referenced = [];
21
+ const top = [];
22
+ // Current group container the following items attach to (null = top level).
23
+ let group = null;
24
+ // Stack of {indent, item} for list nesting within the current section.
25
+ let stack = [];
26
+ const container = () => (group ? group.children : top);
27
+ for (const raw of content.split("\n")) {
28
+ const line = raw.replace(/\s+$/, "");
29
+ if (!line)
30
+ continue;
31
+ const h = line.match(HEADING_RE);
32
+ if (h) {
33
+ // `#` = doc title (ignore). `##`+ = a page group.
34
+ if (h[1].length === 1)
35
+ continue;
36
+ const label = h[2].replace(ANCHOR_TAIL_RE, "").trim();
37
+ group = { label, children: [] };
38
+ top.push(group);
39
+ stack = [];
40
+ continue;
41
+ }
42
+ const it = line.match(ITEM_RE);
43
+ if (!it)
44
+ continue;
45
+ const indent = it[1].replace(/\t/g, " ").length;
46
+ const item = parseItem(it[2], hrefPrefix, referenced);
47
+ if (!item)
48
+ continue;
49
+ // Attach by indentation. Pop deeper-or-equal entries; the remaining
50
+ // top of stack is the parent.
51
+ while (stack.length && stack[stack.length - 1].indent >= indent)
52
+ stack.pop();
53
+ if (stack.length === 0) {
54
+ container().push(item);
55
+ }
56
+ else {
57
+ const parent = stack[stack.length - 1].item;
58
+ (parent.children ??= []).push(item);
59
+ }
60
+ stack.push({ indent, item });
61
+ }
62
+ strip(top);
63
+ return { nav: top, referenced };
64
+ }
65
+ function parseItem(text, hrefPrefix, referenced) {
66
+ const m = text.match(LINK_RE);
67
+ if (!m) {
68
+ // A plain-text item (no link) — a group-ish header without a page.
69
+ const label = text.replace(ANCHOR_TAIL_RE, "").trim();
70
+ return label ? { label } : null;
71
+ }
72
+ const target = (m[2] ?? m[3] ?? "").trim();
73
+ const label = m[1].replace(/[*_`]/g, "").trim() || target;
74
+ if (EXTERNAL_RE.test(target))
75
+ return { label, href: target };
76
+ // Local page. Split off a #fragment, record the file, slugify.
77
+ const hashIdx = target.indexOf("#");
78
+ const filePart = hashIdx === -1 ? target : target.slice(0, hashIdx);
79
+ const frag = hashIdx === -1 ? "" : target.slice(hashIdx);
80
+ if (filePart)
81
+ referenced.push(filePart.replace(/^\.\//, ""));
82
+ const slug = pathToSlug(filePart);
83
+ const href = `${hrefPrefix}/${slug}`.replace(/\/+/g, "/");
84
+ return { label, href: `${href}${frag}` };
85
+ }
86
+ /** Drop empty `children: []` so leaves don't read as empty groups. */
87
+ function strip(items) {
88
+ for (const it of items) {
89
+ if (it.children && it.children.length === 0)
90
+ delete it.children;
91
+ else if (it.children)
92
+ strip(it.children);
93
+ }
94
+ }
95
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/loaders/summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { TreeNode } from "@dogsbay/types";
2
+ import { type TranslateLedgerEntry } from "./translate.js";
3
+ export interface ParseGitbookResult {
4
+ tree: TreeNode[];
5
+ frontmatter: Record<string, unknown>;
6
+ /** Frontmatter + translated body — the editable Dogsbay-MD for migrate. */
7
+ markdown: string;
8
+ /** Translated body only (no frontmatter) — for callers writing their own. */
9
+ body: string;
10
+ ledger: TranslateLedgerEntry[];
11
+ }
12
+ export declare function parseGitbook(src: string): ParseGitbookResult;
13
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAc5D"}
package/dist/parse.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * GitBook page → { tree, frontmatter, markdown, ledger }.
3
+ *
4
+ * Pipeline:
5
+ * 1. Split YAML frontmatter off the body (so the body transform can't
6
+ * disturb it).
7
+ * 2. Translate the GitBook Git Sync body → Dogsbay-MD text
8
+ * (`gitbookToDogsbayMd`).
9
+ * 3. Parse the translated Dogsbay-MD with the canonical
10
+ * `dogsbayMdToTree` — GitBook markdown is a near-superset of
11
+ * Dogsbay-MD, so its own parser is the definition of correctness
12
+ * and yields the TreeNode with zero new node types.
13
+ *
14
+ * `markdown` (frontmatter + translated body) is what `migrate-gitbook`
15
+ * writes to disk — canonical, editable Dogsbay-MD. `tree` feeds the
16
+ * runtime path (format-astro emit, headings, title).
17
+ */
18
+ import { dogsbayMdToTree } from "@dogsbay/format-dogsbay-md";
19
+ import { gitbookToDogsbayMd } from "./translate.js";
20
+ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n?/;
21
+ export function parseGitbook(src) {
22
+ const normalized = src.replace(/\r\n?/g, "\n");
23
+ const fmMatch = normalized.match(FRONTMATTER_RE);
24
+ const fmBlock = fmMatch ? fmMatch[0] : "";
25
+ const body = fmMatch ? normalized.slice(fmMatch[0].length) : normalized;
26
+ const { markdown: translatedBody, ledger } = gitbookToDogsbayMd(body);
27
+ const markdown = fmBlock ? `${fmBlock.replace(/\n?$/, "\n")}\n${translatedBody}` : translatedBody;
28
+ // dogsbayMdToTree extracts frontmatter itself (gray-matter) and parses
29
+ // the body into TreeNode[]. Feed it the recombined markdown.
30
+ const { tree, frontmatter } = dogsbayMdToTree(markdown);
31
+ return { tree, frontmatter: frontmatter ?? {}, markdown, body: translatedBody, ledger };
32
+ }
33
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAA6B,MAAM,gBAAgB,CAAC;AAY/E,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAElD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAExE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;IAElG,uEAAuE;IACvE,6DAA6D;IAC7D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAExD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * GitBook Git Sync markdown → Dogsbay-MD text translator.
3
+ *
4
+ * GitBook's Git Sync dialect is CommonMark + liquid-style `{% tag %}`
5
+ * blocks + a handful of raw-HTML emissions. Dogsbay-MD is CommonMark +
6
+ * `:::` block directives + `{attrs}`. So translation is largely a
7
+ * delimiter rewrite: the inline/prose/list/table markdown passes through
8
+ * untouched; only the `{% %}` tags and specific HTML shapes are rewritten.
9
+ *
10
+ * Two structural classes of `{% %}` tag:
11
+ * - **Directive tags** (hint, tabs/tab, stepper/step, columns/column,
12
+ * expandable) map to `:::` block directives and can nest. These are
13
+ * parsed into a region tree and emitted with DEPTH-AWARE fence lengths
14
+ * (outer directives get more colons than inner) — markdown-it-container
15
+ * closes an outer `:::` at the first bare `:::` otherwise, so equal
16
+ * fence lengths would break nesting. Mirrors format-dogsbay-md's
17
+ * serializer fence-scaling.
18
+ * - **Leaf/opaque tags** (code, embed, content-ref, file, page-ref,
19
+ * include, openapi, swagger, math) transform to a self-contained
20
+ * markdown string in one shot; they don't participate in `:::` nesting.
21
+ *
22
+ * Fence-aware throughout: `{% %}` inside a fenced code block is literal
23
+ * and never rewritten.
24
+ *
25
+ * Anything unmapped is recorded in the returned `ledger` (never silent
26
+ * loss — same discipline as format-dita) and passed through as raw text.
27
+ *
28
+ * See plans/format-gitbook.md and
29
+ * dogsbay-research/content/formats/gitbook-import-support.md.
30
+ */
31
+ export interface TranslateLedgerEntry {
32
+ /** The GitBook construct that wasn't cleanly mapped. */
33
+ construct: string;
34
+ /** Human-readable note on how it was handled. */
35
+ note: string;
36
+ /** 1-based source line, when known. */
37
+ line?: number;
38
+ }
39
+ export interface TranslateResult {
40
+ markdown: string;
41
+ ledger: TranslateLedgerEntry[];
42
+ }
43
+ export declare function gitbookToDogsbayMd(src: string): TranslateResult;
44
+ //# sourceMappingURL=translate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAgED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAsG/D"}
@@ -0,0 +1,427 @@
1
+ /**
2
+ * GitBook Git Sync markdown → Dogsbay-MD text translator.
3
+ *
4
+ * GitBook's Git Sync dialect is CommonMark + liquid-style `{% tag %}`
5
+ * blocks + a handful of raw-HTML emissions. Dogsbay-MD is CommonMark +
6
+ * `:::` block directives + `{attrs}`. So translation is largely a
7
+ * delimiter rewrite: the inline/prose/list/table markdown passes through
8
+ * untouched; only the `{% %}` tags and specific HTML shapes are rewritten.
9
+ *
10
+ * Two structural classes of `{% %}` tag:
11
+ * - **Directive tags** (hint, tabs/tab, stepper/step, columns/column,
12
+ * expandable) map to `:::` block directives and can nest. These are
13
+ * parsed into a region tree and emitted with DEPTH-AWARE fence lengths
14
+ * (outer directives get more colons than inner) — markdown-it-container
15
+ * closes an outer `:::` at the first bare `:::` otherwise, so equal
16
+ * fence lengths would break nesting. Mirrors format-dogsbay-md's
17
+ * serializer fence-scaling.
18
+ * - **Leaf/opaque tags** (code, embed, content-ref, file, page-ref,
19
+ * include, openapi, swagger, math) transform to a self-contained
20
+ * markdown string in one shot; they don't participate in `:::` nesting.
21
+ *
22
+ * Fence-aware throughout: `{% %}` inside a fenced code block is literal
23
+ * and never rewritten.
24
+ *
25
+ * Anything unmapped is recorded in the returned `ledger` (never silent
26
+ * loss — same discipline as format-dita) and passed through as raw text.
27
+ *
28
+ * See plans/format-gitbook.md and
29
+ * dogsbay-research/content/formats/gitbook-import-support.md.
30
+ */
31
+ /** GitBook hint style → Dogsbay callout directive name. */
32
+ const HINT_STYLE_TO_CALLOUT = {
33
+ info: "info",
34
+ success: "success",
35
+ warning: "warning",
36
+ danger: "danger",
37
+ note: "note",
38
+ tip: "tip",
39
+ };
40
+ /** Leaf tags with no matching `{% end… %}` — transformed inline. */
41
+ const LEAF_TAGS = new Set(["include", "page-ref"]);
42
+ /** Directive tags: GitBook tag → Dogsbay directive name (or resolver). */
43
+ const DIRECTIVE_TAGS = new Set([
44
+ "hint",
45
+ "tabs",
46
+ "tab",
47
+ "stepper",
48
+ "step",
49
+ "columns",
50
+ "column",
51
+ "expandable",
52
+ ]);
53
+ // ── Attribute parsing ─────────────────────────────────────────────────────
54
+ /** Parse `key="value"` pairs (and bare `key`) from a tag's attribute text. */
55
+ function parseAttrs(attrText) {
56
+ const out = {};
57
+ const re = /(\w[\w-]*)\s*=\s*"([^"]*)"/g;
58
+ let m;
59
+ while ((m = re.exec(attrText)))
60
+ out[m[1]] = m[2];
61
+ return out;
62
+ }
63
+ /** Serialize a Dogsbay `{key="value"}` attribute block (empty → ""). */
64
+ function attrBlock(attrs) {
65
+ const keys = Object.keys(attrs);
66
+ if (keys.length === 0)
67
+ return "";
68
+ const inner = keys.map((k) => `${k}="${attrs[k].replace(/"/g, "&quot;")}"`).join(" ");
69
+ return `{${inner}}`;
70
+ }
71
+ // ── Fence-aware line scanning ─────────────────────────────────────────────
72
+ const CODE_FENCE_RE = /^(\s*)(`{3,}|~{3,})/;
73
+ /** Match a full-line opening tag `{% name attrs %}` (name captured). */
74
+ const OPEN_TAG_RE = /^\s*\{%\s*([a-z][a-z-]*)\b([^%]*?)\s*%\}\s*$/;
75
+ /** Match a full-line closing tag `{% endname %}`. */
76
+ const CLOSE_TAG_RE = /^\s*\{%\s*end([a-z][a-z-]*)\s*%\}\s*$/;
77
+ /** Match a self-closing/leaf `{% include "…" %}` anywhere on a line. */
78
+ const INCLUDE_RE = /\{%\s*include\s+"([^"]+)"\s*%\}/g;
79
+ // ── Main entry ─────────────────────────────────────────────────────────────
80
+ export function gitbookToDogsbayMd(src) {
81
+ const ledger = [];
82
+ const lines = src.replace(/\r\n?/g, "\n").split("\n");
83
+ // Region stack — index 0 is the root's children.
84
+ const root = [];
85
+ const stack = [root];
86
+ const dirStack = []; // GitBook tag names of open directives, for close matching
87
+ let fence = null; // active code-fence marker
88
+ let i = 0;
89
+ const pushText = (text) => {
90
+ stack[stack.length - 1].push({ kind: "text", text });
91
+ };
92
+ while (i < lines.length) {
93
+ const line = lines[i];
94
+ // Inside a fenced code block: copy verbatim until the fence closes.
95
+ if (fence !== null) {
96
+ pushText(line);
97
+ const fm = line.match(CODE_FENCE_RE);
98
+ if (fm && fm[2][0] === fence[0] && fm[2].length >= fence.length)
99
+ fence = null;
100
+ i++;
101
+ continue;
102
+ }
103
+ const fm = line.match(CODE_FENCE_RE);
104
+ if (fm) {
105
+ fence = fm[2];
106
+ pushText(line);
107
+ i++;
108
+ continue;
109
+ }
110
+ // Close tags MUST be tested before open tags: `{% endtab %}` also
111
+ // matches OPEN_TAG_RE (as a tag literally named "endtab"), so checking
112
+ // open first would swallow every close and never pop the region stack.
113
+ const close = line.match(CLOSE_TAG_RE);
114
+ if (close) {
115
+ const closeTag = close[1];
116
+ // Only pop when the close matches the CURRENTLY OPEN directive. An
117
+ // orphaned close — e.g. `{% endembed %}` left behind when a leaf
118
+ // embed inside a tab bailed (see consumeSpecialBlock), or any
119
+ // unbalanced/foreign close — must NOT pop, or it would tear down an
120
+ // enclosing :::tab/:::step and spill its content out. Non-matching
121
+ // closes are dropped (the marker line vanishes).
122
+ if (dirStack.length > 0 && dirStack[dirStack.length - 1] === closeTag) {
123
+ stack.pop();
124
+ dirStack.pop();
125
+ }
126
+ i++;
127
+ continue;
128
+ }
129
+ const open = line.match(OPEN_TAG_RE);
130
+ if (open) {
131
+ const tag = open[1];
132
+ const attrText = open[2] ?? "";
133
+ // Leaf tags (no close): include / page-ref. Route through the
134
+ // inline transformer, which also handles their mid-line form.
135
+ if (LEAF_TAGS.has(tag)) {
136
+ pushText(transformContentLine(line, ledger, i + 1));
137
+ i++;
138
+ continue;
139
+ }
140
+ if (DIRECTIVE_TAGS.has(tag)) {
141
+ const { name, attrs } = mapDirectiveOpen(tag, attrText, ledger, i + 1);
142
+ const node = { kind: "dir", name, attrs, children: [] };
143
+ stack[stack.length - 1].push(node);
144
+ stack.push(node.children);
145
+ // Track the GITBOOK tag (not the dogsbay name) so a close is
146
+ // matched by its `{% end<tag> %}`.
147
+ dirStack.push(tag);
148
+ i++;
149
+ continue;
150
+ }
151
+ // Opaque/special block tags: consume to their matching close.
152
+ const consumed = consumeSpecialBlock(tag, attrText, lines, i, ledger);
153
+ if (consumed) {
154
+ pushText(consumed.text);
155
+ i = consumed.nextIndex;
156
+ continue;
157
+ }
158
+ // Unknown open tag — record and pass through verbatim.
159
+ ledger.push({ construct: `{% ${tag} %}`, note: "unknown tag, passed through verbatim", line: i + 1 });
160
+ pushText(line);
161
+ i++;
162
+ continue;
163
+ }
164
+ // Content line — apply inline transforms (leaf includes, HTML, emoji).
165
+ pushText(transformContentLine(line, ledger, i + 1));
166
+ i++;
167
+ }
168
+ return { markdown: renderNodes(root, 0).trimEnd() + "\n", ledger };
169
+ }
170
+ // ── Directive open mapping ────────────────────────────────────────────────
171
+ function mapDirectiveOpen(tag, attrText, ledger, line) {
172
+ const a = parseAttrs(attrText);
173
+ switch (tag) {
174
+ case "hint": {
175
+ const style = (a.style ?? "info").toLowerCase();
176
+ const name = HINT_STYLE_TO_CALLOUT[style];
177
+ if (!name) {
178
+ ledger.push({ construct: `{% hint style="${style}" %}`, note: `unknown hint style → :::note`, line });
179
+ return { name: "note", attrs: "" };
180
+ }
181
+ return { name, attrs: "" };
182
+ }
183
+ case "tabs":
184
+ return { name: "tabs", attrs: "" };
185
+ case "tab":
186
+ return { name: "tab", attrs: a.title ? attrBlock({ title: a.title }) : "" };
187
+ case "stepper":
188
+ return { name: "steps", attrs: "" };
189
+ case "step":
190
+ return { name: "step", attrs: a.title ? attrBlock({ title: a.title }) : "" };
191
+ case "columns":
192
+ return { name: "grid", attrs: "" };
193
+ case "column":
194
+ return { name: "grid-item", attrs: "" };
195
+ case "expandable":
196
+ return { name: "details", attrs: a.title ? attrBlock({ title: a.title }) : "" };
197
+ default:
198
+ return { name: tag, attrs: "" };
199
+ }
200
+ }
201
+ // ── Special/opaque block tags ─────────────────────────────────────────────
202
+ /**
203
+ * Handle a block tag whose body needs whole-span transformation rather
204
+ * than `:::` nesting. Returns the emitted markdown + the index of the
205
+ * line after the tag's close, or null if `tag` isn't a special block.
206
+ */
207
+ function consumeSpecialBlock(tag, attrText, lines, openIndex, ledger) {
208
+ const specials = new Set([
209
+ "code",
210
+ "embed",
211
+ "content-ref",
212
+ "file",
213
+ "openapi",
214
+ "swagger",
215
+ "hint-close-guard", // placeholder, never matches
216
+ ]);
217
+ if (!specials.has(tag))
218
+ return null;
219
+ const a = parseAttrs(attrText);
220
+ const line = openIndex + 1;
221
+ // `code` bodies hold a fenced code block that always closes with
222
+ // `{% endcode %}` and may legitimately contain `{`-ish text, so scan
223
+ // it straight through. Every other body-tag (embed, file, content-ref,
224
+ // openapi) ALSO has a leaf form with no close: `{% embed url %}` and
225
+ // `{% file src %}` frequently appear bare, sometimes two in a row. If a
226
+ // foreign `{% %}` tag appears before the close, this is the leaf form —
227
+ // bail so we don't swallow following siblings (GitBook's own tabs.md
228
+ // embed, and snyk's back-to-back file tags, both hit this).
229
+ const closeRe = new RegExp(`^\\s*\\{%\\s*end${tag}\\s*%\\}\\s*$`);
230
+ const body = [];
231
+ let j = openIndex + 1;
232
+ let bailedLeaf = false;
233
+ while (j < lines.length && !closeRe.test(lines[j])) {
234
+ if (tag !== "code" && /^\s*\{%/.test(lines[j])) {
235
+ bailedLeaf = true;
236
+ break;
237
+ }
238
+ body.push(lines[j]);
239
+ j++;
240
+ }
241
+ const leaf = bailedLeaf || j >= lines.length;
242
+ // Leaf form consumes only the open line; block form consumes the close.
243
+ const nextIndex = leaf ? openIndex + 1 : j + 1;
244
+ const effBody = leaf ? [] : body;
245
+ switch (tag) {
246
+ case "code":
247
+ return { text: transformCodeBlock(a, effBody), nextIndex };
248
+ case "content-ref":
249
+ return { text: transformContentRef(a, effBody), nextIndex };
250
+ case "embed":
251
+ return { text: transformEmbed(a, effBody), nextIndex };
252
+ case "file":
253
+ return { text: transformFile(a, effBody), nextIndex };
254
+ case "openapi":
255
+ ledger.push({ construct: "{% openapi %}", note: "emitted :::api-endpoint placeholder; wire to format-openapi to render", line });
256
+ return { text: transformOpenapi(a, effBody), nextIndex };
257
+ case "swagger":
258
+ ledger.push({ construct: "{% swagger %}", note: "legacy API block emitted as :::api-endpoint placeholder", line });
259
+ return { text: transformSwagger(a, lines, openIndex), nextIndex: skipSwagger(lines, openIndex) };
260
+ default:
261
+ return null;
262
+ }
263
+ }
264
+ /** `{% code title lineNumbers overflow %}` wrapping a fence → fence + info. */
265
+ function transformCodeBlock(a, body) {
266
+ // Body holds a normal fenced code block. Fold title/lineNumbers into the
267
+ // fence info string (Dogsbay reads `title="…"` and `{…}` attrs there).
268
+ const text = body.join("\n");
269
+ const fenceMatch = text.match(/^(\s*)(`{3,}|~{3,})([^\n]*)\n([\s\S]*?)\n\1\2\s*$/);
270
+ const extra = {};
271
+ if (a.title)
272
+ extra.title = a.title;
273
+ if (a.lineNumbers === "true")
274
+ extra.lineNumbers = "true";
275
+ if (!fenceMatch) {
276
+ // No inner fence — wrap the raw body in one.
277
+ const info = a.title ? ` title="${a.title}"` : "";
278
+ return "```" + info + "\n" + text + "\n```";
279
+ }
280
+ const [, indent, ticks, lang, code] = fenceMatch;
281
+ const attrs = Object.keys(extra).length
282
+ ? " " + Object.entries(extra).map(([k, v]) => `${k}="${v}"`).join(" ")
283
+ : "";
284
+ return `${indent}${ticks}${lang.trim()}${attrs}\n${code}\n${indent}${ticks}`;
285
+ }
286
+ /** `{% content-ref url="x" %}[label](x){% endcontent-ref %}` → link-card. */
287
+ function transformContentRef(a, body) {
288
+ const url = a.url ?? "";
289
+ // Body usually holds a fallback `[label](url)`. Prefer its label.
290
+ const linkMatch = body.join("\n").match(/\[([^\]]*)\]\(([^)]+)\)/);
291
+ const label = linkMatch?.[1] || url;
292
+ if (!url)
293
+ return body.join("\n");
294
+ // Heading-target refs (url has #frag) are plain links in GitBook's own
295
+ // normalization; keep those as links, page refs as link-cards.
296
+ if (url.includes("#"))
297
+ return `[${label}](${url})`;
298
+ return `:::link-card{href="${url}"}\n${label}\n:::`;
299
+ }
300
+ /** `{% embed url="x" %}caption{% endembed %}` → link (caption or url). */
301
+ function transformEmbed(a, body) {
302
+ const url = a.url ?? "";
303
+ const caption = body.join(" ").trim();
304
+ if (!url)
305
+ return caption;
306
+ return `[${caption || url}](${url})`;
307
+ }
308
+ /** `{% file src="x" %}caption{% endfile %}` → download link. */
309
+ function transformFile(a, body) {
310
+ const src = a.src ?? "";
311
+ const caption = body.join(" ").trim();
312
+ if (!src)
313
+ return caption;
314
+ return `[${caption || src.split("/").pop() || "file"}](${src})`;
315
+ }
316
+ /** `{% openapi src path method %}` → :::api-endpoint placeholder. */
317
+ function transformOpenapi(a, body) {
318
+ const attrs = {};
319
+ if (a.src)
320
+ attrs.spec = a.src;
321
+ if (a.path)
322
+ attrs.path = a.path;
323
+ if (a.method)
324
+ attrs.method = a.method;
325
+ const fallback = body.join("\n").trim();
326
+ const inner = fallback ? `\n${fallback}\n` : "\n";
327
+ return `:::api-endpoint${attrBlock(attrs)}${inner}:::`;
328
+ }
329
+ /** Legacy `{% swagger %}` + nested `{% swagger-* %}` → api-endpoint stub. */
330
+ function transformSwagger(a, lines, openIndex) {
331
+ const attrs = {};
332
+ if (a.baseUrl)
333
+ attrs.baseUrl = a.baseUrl;
334
+ if (a.path)
335
+ attrs.path = a.path;
336
+ if (a.method)
337
+ attrs.method = a.method;
338
+ if (a.summary)
339
+ attrs.summary = a.summary;
340
+ return `:::api-endpoint${attrBlock(attrs)}\n:::`;
341
+ }
342
+ /** Skip a whole `{% swagger %}…{% endswagger %}` span (nested tags included). */
343
+ function skipSwagger(lines, openIndex) {
344
+ let j = openIndex + 1;
345
+ while (j < lines.length && !/^\s*\{%\s*endswagger\s*%\}/.test(lines[j]))
346
+ j++;
347
+ return j < lines.length ? j + 1 : j;
348
+ }
349
+ // ── Content-line inline transforms ────────────────────────────────────────
350
+ /**
351
+ * Rewrite inline GitBook constructs on a content line:
352
+ * - `{% include "path" %}` → kept verbatim (Dogsbay Minja resolves it)
353
+ * - `{% page-ref page="x" %}` → link
354
+ * - `<figure><img …><figcaption>…</figcaption></figure>` → image + caption
355
+ * - `data-gb-custom-inline` emoji spans → the emoji text
356
+ *
357
+ * Everything else (bold/italic/links/`<table>`/`<mark>`/inline `<img>`)
358
+ * is valid Dogsbay-MD as-is and passes through untouched.
359
+ */
360
+ function transformContentLine(line, ledger, lineNo) {
361
+ let out = line;
362
+ // page-ref → link (leaf inline tag).
363
+ out = out.replace(/\{%\s*page-ref\s+page="([^"]+)"\s*%\}/g, (_m, p) => {
364
+ const label = String(p).replace(/\.md$/, "").split("/").pop() || p;
365
+ return `[${label}](${p})`;
366
+ });
367
+ // `{% include "…" %}` stays verbatim — Dogsbay's Minja include resolves
368
+ // it at build time (mirrored fragments), same as the AsciiDoc pipeline.
369
+ // (No rewrite; listed here so the intent is explicit.)
370
+ void INCLUDE_RE;
371
+ // Block-image figure → markdown image, caption kept on its own line.
372
+ // Parse the <img> tag and pull src/alt order-independently — GitBook
373
+ // emits both `<img src alt>` and `<img alt src>`, and a positional
374
+ // regex dropped the alt whenever alt came first (review #7).
375
+ out = out.replace(/<figure>\s*(<img\s+[^>]*>)\s*<figcaption>(?:<p>)?([\s\S]*?)(?:<\/p>)?<\/figcaption>\s*<\/figure>/g, (_m, imgTag, cap = "") => {
376
+ const src = imgTag.match(/\bsrc="([^"]*)"/)?.[1] ?? "";
377
+ const alt = imgTag.match(/\balt="([^"]*)"/)?.[1] ?? "";
378
+ const caption = String(cap).trim();
379
+ const img = `![${alt}](${src})`;
380
+ return caption ? `${img}\n\n_${caption}_` : img;
381
+ });
382
+ // data-gb-custom-inline emoji span → the emoji glyph child.
383
+ out = out.replace(/<span[^>]*data-gb-custom-inline[^>]*data-tag="emoji"[^>]*>([^<]*)<\/span>/g, (_m, glyph) => String(glyph));
384
+ return out;
385
+ }
386
+ // ── Render region tree with depth-aware fences ────────────────────────────
387
+ /** Longest run of `:` in a line-start `:::…` directive fence within text. */
388
+ function longestColonFence(text) {
389
+ let max = 0;
390
+ for (const line of text.split("\n")) {
391
+ const m = line.match(/^(:{3,})/);
392
+ if (m)
393
+ max = Math.max(max, m[1].length);
394
+ }
395
+ return max;
396
+ }
397
+ /**
398
+ * Fence length for a directive node: strictly longer than every `:::`
399
+ * fence in its inner content, whether that content is a nested `dir`
400
+ * child OR a TEXT node that already holds a `:::` directive (link-card /
401
+ * api-endpoint, emitted by consumeSpecialBlock for content-ref / openapi
402
+ * / swagger). Ignoring the text case let a callout wrapping a content-ref
403
+ * get an equal-length fence and close early (review #1).
404
+ */
405
+ function fenceLen(node) {
406
+ let innerMax = 0;
407
+ for (const c of node.children) {
408
+ innerMax = Math.max(innerMax, c.kind === "dir" ? fenceLen(c) : longestColonFence(c.text));
409
+ }
410
+ return Math.max(3, innerMax + 1);
411
+ }
412
+ function renderNodes(nodes, depth) {
413
+ const parts = [];
414
+ for (const n of nodes) {
415
+ if (n.kind === "text") {
416
+ parts.push(n.text);
417
+ }
418
+ else {
419
+ const colons = ":".repeat(fenceLen(n));
420
+ const inner = renderNodes(n.children, depth + 1).trim();
421
+ parts.push(`${colons}${n.name}${n.attrs}\n${inner}\n${colons}`);
422
+ }
423
+ }
424
+ // Join preserving blank-line paragraph separation; collapse >2 blanks.
425
+ return parts.join("\n").replace(/\n{3,}/g, "\n\n");
426
+ }
427
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@dogsbay/format-gitbook",
3
+ "version": "0.2.0-beta.101",
4
+ "description": "GitBook format plugin for Dogsbay — imports GitBook Git Sync (and legacy gitbook-cli) corpora into TreeNode[] by translating the Git Sync markdown dialect to Dogsbay-MD.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./cli": {
14
+ "types": "./dist/cli.d.ts",
15
+ "import": "./dist/cli.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "dependencies": {
23
+ "yaml": "^2.9.0",
24
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.101",
25
+ "@dogsbay/types": "0.2.0-beta.101"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^25.9.5",
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.1.10"
31
+ },
32
+ "license": "MIT",
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
37
+ }
38
+ }