@pruddiman/mdmirror 0.1.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.
Files changed (60) hide show
  1. package/README.md +1 -0
  2. package/dist/build/builder.d.ts +41 -0
  3. package/dist/build/builder.js +108 -0
  4. package/dist/build/builder.js.map +1 -0
  5. package/dist/cli/build.d.ts +14 -0
  6. package/dist/cli/build.js +116 -0
  7. package/dist/cli/build.js.map +1 -0
  8. package/dist/cli/index.d.ts +6 -0
  9. package/dist/cli/index.js +104 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/serve.d.ts +15 -0
  12. package/dist/cli/serve.js +233 -0
  13. package/dist/cli/serve.js.map +1 -0
  14. package/dist/core/discovery.d.ts +12 -0
  15. package/dist/core/discovery.js +91 -0
  16. package/dist/core/discovery.js.map +1 -0
  17. package/dist/core/navigation.d.ts +12 -0
  18. package/dist/core/navigation.js +155 -0
  19. package/dist/core/navigation.js.map +1 -0
  20. package/dist/core/slug.d.ts +47 -0
  21. package/dist/core/slug.js +132 -0
  22. package/dist/core/slug.js.map +1 -0
  23. package/dist/core/title.d.ts +22 -0
  24. package/dist/core/title.js +43 -0
  25. package/dist/core/title.js.map +1 -0
  26. package/dist/render/highlight.d.ts +23 -0
  27. package/dist/render/highlight.js +36 -0
  28. package/dist/render/highlight.js.map +1 -0
  29. package/dist/render/mermaid.d.ts +13 -0
  30. package/dist/render/mermaid.js +66 -0
  31. package/dist/render/mermaid.js.map +1 -0
  32. package/dist/render/pipeline.d.ts +32 -0
  33. package/dist/render/pipeline.js +141 -0
  34. package/dist/render/pipeline.js.map +1 -0
  35. package/dist/search/index.d.ts +19 -0
  36. package/dist/search/index.js +43 -0
  37. package/dist/search/index.js.map +1 -0
  38. package/dist/server/reload.d.ts +23 -0
  39. package/dist/server/reload.js +80 -0
  40. package/dist/server/reload.js.map +1 -0
  41. package/dist/server/server.d.ts +22 -0
  42. package/dist/server/server.js +137 -0
  43. package/dist/server/server.js.map +1 -0
  44. package/dist/server/watcher.d.ts +24 -0
  45. package/dist/server/watcher.js +62 -0
  46. package/dist/server/watcher.js.map +1 -0
  47. package/dist/theme/index.d.ts +8 -0
  48. package/dist/theme/index.js +19 -0
  49. package/dist/theme/index.js.map +1 -0
  50. package/dist/theme/layout.d.ts +37 -0
  51. package/dist/theme/layout.js +141 -0
  52. package/dist/theme/layout.js.map +1 -0
  53. package/dist/theme/scripts.d.ts +29 -0
  54. package/dist/theme/scripts.js +159 -0
  55. package/dist/theme/scripts.js.map +1 -0
  56. package/dist/theme/styles.css +462 -0
  57. package/dist/types.d.ts +99 -0
  58. package/dist/types.js +6 -0
  59. package/dist/types.js.map +1 -0
  60. package/package.json +76 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Recursive file discovery module.
3
+ * Accepts a folder path, recursively finds all .md and .txt files,
4
+ * and returns partially-populated Document objects.
5
+ */
6
+ import type { Document } from "../types.js";
7
+ /**
8
+ * Discover all supported files in a directory recursively.
9
+ * Returns Document objects with sourcePath, absolutePath, fileType, and isIndex populated.
10
+ * Other fields (slug, title, content, renderedHtml, sortKey) are left as empty strings.
11
+ */
12
+ export declare function discoverFiles(rootPath: string): Promise<Document[]>;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Recursive file discovery module.
3
+ * Accepts a folder path, recursively finds all .md and .txt files,
4
+ * and returns partially-populated Document objects.
5
+ */
6
+ import { readdir, stat } from "node:fs/promises";
7
+ import { resolve, relative, extname, basename } from "node:path";
8
+ const SUPPORTED_EXTENSIONS = new Set([".md", ".txt"]);
9
+ const INDEX_FILENAMES = new Set(["index.md", "readme.md", "overview.md"]);
10
+ /**
11
+ * Discover all supported files in a directory recursively.
12
+ * Returns Document objects with sourcePath, absolutePath, fileType, and isIndex populated.
13
+ * Other fields (slug, title, content, renderedHtml, sortKey) are left as empty strings.
14
+ */
15
+ export async function discoverFiles(rootPath) {
16
+ const absoluteRoot = resolve(rootPath);
17
+ // Validate path exists
18
+ let rootStat;
19
+ try {
20
+ rootStat = await stat(absoluteRoot);
21
+ }
22
+ catch {
23
+ throw new Error(`Path does not exist: ${absoluteRoot}`);
24
+ }
25
+ // Handle single file input
26
+ if (rootStat.isFile()) {
27
+ const ext = extname(absoluteRoot).toLowerCase();
28
+ if (!SUPPORTED_EXTENSIONS.has(ext)) {
29
+ throw new Error(`File is not a supported type (.md, .txt): ${absoluteRoot}`);
30
+ }
31
+ const fileName = basename(absoluteRoot);
32
+ return [
33
+ {
34
+ sourcePath: fileName,
35
+ absolutePath: absoluteRoot,
36
+ slug: "",
37
+ title: "",
38
+ description: "",
39
+ content: "",
40
+ renderedHtml: "",
41
+ fileType: ext.slice(1),
42
+ isIndex: INDEX_FILENAMES.has(fileName.toLowerCase()),
43
+ sortKey: "",
44
+ },
45
+ ];
46
+ }
47
+ if (!rootStat.isDirectory()) {
48
+ throw new Error(`Path is not a file or directory: ${absoluteRoot}`);
49
+ }
50
+ const documents = [];
51
+ await walkDirectory(absoluteRoot, absoluteRoot, documents);
52
+ if (documents.length === 0) {
53
+ throw new Error(`No .md or .txt files found in ${absoluteRoot}`);
54
+ }
55
+ return documents;
56
+ }
57
+ /**
58
+ * Recursively walk a directory and collect Document objects.
59
+ */
60
+ async function walkDirectory(currentPath, rootPath, documents) {
61
+ const entries = await readdir(currentPath, { withFileTypes: true });
62
+ for (const entry of entries) {
63
+ const fullPath = resolve(currentPath, entry.name);
64
+ if (entry.isDirectory()) {
65
+ // Skip hidden directories
66
+ if (entry.name.startsWith("."))
67
+ continue;
68
+ await walkDirectory(fullPath, rootPath, documents);
69
+ }
70
+ else if (entry.isFile()) {
71
+ const ext = extname(entry.name).toLowerCase();
72
+ if (!SUPPORTED_EXTENSIONS.has(ext))
73
+ continue;
74
+ const sourcePath = relative(rootPath, fullPath);
75
+ const fileName = basename(entry.name).toLowerCase();
76
+ documents.push({
77
+ sourcePath,
78
+ absolutePath: fullPath,
79
+ slug: "",
80
+ title: "",
81
+ description: "",
82
+ content: "",
83
+ renderedHtml: "",
84
+ fileType: ext.slice(1),
85
+ isIndex: INDEX_FILENAMES.has(fileName),
86
+ sortKey: "",
87
+ });
88
+ }
89
+ }
90
+ }
91
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/core/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Navigation tree builder.
3
+ * Takes Document[] and builds a NavigationTree with NavigationNode hierarchy
4
+ * mirroring folder structure.
5
+ */
6
+ import type { Document, NavigationTree } from "../types.js";
7
+ /**
8
+ * Build a NavigationTree from a list of documents.
9
+ * Creates a hierarchy of sections (folders) and pages (files),
10
+ * sorted by numeric prefix then alphabetically.
11
+ */
12
+ export declare function buildNavigationTree(documents: Document[]): NavigationTree;
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Navigation tree builder.
3
+ * Takes Document[] and builds a NavigationTree with NavigationNode hierarchy
4
+ * mirroring folder structure.
5
+ */
6
+ import { dirname, basename } from "node:path";
7
+ import { generateSortKey } from "./slug.js";
8
+ import { humanizeFilename } from "./title.js";
9
+ /**
10
+ * Build a NavigationTree from a list of documents.
11
+ * Creates a hierarchy of sections (folders) and pages (files),
12
+ * sorted by numeric prefix then alphabetically.
13
+ */
14
+ export function buildNavigationTree(documents) {
15
+ // Create root node
16
+ const root = {
17
+ label: "",
18
+ slug: "",
19
+ sortKey: "",
20
+ children: new Map(),
21
+ pages: [],
22
+ indexDocument: null,
23
+ };
24
+ // Place each document into the tree
25
+ for (const doc of documents) {
26
+ const dir = dirname(doc.sourcePath);
27
+ const segments = dir === "." ? [] : dir.split(/[/\\]/);
28
+ // Navigate to the correct folder node, creating intermediate nodes as needed
29
+ let current = root;
30
+ let currentSlug = "";
31
+ for (const segment of segments) {
32
+ currentSlug = currentSlug ? `${currentSlug}/${segment}` : segment;
33
+ if (!current.children.has(segment)) {
34
+ current.children.set(segment, {
35
+ label: humanizeFilename(segment + ".md"), // reuse humanize logic
36
+ slug: currentSlug,
37
+ sortKey: generateSortKey(segment),
38
+ children: new Map(),
39
+ pages: [],
40
+ indexDocument: null,
41
+ });
42
+ }
43
+ current = current.children.get(segment);
44
+ }
45
+ // Place the document
46
+ if (doc.isIndex) {
47
+ current.indexDocument = doc;
48
+ }
49
+ else {
50
+ current.pages.push(doc);
51
+ }
52
+ }
53
+ // Resolve index documents using priority chain:
54
+ // index.md > readme.md > overview.md > first file alphabetically
55
+ const INDEX_PRIORITY = ["index.md", "readme.md", "overview.md"];
56
+ function resolveIndexDocuments(node) {
57
+ // Recurse into children first
58
+ for (const child of node.children.values()) {
59
+ resolveIndexDocuments(child);
60
+ }
61
+ // Collect all candidate pages (existing index doc + regular pages)
62
+ const allPages = [...node.pages];
63
+ if (node.indexDocument) {
64
+ allPages.unshift(node.indexDocument);
65
+ node.indexDocument = null;
66
+ }
67
+ if (allPages.length === 0)
68
+ return;
69
+ // Try priority filenames first
70
+ let chosen = null;
71
+ for (const target of INDEX_PRIORITY) {
72
+ chosen =
73
+ allPages.find((d) => basename(d.sourcePath).toLowerCase() === target) ?? null;
74
+ if (chosen)
75
+ break;
76
+ }
77
+ // Fallback: first page alphabetically by filename
78
+ if (!chosen) {
79
+ allPages.sort((a, b) => basename(a.sourcePath)
80
+ .toLowerCase()
81
+ .localeCompare(basename(b.sourcePath).toLowerCase()));
82
+ chosen = allPages[0];
83
+ }
84
+ // Set as index, remove from pages list
85
+ node.indexDocument = chosen;
86
+ node.pages = allPages.filter((d) => d !== chosen);
87
+ }
88
+ resolveIndexDocuments(root);
89
+ // Convert tree to NavigationNode[]
90
+ const flatPages = [];
91
+ function convertNode(node, depth) {
92
+ const result = [];
93
+ // Add section nodes for child folders
94
+ for (const [_name, child] of node.children) {
95
+ const sectionSlug = child.indexDocument ? child.indexDocument.slug : child.slug;
96
+ const childNavNodes = convertNode(child, depth + 1);
97
+ const section = {
98
+ label: child.label,
99
+ slug: sectionSlug,
100
+ type: "section",
101
+ children: childNavNodes,
102
+ sortKey: child.sortKey,
103
+ isActive: false,
104
+ indexDocument: child.indexDocument,
105
+ depth,
106
+ };
107
+ if (child.indexDocument) {
108
+ flatPages.push(child.indexDocument);
109
+ }
110
+ result.push(section);
111
+ }
112
+ // Add page nodes for files in this folder
113
+ for (const doc of node.pages) {
114
+ flatPages.push(doc);
115
+ result.push({
116
+ label: doc.title,
117
+ slug: doc.slug,
118
+ type: "page",
119
+ children: [],
120
+ sortKey: doc.sortKey,
121
+ isActive: false,
122
+ indexDocument: null,
123
+ depth,
124
+ });
125
+ }
126
+ // Sort: numeric prefixes first (numerically), then alphabetical
127
+ result.sort((a, b) => {
128
+ const aIsNumeric = a.sortKey.match(/^\d+$/);
129
+ const bIsNumeric = b.sortKey.match(/^\d+$/);
130
+ // Numeric-prefixed items come before non-prefixed
131
+ if (aIsNumeric && !bIsNumeric)
132
+ return -1;
133
+ if (!aIsNumeric && bIsNumeric)
134
+ return 1;
135
+ // Both numeric: compare numerically
136
+ if (aIsNumeric && bIsNumeric) {
137
+ return a.sortKey.localeCompare(b.sortKey);
138
+ }
139
+ // Both non-numeric: compare alphabetically
140
+ return a.sortKey.localeCompare(b.sortKey);
141
+ });
142
+ return result;
143
+ }
144
+ // Handle root-level index document
145
+ if (root.indexDocument) {
146
+ flatPages.unshift(root.indexDocument);
147
+ }
148
+ const rootNodes = convertNode(root, 0);
149
+ return {
150
+ root: rootNodes,
151
+ flatPages,
152
+ totalPages: flatPages.length,
153
+ };
154
+ }
155
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/core/navigation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * URL slug generation module.
3
+ * Converts file/folder paths to clean URL slugs.
4
+ * Handles spaces, special characters, numeric prefixes, and slug collisions.
5
+ */
6
+ /**
7
+ * Strip the numeric prefix from a filename/folder name.
8
+ * "01-intro" -> "intro", "setup" -> "setup"
9
+ */
10
+ export declare function stripNumericPrefix(name: string): string;
11
+ /**
12
+ * Extract the numeric prefix value for sorting.
13
+ * "01-intro" -> 1, "setup" -> Infinity (sorts after numeric-prefixed items)
14
+ */
15
+ export declare function extractNumericPrefix(name: string): number;
16
+ /**
17
+ * Generate a sort key from a filename.
18
+ * Returns the numeric prefix (zero-padded) or the name for alphabetical sorting.
19
+ */
20
+ export declare function generateSortKey(name: string): string;
21
+ /**
22
+ * Generate a clean URL slug from a document's source path.
23
+ *
24
+ * Rules:
25
+ * - Strip file extension
26
+ * - Strip numeric prefixes from each path segment
27
+ * - index.md / README.md map to the folder slug (e.g., guides/index.md -> guides)
28
+ * - Root index.md maps to empty string (root page)
29
+ */
30
+ export declare function generateSlug(sourcePath: string): string;
31
+ /**
32
+ * Detect slug collisions in a set of documents and warn about them.
33
+ * Returns a map of slug -> source paths for any collisions.
34
+ */
35
+ export declare function detectSlugCollisions(slugMap: Map<string, string[]>): Map<string, string[]>;
36
+ /**
37
+ * Disambiguate slug collisions by appending numeric suffixes.
38
+ * When two or more documents produce the same slug, all but the first
39
+ * get a "-2", "-3", etc. suffix appended.
40
+ *
41
+ * Takes an array of objects with { slug, sourcePath } and mutates
42
+ * the slug property in-place.
43
+ */
44
+ export declare function disambiguateSlugs(items: Array<{
45
+ slug: string;
46
+ sourcePath: string;
47
+ }>): void;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * URL slug generation module.
3
+ * Converts file/folder paths to clean URL slugs.
4
+ * Handles spaces, special characters, numeric prefixes, and slug collisions.
5
+ */
6
+ import { dirname, basename, extname } from "node:path";
7
+ /** Regex to detect numeric prefixes like "01-", "02-", "10-" */
8
+ const NUMERIC_PREFIX_RE = /^(\d+)-(.+)$/;
9
+ /**
10
+ * Strip the numeric prefix from a filename/folder name.
11
+ * "01-intro" -> "intro", "setup" -> "setup"
12
+ */
13
+ export function stripNumericPrefix(name) {
14
+ const match = name.match(NUMERIC_PREFIX_RE);
15
+ return match ? match[2] : name;
16
+ }
17
+ /**
18
+ * Extract the numeric prefix value for sorting.
19
+ * "01-intro" -> 1, "setup" -> Infinity (sorts after numeric-prefixed items)
20
+ */
21
+ export function extractNumericPrefix(name) {
22
+ const match = name.match(NUMERIC_PREFIX_RE);
23
+ return match ? parseInt(match[1], 10) : Infinity;
24
+ }
25
+ /**
26
+ * Generate a sort key from a filename.
27
+ * Returns the numeric prefix (zero-padded) or the name for alphabetical sorting.
28
+ */
29
+ export function generateSortKey(name) {
30
+ const match = name.match(NUMERIC_PREFIX_RE);
31
+ if (match) {
32
+ // Zero-pad to 10 digits for consistent numeric sorting
33
+ return match[1].padStart(10, "0");
34
+ }
35
+ // For non-numeric names, use the lowercase name for alphabetical sorting
36
+ return name.toLowerCase();
37
+ }
38
+ /**
39
+ * Convert a name (filename or folder) into a URL-safe slug segment.
40
+ * Handles Unicode by normalizing to NFKD and stripping combining diacritics,
41
+ * then falls back to percent-encoding for characters that survive that step.
42
+ */
43
+ function slugifySegment(name) {
44
+ // Strip numeric prefix
45
+ const stripped = stripNumericPrefix(name);
46
+ const transliterated = stripped
47
+ // NFKD decomposes accented chars into base letter + combining mark
48
+ .normalize("NFKD")
49
+ // Remove combining diacritical marks (accents, tildes, etc.)
50
+ .replace(/[\u0300-\u036f]/g, "")
51
+ .toLowerCase()
52
+ // Replace spaces and underscores with hyphens
53
+ .replace(/[\s_]+/g, "-")
54
+ // Remove any remaining non-ASCII characters (CJK, emoji, etc.)
55
+ // by replacing them with a hyphen so they don't silently vanish
56
+ // eslint-disable-next-line no-control-regex
57
+ .replace(/[^\x00-\x7f]/g, "-")
58
+ // Remove any remaining non-URL-safe ASCII characters (keep letters, numbers, hyphens)
59
+ .replace(/[^a-z0-9-]/g, "")
60
+ // Collapse multiple hyphens
61
+ .replace(/-+/g, "-")
62
+ // Trim leading/trailing hyphens
63
+ .replace(/^-|-$/g, "");
64
+ return transliterated;
65
+ }
66
+ /**
67
+ * Generate a clean URL slug from a document's source path.
68
+ *
69
+ * Rules:
70
+ * - Strip file extension
71
+ * - Strip numeric prefixes from each path segment
72
+ * - index.md / README.md map to the folder slug (e.g., guides/index.md -> guides)
73
+ * - Root index.md maps to empty string (root page)
74
+ */
75
+ export function generateSlug(sourcePath) {
76
+ const ext = extname(sourcePath);
77
+ const withoutExt = sourcePath.slice(0, -ext.length);
78
+ // Split into path segments
79
+ const dir = dirname(withoutExt);
80
+ const file = basename(withoutExt);
81
+ // Check if this is an index/readme file
82
+ const isIndex = ["index", "readme"].includes(file.toLowerCase());
83
+ // Process directory segments
84
+ const dirSegments = dir === "." ? [] : dir.split(/[/\\]/).map(slugifySegment).filter(Boolean);
85
+ if (isIndex) {
86
+ // index.md / README.md -> folder slug or root
87
+ return dirSegments.join("/");
88
+ }
89
+ // Regular file -> add slugified filename
90
+ const fileSlug = slugifySegment(file);
91
+ return [...dirSegments, fileSlug].filter(Boolean).join("/");
92
+ }
93
+ /**
94
+ * Detect slug collisions in a set of documents and warn about them.
95
+ * Returns a map of slug -> source paths for any collisions.
96
+ */
97
+ export function detectSlugCollisions(slugMap) {
98
+ const collisions = new Map();
99
+ for (const [slug, paths] of slugMap) {
100
+ if (paths.length > 1) {
101
+ collisions.set(slug, paths);
102
+ }
103
+ }
104
+ return collisions;
105
+ }
106
+ /**
107
+ * Disambiguate slug collisions by appending numeric suffixes.
108
+ * When two or more documents produce the same slug, all but the first
109
+ * get a "-2", "-3", etc. suffix appended.
110
+ *
111
+ * Takes an array of objects with { slug, sourcePath } and mutates
112
+ * the slug property in-place.
113
+ */
114
+ export function disambiguateSlugs(items) {
115
+ const slugMap = new Map();
116
+ for (const item of items) {
117
+ const existing = slugMap.get(item.slug) || [];
118
+ existing.push(item);
119
+ slugMap.set(item.slug, existing);
120
+ }
121
+ for (const [slug, owners] of slugMap) {
122
+ if (owners.length <= 1)
123
+ continue;
124
+ // Sort by sourcePath for deterministic disambiguation
125
+ owners.sort((a, b) => a.sourcePath.localeCompare(b.sourcePath));
126
+ // First one keeps the original slug, subsequent ones get suffixes
127
+ for (let i = 1; i < owners.length; i++) {
128
+ owners[i].slug = `${slug}-${i + 1}`;
129
+ }
130
+ }
131
+ }
132
+ //# sourceMappingURL=slug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/core/slug.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Title extraction module.
3
+ * Parses markdown content to extract the first heading as the page title.
4
+ * Falls back to a humanized filename if no heading is found.
5
+ */
6
+ /**
7
+ * Extract the title from markdown content.
8
+ * Returns the text of the first heading found, or null if none exists.
9
+ */
10
+ export declare function extractTitleFromContent(content: string): string | null;
11
+ /**
12
+ * Convert a filename into a human-readable title.
13
+ * "getting-started.md" -> "Getting Started"
14
+ * "01-intro.md" -> "Intro"
15
+ * "my_cool_doc.txt" -> "My Cool Doc"
16
+ */
17
+ export declare function humanizeFilename(filename: string): string;
18
+ /**
19
+ * Get the title for a document.
20
+ * Tries to extract from content first, falls back to humanized filename.
21
+ */
22
+ export declare function getTitle(content: string, sourcePath: string): string;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Title extraction module.
3
+ * Parses markdown content to extract the first heading as the page title.
4
+ * Falls back to a humanized filename if no heading is found.
5
+ */
6
+ import { basename, extname } from "node:path";
7
+ import { stripNumericPrefix } from "./slug.js";
8
+ /** Regex to match a markdown heading (# Title) */
9
+ const HEADING_RE = /^#{1,6}\s+(.+)$/m;
10
+ /**
11
+ * Extract the title from markdown content.
12
+ * Returns the text of the first heading found, or null if none exists.
13
+ */
14
+ export function extractTitleFromContent(content) {
15
+ const match = content.match(HEADING_RE);
16
+ return match ? match[1].trim() : null;
17
+ }
18
+ /**
19
+ * Convert a filename into a human-readable title.
20
+ * "getting-started.md" -> "Getting Started"
21
+ * "01-intro.md" -> "Intro"
22
+ * "my_cool_doc.txt" -> "My Cool Doc"
23
+ */
24
+ export function humanizeFilename(filename) {
25
+ // Remove extension
26
+ const withoutExt = basename(filename, extname(filename));
27
+ // Strip numeric prefix
28
+ const stripped = stripNumericPrefix(withoutExt);
29
+ return (stripped
30
+ // Replace hyphens and underscores with spaces
31
+ .replace(/[-_]+/g, " ")
32
+ // Capitalize first letter of each word
33
+ .replace(/\b\w/g, (c) => c.toUpperCase())
34
+ .trim());
35
+ }
36
+ /**
37
+ * Get the title for a document.
38
+ * Tries to extract from content first, falls back to humanized filename.
39
+ */
40
+ export function getTitle(content, sourcePath) {
41
+ return extractTitleFromContent(content) || humanizeFilename(sourcePath);
42
+ }
43
+ //# sourceMappingURL=title.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title.js","sourceRoot":"","sources":["../../src/core/title.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,kDAAkD;AAClD,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,mBAAmB;IACnB,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEzD,uBAAuB;IACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAEhD,OAAO,CACL,QAAQ;QACN,8CAA8C;SAC7C,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;QACvB,uCAAuC;SACtC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACxC,IAAI,EAAE,CACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,UAAkB;IAC1D,OAAO,uBAAuB,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shiki syntax highlighting configuration.
3
+ * Exports the @shikijs/rehype plugin configuration for the rendering pipeline.
4
+ * Ensures mermaid blocks are excluded from syntax highlighting.
5
+ */
6
+ /**
7
+ * Get the configured Shiki rehype plugin.
8
+ * Uses github-light theme with lazy language loading.
9
+ * Mermaid blocks are excluded since they're handled by the mermaid plugin.
10
+ */
11
+ export declare function getShikiPlugin(): readonly [import("unified").Plugin<[import("@shikijs/rehype").RehypeShikiOptions], import("hast").Root>, {
12
+ readonly themes: {
13
+ readonly light: "github-light";
14
+ readonly dark: "github-dark";
15
+ };
16
+ readonly defaultColor: false;
17
+ readonly transformers: readonly [{
18
+ readonly name: "mdmirror:skip-mermaid";
19
+ readonly preprocess: (code: string, options: {
20
+ lang?: string;
21
+ }) => string;
22
+ }];
23
+ }];
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shiki syntax highlighting configuration.
3
+ * Exports the @shikijs/rehype plugin configuration for the rendering pipeline.
4
+ * Ensures mermaid blocks are excluded from syntax highlighting.
5
+ */
6
+ import rehypeShiki from "@shikijs/rehype";
7
+ /**
8
+ * Get the configured Shiki rehype plugin.
9
+ * Uses github-light theme with lazy language loading.
10
+ * Mermaid blocks are excluded since they're handled by the mermaid plugin.
11
+ */
12
+ export function getShikiPlugin() {
13
+ return [
14
+ rehypeShiki,
15
+ {
16
+ themes: {
17
+ light: "github-light",
18
+ dark: "github-dark",
19
+ },
20
+ defaultColor: false,
21
+ // Don't highlight mermaid blocks — they're handled separately
22
+ transformers: [
23
+ {
24
+ name: "mdmirror:skip-mermaid",
25
+ preprocess(code, options) {
26
+ if (options.lang === "mermaid") {
27
+ return false;
28
+ }
29
+ return code;
30
+ },
31
+ },
32
+ ],
33
+ },
34
+ ];
35
+ }
36
+ //# sourceMappingURL=highlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../src/render/highlight.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,WAAW;QACX;YACE,MAAM,EAAE;gBACN,KAAK,EAAE,cAAc;gBACrB,IAAI,EAAE,aAAa;aACpB;YACD,YAAY,EAAE,KAAK;YACnB,8DAA8D;YAC9D,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,uBAAuB;oBAC7B,UAAU,CAAC,IAAY,EAAE,OAA0B;wBACjD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;4BAC/B,OAAO,KAA0B,CAAC;wBACpC,CAAC;wBACD,OAAO,IAAI,CAAC;oBACd,CAAC;iBACF;aACF;SACF;KACO,CAAC;AACb,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Mermaid diagram rehype plugin.
3
+ * Detects fenced code blocks with lang="mermaid" and replaces them
4
+ * with <pre class="mermaid"> elements for client-side rendering.
5
+ */
6
+ import type { Root } from "hast";
7
+ import type { Plugin } from "unified";
8
+ /**
9
+ * Rehype plugin that transforms mermaid code blocks into renderable elements.
10
+ * Converts: <pre><code class="language-mermaid">...</code></pre>
11
+ * Into: <pre class="mermaid">...</pre>
12
+ */
13
+ export declare const rehypeMermaid: Plugin<[], Root>;