various path fixes for links to extensions, fix relative paths in links

This commit is contained in:
Jacky Zhao 2023-08-17 00:55:28 -07:00
parent 2dc0ae279c
commit 0c199975f2
16 changed files with 77 additions and 52 deletions
quartz/util

View file

@ -72,7 +72,7 @@ export type RelativeURL = SlugLike<"relative">
export function isRelativeURL(s: string): s is RelativeURL {
const validStart = /^\.{1,2}/.test(s)
const validEnding = !(s.endsWith("/index") || s === "index")
return validStart && validEnding && !_hasFileExtension(s)
return validStart && validEnding && ![".md", ".html"].includes(_getFileExtension(s) ?? "")
}
/** A server side slug. This is what Quartz uses to emit files so uses index suffixes */
@ -80,7 +80,7 @@ export type ServerSlug = SlugLike<"server">
export function isServerSlug(s: string): s is ServerSlug {
const validStart = !(s.startsWith(".") || s.startsWith("/"))
const validEnding = !s.endsWith("/")
return validStart && validEnding && !_containsForbiddenCharacters(s) && !_hasFileExtension(s)
return validStart && validEnding && !_containsForbiddenCharacters(s)
}
/** The real file path to a file on disk */
@ -114,9 +114,14 @@ export function canonicalizeServer(slug: ServerSlug): CanonicalSlug {
return res
}
export function slugifyFilePath(fp: FilePath): ServerSlug {
export function slugifyFilePath(fp: FilePath, excludeExt?: boolean): ServerSlug {
fp = _stripSlashes(fp) as FilePath
const withoutFileExt = fp.replace(new RegExp(_getFileExtension(fp) + "$"), "")
let ext = _getFileExtension(fp)
const withoutFileExt = fp.replace(new RegExp(ext + "$"), "")
if (excludeExt || [".md", ".html", undefined].includes(ext)) {
ext = ""
}
let slug = withoutFileExt
.split("/")
.map((segment) => segment.replace(/\s/g, "-")) // slugify all segments
@ -128,7 +133,7 @@ export function slugifyFilePath(fp: FilePath): ServerSlug {
slug = slug.replace(/_index$/, "index")
}
return slug as ServerSlug
return slug + ext as ServerSlug
}
export function transformInternalLink(link: string): RelativeURL {
@ -139,19 +144,16 @@ export function transformInternalLink(link: string): RelativeURL {
fplike.endsWith("index.md") ||
fplike.endsWith("index.html") ||
fplike.endsWith("/")
let segments = fplike.split("/").filter((x) => x.length > 0)
let prefix = segments.filter(_isRelativeSegment).join("/")
let fp = segments.filter((seg) => !_isRelativeSegment(seg)).join("/")
// implicit markdown
if (!_hasFileExtension(fp)) {
fp += ".md"
}
fp = canonicalizeServer(slugifyFilePath(fp as FilePath))
// manually add ext here as we want to not strip 'index' if it has an extension
fp = canonicalizeServer(slugifyFilePath(fp as FilePath) as ServerSlug)
const joined = joinSegments(_stripSlashes(prefix), _stripSlashes(fp))
const trail = folderPath ? "/" : ""
const res = (_addRelativeToStart(joined) + anchor + trail) as RelativeURL
const res = (_addRelativeToStart(joined) + trail + anchor) as RelativeURL
return res
}
@ -217,8 +219,9 @@ export function transformLink(
if (opts.strategy === "relative") {
return _addRelativeToStart(targetSlug) as RelativeURL
} else {
targetSlug = _stripSlashes(targetSlug.slice(".".length))
let [targetCanonical, targetAnchor] = splitAnchor(targetSlug)
const folderTail = targetSlug.endsWith("/") ? "/" : ""
const canonicalSlug = _stripSlashes(targetSlug.slice(".".length))
let [targetCanonical, targetAnchor] = splitAnchor(canonicalSlug)
if (opts.strategy === "shortest") {
// if the file name is unique, then it's just the filename
@ -236,7 +239,7 @@ export function transformLink(
}
// if it's not unique, then it's the absolute path from the vault root
return joinSegments(pathToRoot(src), targetSlug) as RelativeURL
return joinSegments(pathToRoot(src), canonicalSlug) + folderTail as RelativeURL
}
}