mdzilla 0.0.2 → 0.0.4
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/_chunks/exporter.mjs +74 -23
- package/dist/cli/main.mjs +2 -2
- package/dist/index.d.mts +17 -11
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { basename, dirname, extname, join } from "node:path";
|
|
3
|
-
import { parseMeta, renderToText } from "md4x";
|
|
3
|
+
import { parseMeta, renderToMarkdown, renderToText } from "md4x";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
//#region src/docs/manager.ts
|
|
@@ -279,6 +279,7 @@ async function _scanNav(dirPath, parentPath, options) {
|
|
|
279
279
|
if (draft && !options.drafts) continue;
|
|
280
280
|
const meta = applyNavigationOverride(parseMeta(await readFile(fullPath, "utf8")));
|
|
281
281
|
if (meta.navigation === false) continue;
|
|
282
|
+
const resolvedOrder = typeof meta.order === "number" ? meta.order : order;
|
|
282
283
|
const resolvedSlug = slug === "index" ? "" : slug;
|
|
283
284
|
const title = meta.title || humanizeSlug(slug) || "index";
|
|
284
285
|
const entryPath = resolvedSlug === "" ? parentPath === "/" ? "/" : parentPath : parentPath === "/" ? `/${resolvedSlug}` : `${parentPath}/${resolvedSlug}`;
|
|
@@ -287,7 +288,7 @@ async function _scanNav(dirPath, parentPath, options) {
|
|
|
287
288
|
slug: resolvedSlug,
|
|
288
289
|
path: entryPath,
|
|
289
290
|
title,
|
|
290
|
-
order,
|
|
291
|
+
order: resolvedOrder,
|
|
291
292
|
...meta.icon ? { icon: meta.icon } : {},
|
|
292
293
|
...meta.description ? { description: meta.description } : {},
|
|
293
294
|
...draft ? { draft: true } : {},
|
|
@@ -308,8 +309,10 @@ var DocsSourceFS = class extends DocsSource {
|
|
|
308
309
|
this.dir = dir;
|
|
309
310
|
}
|
|
310
311
|
async load() {
|
|
312
|
+
const tree = await scanNav(this.dir);
|
|
313
|
+
await applyNavManifest(tree, this.dir);
|
|
311
314
|
return {
|
|
312
|
-
tree
|
|
315
|
+
tree,
|
|
313
316
|
fileMap: await buildFileMap("/", this.dir)
|
|
314
317
|
};
|
|
315
318
|
}
|
|
@@ -341,6 +344,30 @@ async function buildFileMap(parentPath, dirPath) {
|
|
|
341
344
|
}
|
|
342
345
|
return map;
|
|
343
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Read `_navigation.json` manifest (exported by mdzilla) and apply its
|
|
349
|
+
* ordering to the scanned nav tree. Only reorders; does not add/remove entries.
|
|
350
|
+
*/
|
|
351
|
+
async function applyNavManifest(tree, dir) {
|
|
352
|
+
let manifest;
|
|
353
|
+
try {
|
|
354
|
+
manifest = JSON.parse(await readFile(join(dir, "_navigation.json"), "utf8"));
|
|
355
|
+
} catch {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
reorderTree(tree, manifest);
|
|
359
|
+
}
|
|
360
|
+
/** Recursively reorder tree entries to match manifest ordering. */
|
|
361
|
+
function reorderTree(entries, manifest) {
|
|
362
|
+
const pathIndex = new Map(manifest.map((m, i) => [m.path, i]));
|
|
363
|
+
entries.sort((a, b) => {
|
|
364
|
+
return (pathIndex.get(a.path) ?? Infinity) - (pathIndex.get(b.path) ?? Infinity);
|
|
365
|
+
});
|
|
366
|
+
for (const entry of entries) if (entry.children?.length) {
|
|
367
|
+
const manifestEntry = manifest.find((m) => m.path === entry.path);
|
|
368
|
+
if (manifestEntry?.children) reorderTree(entry.children, manifestEntry.children);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
344
371
|
//#endregion
|
|
345
372
|
//#region src/docs/sources/git.ts
|
|
346
373
|
var DocsSourceGit = class extends DocsSource {
|
|
@@ -763,25 +790,49 @@ async function npmProvider(input) {
|
|
|
763
790
|
}
|
|
764
791
|
//#endregion
|
|
765
792
|
//#region src/docs/exporter.ts
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
793
|
+
/** Paths to skip during export (generated by source, not actual docs) */
|
|
794
|
+
const IGNORED_PATHS = new Set(["/llms.txt", "/llms-full.txt"]);
|
|
795
|
+
/**
|
|
796
|
+
* Export documentation entries to a local filesystem directory as flat `.md` files.
|
|
797
|
+
*
|
|
798
|
+
* Each entry is written to `<dir>/<path>.md` (or `<dir>/<path>/index.md` for directory
|
|
799
|
+
* index pages). Navigation order is preserved via `order` frontmatter in pages and
|
|
800
|
+
* `.navigation.yml` files in directories.
|
|
801
|
+
*
|
|
802
|
+
* A `README.md` table of contents is generated at the root of the output directory.
|
|
803
|
+
*/
|
|
804
|
+
async function exportDocsToFS(manager, dir, options = {}) {
|
|
805
|
+
const rootEntry = manager.flat.find((f) => f.entry.path === "/");
|
|
806
|
+
const tocLines = [`# ${options.title ?? rootEntry?.entry.title ?? "Table of Contents"}`, ""];
|
|
807
|
+
const writtenFiles = /* @__PURE__ */ new Set();
|
|
808
|
+
const dirPaths = /* @__PURE__ */ new Set();
|
|
809
|
+
collectDirPaths(manager.tree, dirPaths);
|
|
810
|
+
for (const flat of manager.flat) {
|
|
811
|
+
if (options.filter ? !options.filter(flat) : flat.entry.page === false) continue;
|
|
812
|
+
if (IGNORED_PATHS.has(flat.entry.path)) continue;
|
|
813
|
+
let content = await manager.getContent(flat);
|
|
814
|
+
if (content === void 0) continue;
|
|
815
|
+
const cleanContent = options.plainText ? renderToText(content) : renderToMarkdown(content);
|
|
816
|
+
const filePath = flat.entry.path === "/" || dirPaths.has(flat.entry.path) ? flat.entry.path === "/" ? "/index.md" : `${flat.entry.path}/index.md` : flat.entry.path.endsWith(".md") ? flat.entry.path : `${flat.entry.path}.md`;
|
|
817
|
+
const dest = join(dir, filePath);
|
|
818
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
819
|
+
await writeFile(dest, cleanContent, "utf8");
|
|
820
|
+
writtenFiles.add(filePath.slice(1));
|
|
821
|
+
const indent = " ".repeat(flat.depth);
|
|
822
|
+
const desc = flat.entry.description ? `: ${flat.entry.description}` : "";
|
|
823
|
+
tocLines.push(`${indent}- [${flat.entry.title}](.${filePath})${desc}`);
|
|
824
|
+
}
|
|
825
|
+
let tocFile = options.tocFile ?? "README.md";
|
|
826
|
+
if (writtenFiles.has(tocFile)) tocFile = `_${tocFile}`;
|
|
827
|
+
await writeFile(join(dir, tocFile), tocLines.join("\n") + "\n", "utf8");
|
|
828
|
+
await writeFile(join(dir, "_navigation.json"), JSON.stringify(manager.tree, null, 2) + "\n", "utf8");
|
|
829
|
+
}
|
|
830
|
+
/** Collect all paths that are directories (have children in the tree). */
|
|
831
|
+
function collectDirPaths(entries, set) {
|
|
832
|
+
for (const entry of entries) if (entry.children?.length) {
|
|
833
|
+
set.add(entry.path);
|
|
834
|
+
collectDirPaths(entry.children, set);
|
|
784
835
|
}
|
|
785
|
-
}
|
|
836
|
+
}
|
|
786
837
|
//#endregion
|
|
787
|
-
export {
|
|
838
|
+
export { DocsSourceFS as a, DocsSourceGit as i, DocsSourceNpm as n, DocsSource as o, DocsSourceHTTP as r, DocsManager as s, exportDocsToFS as t };
|
package/dist/cli/main.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as DocsSourceFS, i as DocsSourceGit, n as DocsSourceNpm, r as DocsSourceHTTP, s as DocsManager, t as exportDocsToFS } from "../_chunks/exporter.mjs";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { basename } from "node:path";
|
|
5
5
|
import { parseMeta, renderToAnsi, renderToText } from "md4x";
|
|
@@ -765,7 +765,7 @@ async function main() {
|
|
|
765
765
|
const docs = new DocsManager(isURL ? new DocsSourceHTTP(docsDir) : docsDir.startsWith("gh:") ? new DocsSourceGit(docsDir) : docsDir.startsWith("npm:") ? new DocsSourceNpm(docsDir) : new DocsSourceFS(docsDir));
|
|
766
766
|
await docs.load();
|
|
767
767
|
if (exportDir) {
|
|
768
|
-
await
|
|
768
|
+
await exportDocsToFS(docs, exportDir, { plainText: plain });
|
|
769
769
|
console.log(`Exported ${docs.pages.length} pages to ${exportDir}`);
|
|
770
770
|
return;
|
|
771
771
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -144,18 +144,24 @@ declare class DocsManager {
|
|
|
144
144
|
//#endregion
|
|
145
145
|
//#region src/docs/exporter.d.ts
|
|
146
146
|
interface ExportOptions {
|
|
147
|
-
/**
|
|
148
|
-
|
|
147
|
+
/** Custom filter callback. Return false to skip an entry. Default: skip stubs (page === false) */
|
|
148
|
+
filter?: (entry: FlatEntry) => boolean;
|
|
149
149
|
/** Compile markdown to plain text using md4x. Default: false */
|
|
150
150
|
plainText?: boolean;
|
|
151
|
+
/** Filename for the generated table of contents. Default: "README.md" */
|
|
152
|
+
tocFile?: string;
|
|
153
|
+
/** Title for the table of contents. Default: root entry title or "Table of Contents" */
|
|
154
|
+
title?: string;
|
|
151
155
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Export documentation entries to a local filesystem directory as flat `.md` files.
|
|
158
|
+
*
|
|
159
|
+
* Each entry is written to `<dir>/<path>.md` (or `<dir>/<path>/index.md` for directory
|
|
160
|
+
* index pages). Navigation order is preserved via `order` frontmatter in pages and
|
|
161
|
+
* `.navigation.yml` files in directories.
|
|
162
|
+
*
|
|
163
|
+
* A `README.md` table of contents is generated at the root of the output directory.
|
|
164
|
+
*/
|
|
165
|
+
declare function exportDocsToFS(manager: DocsManager, dir: string, options?: ExportOptions): Promise<void>;
|
|
160
166
|
//#endregion
|
|
161
|
-
export {
|
|
167
|
+
export { DocsManager, DocsSource, DocsSourceFS, DocsSourceGit, type DocsSourceGitOptions, DocsSourceHTTP, type DocsSourceHTTPOptions, DocsSourceNpm, type DocsSourceNpmOptions, type ExportOptions, type FlatEntry, type NavEntry, exportDocsToFS };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export {
|
|
1
|
+
import { a as DocsSourceFS, i as DocsSourceGit, n as DocsSourceNpm, o as DocsSource, r as DocsSourceHTTP, s as DocsManager, t as exportDocsToFS } from "./_chunks/exporter.mjs";
|
|
2
|
+
export { DocsManager, DocsSource, DocsSourceFS, DocsSourceGit, DocsSourceHTTP, DocsSourceNpm, exportDocsToFS };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mdzilla",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "pi0/mdzilla",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@speed-highlight/core": "^1.2.14",
|
|
34
34
|
"giget": "^3.1.2",
|
|
35
|
-
"md4x": ">=0.0.
|
|
35
|
+
"md4x": ">=0.0.22",
|
|
36
36
|
"mdream": "^0.16.0",
|
|
37
37
|
"std-env": "4.0.0-rc.1"
|
|
38
38
|
},
|