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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuartz",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Obsidian-compatible markdown pipeline for Next.js",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -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: $x^2$")
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
- return { slug, filePath, frontmatter: data as Frontmatter, raw }
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) => a.slug.localeCompare(b.slug))
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 files; alphabetically within each group
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)