nuartz 0.1.0 → 0.1.2
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/package.json +1 -1
- package/src/__tests__/markdown.test.ts +1 -1
- package/src/fs.ts +44 -4
- package/src/markdown.ts +1 -1
package/package.json
CHANGED
|
@@ -87,7 +87,7 @@ Content with #beta and #gamma`
|
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
it("renders LaTeX with KaTeX", async () => {
|
|
90
|
-
const result = await renderMarkdown("Inline math:
|
|
90
|
+
const result = await renderMarkdown("Inline math: $$x^2$$")
|
|
91
91
|
expect(result.html).toContain("katex")
|
|
92
92
|
})
|
|
93
93
|
|
package/src/fs.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface MarkdownFile {
|
|
|
8
8
|
filePath: string // absolute file path
|
|
9
9
|
frontmatter: Frontmatter
|
|
10
10
|
raw: string
|
|
11
|
+
mtime?: Date // File modification time
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -39,11 +40,22 @@ export async function getAllMarkdownFiles(
|
|
|
39
40
|
|
|
40
41
|
const relative = path.relative(contentDir, fullPath)
|
|
41
42
|
const slug = relative.replace(/\.md$/, "").replace(/\\/g, "/")
|
|
43
|
+
|
|
44
|
+
// Get file modification time
|
|
45
|
+
let mtime: Date | undefined
|
|
46
|
+
try {
|
|
47
|
+
const stat = await fs.stat(fullPath)
|
|
48
|
+
mtime = stat.mtime
|
|
49
|
+
} catch {
|
|
50
|
+
mtime = undefined
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
results.push({
|
|
43
54
|
slug,
|
|
44
55
|
filePath: fullPath,
|
|
45
56
|
frontmatter: data as Frontmatter,
|
|
46
57
|
raw,
|
|
58
|
+
mtime,
|
|
47
59
|
})
|
|
48
60
|
}
|
|
49
61
|
}
|
|
@@ -65,7 +77,14 @@ export async function getMarkdownBySlug(
|
|
|
65
77
|
try {
|
|
66
78
|
const raw = await fs.readFile(filePath, "utf-8")
|
|
67
79
|
const { data } = matter(raw)
|
|
68
|
-
|
|
80
|
+
let mtime: Date | undefined
|
|
81
|
+
try {
|
|
82
|
+
const stat = await fs.stat(filePath)
|
|
83
|
+
mtime = stat.mtime
|
|
84
|
+
} catch {
|
|
85
|
+
mtime = undefined
|
|
86
|
+
}
|
|
87
|
+
return { slug, filePath, frontmatter: data as Frontmatter, raw, mtime }
|
|
69
88
|
} catch {
|
|
70
89
|
return null
|
|
71
90
|
}
|
|
@@ -76,16 +95,30 @@ export interface FileTreeNode {
|
|
|
76
95
|
path: string
|
|
77
96
|
type: "file" | "folder"
|
|
78
97
|
children?: FileTreeNode[]
|
|
98
|
+
mtime?: Date // File modification time (for sorting)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface BuildFileTreeOptions {
|
|
102
|
+
/** Sort method: 'name' (alphabetical) or 'modified' (newest first) */
|
|
103
|
+
sortBy?: 'name' | 'modified'
|
|
79
104
|
}
|
|
80
105
|
|
|
81
106
|
/**
|
|
82
107
|
* Builds a nested file tree from a flat list of MarkdownFile entries.
|
|
83
108
|
*/
|
|
84
|
-
export function buildFileTree(files: MarkdownFile[]): FileTreeNode[] {
|
|
109
|
+
export function buildFileTree(files: MarkdownFile[], options?: BuildFileTreeOptions): FileTreeNode[] {
|
|
110
|
+
const { sortBy = 'name' } = options ?? {}
|
|
85
111
|
const root: FileTreeNode[] = []
|
|
86
112
|
const nodeMap = new Map<string, FileTreeNode>()
|
|
87
113
|
|
|
88
|
-
const sortedFiles = [...files].sort((a, b) =>
|
|
114
|
+
const sortedFiles = [...files].sort((a, b) => {
|
|
115
|
+
if (sortBy === 'modified') {
|
|
116
|
+
const timeA = a.mtime?.getTime() ?? 0
|
|
117
|
+
const timeB = b.mtime?.getTime() ?? 0
|
|
118
|
+
return timeB - timeA // Newest first
|
|
119
|
+
}
|
|
120
|
+
return a.slug.localeCompare(b.slug)
|
|
121
|
+
})
|
|
89
122
|
|
|
90
123
|
for (const file of sortedFiles) {
|
|
91
124
|
const parts = file.slug.split("/")
|
|
@@ -101,6 +134,7 @@ export function buildFileTree(files: MarkdownFile[]): FileTreeNode[] {
|
|
|
101
134
|
name: file.frontmatter.title ?? part,
|
|
102
135
|
path: file.slug,
|
|
103
136
|
type: "file",
|
|
137
|
+
mtime: file.mtime,
|
|
104
138
|
}
|
|
105
139
|
parentList.push(node)
|
|
106
140
|
} else {
|
|
@@ -115,10 +149,16 @@ export function buildFileTree(files: MarkdownFile[]): FileTreeNode[] {
|
|
|
115
149
|
}
|
|
116
150
|
}
|
|
117
151
|
|
|
118
|
-
// Sort each level: folders first, then
|
|
152
|
+
// Sort each level: folders first, then by name or modification time
|
|
119
153
|
function sortNodes(nodes: FileTreeNode[]): FileTreeNode[] {
|
|
120
154
|
nodes.sort((a, b) => {
|
|
121
155
|
if (a.type !== b.type) return a.type === "folder" ? -1 : 1
|
|
156
|
+
|
|
157
|
+
if (sortBy === 'modified') {
|
|
158
|
+
const timeA = a.mtime?.getTime() ?? 0
|
|
159
|
+
const timeB = b.mtime?.getTime() ?? 0
|
|
160
|
+
return timeB - timeA // Newest first
|
|
161
|
+
}
|
|
122
162
|
return a.name.localeCompare(b.name, undefined, { sensitivity: "base" })
|
|
123
163
|
})
|
|
124
164
|
for (const node of nodes) {
|
package/src/markdown.ts
CHANGED
|
@@ -86,7 +86,7 @@ export async function renderMarkdown(
|
|
|
86
86
|
.use(remarkFrontmatter, ["yaml", "toml"])
|
|
87
87
|
.use(remarkObsidianComment)
|
|
88
88
|
.use(remarkGfm)
|
|
89
|
-
.use(remarkMath)
|
|
89
|
+
.use(remarkMath, { singleDollarTextMath: false })
|
|
90
90
|
.use(remarkBreaks)
|
|
91
91
|
.use(remarkWikilink, { baseUrl, resolve: resolveLink, knownSlugs })
|
|
92
92
|
.use(remarkCallout)
|