nuartz 0.1.1 → 0.1.3

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.
@@ -1,107 +0,0 @@
1
- import { visit } from "unist-util-visit"
2
- import type { Root, Text, PhrasingContent } from "mdast"
3
- import type { Plugin } from "unified"
4
-
5
- /**
6
- * Matches:
7
- * [[target]] → link to target, display "target"
8
- * [[target|alias]] → link to target, display "alias"
9
- * [[target#heading]] → link to target#heading
10
- * [[target#heading|alias]]
11
- * ![[image.png]] → embed (image or transclusion)
12
- */
13
- const WIKILINK_REGEX = /(!?)\[\[([^\[\]|#]+?)(?:#([^\[\]|]+?))?(?:\|([^\[\]]+?))?\]\]/g
14
-
15
- export interface WikilinkOptions {
16
- /** Base URL prepended to all wikilink hrefs. Default: '/' */
17
- baseUrl?: string
18
- /** Custom resolver: transforms raw target string into a URL path */
19
- resolve?: (target: string, heading?: string) => string
20
- /** Known slugs for dead-link detection. If provided, unresolved targets get class "broken". */
21
- knownSlugs?: Set<string>
22
- }
23
-
24
- export const remarkWikilink: Plugin<[WikilinkOptions?], Root> = (options = {}) => {
25
- const { baseUrl = "/", resolve, knownSlugs } = options
26
-
27
- const defaultResolve = (target: string, heading?: string): string => {
28
- const slug = target
29
- .toLowerCase()
30
- .replace(/\s+/g, "-")
31
- .replace(/[^\w-]/g, "")
32
- const hash = heading ? `#${heading.toLowerCase().replace(/\s+/g, "-")}` : ""
33
- return `${baseUrl}${slug}${hash}`
34
- }
35
-
36
- const resolveUrl = resolve
37
- ? (t: string, h?: string) => resolve(t, h)
38
- : defaultResolve
39
-
40
- return (tree, file) => {
41
- const outgoingLinks: string[] = []
42
-
43
- visit(tree, "text", (node: Text, index, parent) => {
44
- if (!parent || index === undefined) return
45
-
46
- const matches = [...node.value.matchAll(WIKILINK_REGEX)]
47
- if (!matches.length) return
48
-
49
- const nodes: PhrasingContent[] = []
50
- let lastIndex = 0
51
-
52
- for (const match of matches) {
53
- const [full, bang, target, heading, alias] = match
54
- const matchIndex = match.index!
55
-
56
- if (matchIndex > lastIndex) {
57
- nodes.push({ type: "text", value: node.value.slice(lastIndex, matchIndex) })
58
- }
59
-
60
- const href = resolveUrl(target, heading)
61
- const displayText = alias ?? (heading ? `${target} > ${heading}` : target)
62
-
63
- if (bang === "!") {
64
- const IMAGE_EXTS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".mp4"])
65
- const extMatch = target.match(/\.(\w+)$/)
66
- const isImage = extMatch ? IMAGE_EXTS.has("." + extMatch[1].toLowerCase()) : false
67
-
68
- nodes.push({
69
- type: "image",
70
- url: isImage ? `/api/content/${target}` : href,
71
- alt: displayText,
72
- data: { hProperties: { className: isImage ? "embed-image" : "embed-note", "data-embed": target } },
73
- })
74
- } else {
75
- outgoingLinks.push(target)
76
- const normalized = target.toLowerCase().replace(/\s+/g, "-").replace(/[^\w/-]/g, "")
77
- const isKnown = !knownSlugs || [...knownSlugs].some(
78
- (s) => s === normalized || s.endsWith("/" + normalized)
79
- )
80
- nodes.push({
81
- type: "link",
82
- url: href,
83
- data: {
84
- hProperties: {
85
- className: isKnown ? "wikilink" : "wikilink broken",
86
- "data-target": target,
87
- ...(heading ? { "data-heading": heading } : {}),
88
- },
89
- },
90
- children: [{ type: "text", value: displayText }],
91
- })
92
- }
93
-
94
- lastIndex = matchIndex + full.length
95
- }
96
-
97
- if (lastIndex < node.value.length) {
98
- nodes.push({ type: "text", value: node.value.slice(lastIndex) })
99
- }
100
-
101
- parent.children.splice(index, 1, ...nodes)
102
- })
103
-
104
- const existing = (file.data.links as string[] | undefined) ?? []
105
- file.data.links = [...new Set([...existing, ...outgoingLinks])]
106
- }
107
- }
package/src/search.ts DELETED
@@ -1,42 +0,0 @@
1
- import type { MarkdownFile } from "./fs.js"
2
-
3
- export interface SearchEntry {
4
- slug: string
5
- title: string
6
- content: string
7
- tags: string[]
8
- description?: string
9
- }
10
-
11
- /**
12
- * Builds a flat search index from a list of MarkdownFile entries.
13
- * Strip HTML and frontmatter for plain-text indexing.
14
- */
15
- export function buildSearchIndex(files: MarkdownFile[]): SearchEntry[] {
16
- return files
17
- .filter((f) => !f.frontmatter.draft)
18
- .map((file) => {
19
- // Strip frontmatter block
20
- const body = file.raw.replace(/^---[\s\S]*?---\n?/, "")
21
- // Strip markdown syntax (rough pass)
22
- const text = body
23
- .replace(/```[\s\S]*?```/g, "") // code blocks
24
- .replace(/`[^`]+`/g, "") // inline code
25
- .replace(/!\[.*?\]\(.*?\)/g, "") // images
26
- .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") // links → text
27
- .replace(/\[\[([^\]|#]+)(?:[|#][^\]]*)?\]\]/g, "$1") // wikilinks → text
28
- .replace(/#{1,6}\s/g, "") // headings
29
- .replace(/[*_~]/g, "") // emphasis
30
- .replace(/>\s/g, "") // blockquotes
31
- .replace(/\s+/g, " ")
32
- .trim()
33
-
34
- return {
35
- slug: file.slug,
36
- title: file.frontmatter.title ?? file.slug.split("/").pop() ?? file.slug,
37
- content: text,
38
- tags: file.frontmatter.tags ?? [],
39
- description: file.frontmatter.description,
40
- }
41
- })
42
- }
package/src/types.ts DELETED
@@ -1,35 +0,0 @@
1
- export interface Frontmatter {
2
- title?: string
3
- date?: string | Date
4
- tags?: string[]
5
- description?: string
6
- draft?: boolean
7
- aliases?: string[]
8
- [key: string]: unknown
9
- }
10
-
11
- export interface TocEntry {
12
- depth: number
13
- text: string
14
- id: string
15
- children: TocEntry[]
16
- }
17
-
18
- export interface RenderResult {
19
- html: string
20
- frontmatter: Frontmatter
21
- toc: TocEntry[]
22
- links: string[] // outgoing wikilinks
23
- tags: string[] // inline #tags
24
- }
25
-
26
- export interface RenderOptions {
27
- /** Base URL for wikilinks (default: '/') */
28
- baseUrl?: string
29
- /** Resolve wikilink target to URL path */
30
- resolveLink?: (target: string) => string
31
- /** Known slugs for dead-link detection */
32
- knownSlugs?: Set<string>
33
- /** Whether to strip draft pages (default: false) */
34
- stripDrafts?: boolean
35
- }
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": ["ES2022"],
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "declaration": true,
10
- "declarationMap": true,
11
- "sourceMap": true,
12
- "strict": true,
13
- "skipLibCheck": true
14
- },
15
- "include": ["src"],
16
- "exclude": ["node_modules", "dist"]
17
- }
package/vitest.config.ts DELETED
@@ -1,20 +0,0 @@
1
- import { defineConfig } from "vitest/config"
2
-
3
- export default defineConfig({
4
- test: {
5
- environment: "node",
6
- globals: true,
7
- include: ["src/**/*.test.ts"],
8
- coverage: {
9
- provider: "v8",
10
- include: ["src/**/*.ts"],
11
- exclude: ["src/**/*.test.ts", "src/index.ts"],
12
- thresholds: {
13
- lines: 85,
14
- functions: 85,
15
- branches: 80,
16
- statements: 85,
17
- },
18
- },
19
- },
20
- })