feat(links.ts): custom identifiers for custom icons

This commit is contained in:
bfahrenfort 2024-12-16 00:47:24 -06:00
parent 8141cb1587
commit f581fd5894

View File

@ -12,7 +12,9 @@ import {
import path from "path" import path from "path"
import { visit } from "unist-util-visit" import { visit } from "unist-util-visit"
import isAbsoluteUrl from "is-absolute-url" import isAbsoluteUrl from "is-absolute-url"
import { Root } from "hast" import { ElementContent, Root } from "hast"
type Sub = [RegExp, string | ElementContent]
interface Options { interface Options {
/** How to resolve Markdown paths */ /** How to resolve Markdown paths */
@ -22,6 +24,7 @@ interface Options {
openLinksInNewTab: boolean openLinksInNewTab: boolean
lazyLoad: boolean lazyLoad: boolean
externalLinkIcon: boolean externalLinkIcon: boolean
substitutions?: Sub[]
} }
const defaultOptions: Options = { const defaultOptions: Options = {
@ -55,32 +58,54 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options>> = (userOpts)
node.properties && node.properties &&
typeof node.properties.href === "string" typeof node.properties.href === "string"
) { ) {
let dest = node.properties.href as RelativeURL let href = node.properties.href
var dest = href as RelativeURL
var refIcon: string | ElementContent | null = null
var matched = false
opts.substitutions?.every(([regex, sub]) => {
let parts = href.match(regex)
if (parts != null) {
dest = parts.slice(1).join("") as RelativeURL
if (typeof sub == "object") {
refIcon = sub
} else {
refIcon = { type: "text", value: sub }
}
matched = true
return false // break equivalent
}
return true
})
node.properties.href = dest
const classes = (node.properties.className ?? []) as string[] const classes = (node.properties.className ?? []) as string[]
const isExternal = isAbsoluteUrl(dest) const isExternal = isAbsoluteUrl(dest)
classes.push(isExternal ? "external" : "internal") classes.push(isExternal ? "external" : "internal")
if (isExternal && opts.externalLinkIcon) { if ((isExternal && opts.externalLinkIcon) || matched) {
node.children.push({ node.children.push(
type: "element", refIcon != null
tagName: "svg", ? refIcon
properties: { : {
"aria-hidden": "true",
class: "external-icon",
style: "max-width:0.8em;max-height:0.8em",
viewBox: "0 0 512 512",
},
children: [
{
type: "element", type: "element",
tagName: "path", tagName: "svg",
properties: { properties: {
d: "M320 0H288V64h32 82.7L201.4 265.4 178.7 288 224 333.3l22.6-22.6L448 109.3V192v32h64V192 32 0H480 320zM32 32H0V64 480v32H32 456h32V480 352 320H424v32 96H64V96h96 32V32H160 32z", "aria-hidden": "true",
class: "external-icon",
style: "max-width:0.8em;max-height:0.8em",
viewBox: "0 0 512 512",
}, },
children: [], children: [
{
type: "element",
tagName: "path",
properties: {
d: "M320 0H288V64h32 82.7L201.4 265.4 178.7 288 224 333.3l22.6-22.6L448 109.3V192v32h64V192 32 0H480 320zM32 32H0V64 480v32H32 456h32V480 352 320H424v32 96H64V96h96 32V32H160 32z",
},
children: [],
},
],
}, },
], )
})
} }
// Check if the link has alias text // Check if the link has alias text