Commit graph

11 commits

Author SHA1 Message Date
saberzero1
37b89c3fbe
fix: match obsidian-importer illegal character filter in slugs 2026-06-03 15:10:02 +02:00
saberzero1
b6aa8b0feb
test: added regression tests 2026-05-26 17:44:42 +02:00
saberzero1
6721918708
fix(path): detect folder paths after slugification in transformInternalLink
isFolderPath() was checked on the raw input before slugifyFilePath()
rewrote folder notes (e.g. "My Folder/My Folder" -> "my-folder/index").
Now checks isFolderPath on both the raw input and the slugified result,
so the trailing slash is correctly emitted for folder note links.
2026-04-22 18:13:15 +02:00
saberzero1
bb5c136296
feat(path): add normalizeHastElement for cross-slug HAST rebasing
Moved from Quartz core (quartz/util/path.ts) into the shared utils
package so that plugins performing cross-slug HAST embedding can
re-use the same rebase helper as Quartz's internal transclude
expansion, rather than reimplementing or skipping the rebase.

The primary consumer outside of Quartz core is canvas-page, whose
buildEmbeddedContent() pulls vfile.data.htmlAst from arbitrary target
pages and serializes it verbatim into canvas pages - producing broken
relative hrefs that survive accidentally on root deployments but fail
under non-trivial basePath configurations. Exposing the helper here
lets canvas-page (and any future embedding plugin) rebase correctly
without duplicating the logic.

Implementation details:
- Deep-clones the input via structuredClone (Node >=22 builtin) so
  callers don't need to bring their own clone function
- Absolute URLs (http://, https://, /root-relative) pass through
  untouched; only relative URLs are rebased
- Recurses into children so nested anchors inside a rebased subtree
  are also normalized

Backed by 10 new tests covering same-slug, cross-slug (both directions),
nested depth, anchor preservation, absolute URL passthrough, root-relative
passthrough, src-attribute rebasing, elements without href/src, nested
children recursion, and input-immutability.
2026-04-17 02:24:33 +02:00
saberzero1
4dda81bc82
feat(path)!: lowercase slugs for Obsidian-parity case-insensitive matching
slugifyPath now lowercases its output, which cascades through
slugifyFilePath, slugTag, and transformInternalLink (all of which
funnel through _sluggify).

This matches Obsidian's case-insensitive link and tag matching:
[[MyNote]], [[mynote]], and [[MYNOTE]] all resolve to the slug
'my-note', and the tags #MyTag, #mytag, and #MYTAG collapse into a
single tag page.

BREAKING CHANGE: all generated URLs are now lowercase. Users
upgrading with mixed-case source filenames will see their URLs
change (e.g. /MyNote -> /my-note). Also eliminates silent data
loss on case-insensitive filesystems (macOS APFS, Windows NTFS)
where Apple.md and apple.md previously produced conflicting HTML
outputs that overwrote each other without warning.
2026-04-16 21:12:37 +02:00
saberzero1
e17fc8d5f0
feat(path): support folder note convention 2026-04-10 19:16:30 +02:00
saberzero1
1ad4e4f2f6
fix: support multi-segment partial paths in shortest link resolution
The 'shortest' strategy in transformLink() only matched by filename (last
segment), causing wiki-links like [[Species/Elf/Wood]] to fail resolution
when the target lived under a deeper path (e.g. Compendium/Species/Elf/Wood).

Add suffix-based matching for multi-segment partial paths and handle the
/index variant for folder targets whose suffix gets stripped by
transformInternalLink().
2026-03-22 11:51:41 +01:00
saberzero1
1bc315eb6e
fix: handle folder/index page slugs in transformLink relative path computation
When src is a folder page (e.g. 'Compendium/Spells' backed by index.md),
pathToRoot miscalculated the depth because the browser serves folder pages
at '/Compendium/Spells/' (trailing slash). Now detects folder pages via
allSlugs and uses the index slug for correct relative URL generation.
2026-03-20 11:45:06 +01:00
saberzero1
e0b3f658b9
feat: export slugifyPath as public utility 2026-03-20 11:19:40 +01:00
saberzero1
d7d93758b2
feat: add getBasePath and resolveBasePath for subdirectory deployments
Add utility functions to resolve links correctly when Quartz is deployed
to a subdirectory (e.g., user.github.io/repository). getBasePath() reads
the base path from a data attribute on <body>, and resolveBasePath()
prepends it to slugs for client-side navigation.
2026-03-18 11:50:30 +01:00
saberzero1
61970ce89f
feat: migrate to shared utility library
- Remove plugin template code
- Add path utilities (simplifySlug, joinSegments, etc.)
- Add DOM utilities (removeAllChildren, registerEscapeHandler)
- Add lang utilities (classNames)
- Update package.json for @quartz-community/utils
- Add tests for path utilities
2026-02-09 12:38:53 +01:00