Jacky Zhao
2023-08-12 83269ac26e41f8e81b56e000b4347ee60d4ff84b
quartz/plugins/transformers/links.ts
@@ -2,6 +2,7 @@
import {
  CanonicalSlug,
  RelativeURL,
  _stripSlashes,
  canonicalizeServer,
  joinSegments,
  pathToRoot,
@@ -29,27 +30,25 @@
  const opts = { ...defaultOptions, ...userOpts }
  return {
    name: "LinkProcessing",
    htmlPlugins() {
    htmlPlugins(ctx) {
      return [
        () => {
          return (tree, file) => {
            const curSlug = canonicalizeServer(file.data.slug!)
            const transformLink = (target: string): RelativeURL => {
              const targetSlug = transformInternalLink(target).slice("./".length)
              const targetSlug = _stripSlashes(transformInternalLink(target).slice(".".length))
              let [targetCanonical, targetAnchor] = splitAnchor(targetSlug)
              if (opts.markdownLinkResolution === "relative") {
                return targetSlug as RelativeURL
              } else if (opts.markdownLinkResolution === "shortest") {
                // https://forum.obsidian.md/t/settings-new-link-format-what-is-shortest-path-when-possible/6748/5
                const allSlugs = file.data.allSlugs!
                // if the file name is unique, then it's just the filename
                const matchingFileNames = allSlugs.filter((slug) => {
                const matchingFileNames = ctx.allSlugs.filter((slug) => {
                  const parts = slug.split(path.posix.sep)
                  const fileName = parts.at(-1)
                  return targetCanonical === fileName
                })
                // only match, just use it
                if (matchingFileNames.length === 1) {
                  const targetSlug = canonicalizeServer(matchingFileNames[0])
                  return (resolveRelative(curSlug, targetSlug) + targetAnchor) as RelativeURL
@@ -72,12 +71,13 @@
                typeof node.properties.href === "string"
              ) {
                let dest = node.properties.href as RelativeURL
                node.properties.className = isAbsoluteUrl(dest) ? "external" : "internal"
                node.properties.className ??= []
                node.properties.className.push(isAbsoluteUrl(dest) ? "external" : "internal")
                // don't process external links or intra-document anchors
                if (!(isAbsoluteUrl(dest) || dest.startsWith("#"))) {
                  dest = node.properties.href = transformLink(dest)
                  const canonicalDest = path.normalize(joinSegments(curSlug, dest))
                  const canonicalDest = path.posix.normalize(joinSegments(curSlug, dest))
                  const [destCanonical, _destAnchor] = splitAnchor(canonicalDest)
                  outgoing.add(destCanonical as CanonicalSlug)
                }
@@ -86,7 +86,8 @@
                if (
                  opts.prettyLinks &&
                  node.children.length === 1 &&
                  node.children[0].type === "text"
                  node.children[0].type === "text" &&
                  !node.children[0].value.startsWith("#")
                ) {
                  node.children[0].value = path.basename(node.children[0].value)
                }
@@ -99,9 +100,10 @@
                typeof node.properties.src === "string"
              ) {
                if (!isAbsoluteUrl(node.properties.src)) {
                  let dest = node.properties.src as RelativeURL
                  const ext = path.extname(node.properties.src)
                  node.properties.src =
                    transformLink(path.join("assets", node.properties.src)) + ext
                  dest = node.properties.src = transformLink(dest)
                  node.properties.src = dest + ext
                }
              }
            })