mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
Merge e18b31304f into 59b5807601
This commit is contained in:
commit
77d5669c0e
@ -72,6 +72,7 @@ const config: QuartzConfig = {
|
||||
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
|
||||
Plugin.Description(),
|
||||
Plugin.Latex({ renderEngine: "katex" }),
|
||||
Plugin.LucideIcons(),
|
||||
],
|
||||
filters: [Plugin.RemoveDrafts()],
|
||||
emitters: [
|
||||
|
||||
@ -11,3 +11,4 @@ export { SyntaxHighlighting } from "./syntax"
|
||||
export { TableOfContents } from "./toc"
|
||||
export { HardLineBreaks } from "./linebreaks"
|
||||
export { RoamFlavoredMarkdown } from "./roam"
|
||||
export { LucideIcons } from "./lucide"
|
||||
|
||||
93
quartz/plugins/transformers/lucide.ts
Normal file
93
quartz/plugins/transformers/lucide.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { Element, Literal, Root } from "hast"
|
||||
import { visit } from "unist-util-visit"
|
||||
import { QuartzTransformerPlugin } from "../types"
|
||||
|
||||
function rehypeLucideIcons(verbose: boolean = false) {
|
||||
return (tree: Root) => {
|
||||
visit(tree, "text", (node: Literal, index: number | undefined, parent: any) => {
|
||||
if (
|
||||
typeof node.value === "string" &&
|
||||
typeof index === "number" &&
|
||||
parent &&
|
||||
parent.children &&
|
||||
Array.isArray(parent.children)
|
||||
) {
|
||||
// Replace the first match of a Lucide icon tag in this node.
|
||||
// Once the node is updated with the icon element, it will trigger a
|
||||
// new visit call to this node and recursively replace all icon tags.
|
||||
const originalText = node.value
|
||||
const lucidePattern = /:luc_([a-z_]+):/
|
||||
const lucideTag = originalText.match(lucidePattern)
|
||||
|
||||
if (lucideTag) {
|
||||
const [iconTag, iconName] = lucideTag
|
||||
const tagStart = lucideTag.index ?? 0
|
||||
|
||||
let replacedText: Array<Literal | Element> = []
|
||||
|
||||
if (tagStart > 0) {
|
||||
replacedText.push({
|
||||
type: "text",
|
||||
value: originalText.substring(0, tagStart),
|
||||
})
|
||||
}
|
||||
|
||||
const lucideIconElement: Element = {
|
||||
type: "element",
|
||||
tagName: "i",
|
||||
properties: {
|
||||
class: `lucide lucide-${iconName}`,
|
||||
"data-lucide": iconName,
|
||||
"aria-hidden": "true",
|
||||
},
|
||||
children: [],
|
||||
}
|
||||
replacedText.push(lucideIconElement)
|
||||
|
||||
if (verbose) {
|
||||
console.log(
|
||||
`[LucideIcons] Replaced markdown :luc_${iconName}: with HTML Lucide icon "${iconName}"`,
|
||||
)
|
||||
}
|
||||
|
||||
const remainingText = originalText.substring(tagStart + iconTag.length)
|
||||
if (remainingText) {
|
||||
replacedText.push({
|
||||
type: "text",
|
||||
value: remainingText,
|
||||
})
|
||||
}
|
||||
|
||||
parent.children.splice(index, 1, ...replacedText)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const LucideIcons: QuartzTransformerPlugin = () => {
|
||||
return {
|
||||
name: "LucideIcons",
|
||||
htmlPlugins(ctx) {
|
||||
return [() => rehypeLucideIcons(ctx?.argv?.verbose || false)]
|
||||
},
|
||||
externalResources() {
|
||||
return {
|
||||
js: [
|
||||
{
|
||||
src: "https://unpkg.com/lucide@latest",
|
||||
loadTime: "afterDOMReady",
|
||||
contentType: "external",
|
||||
},
|
||||
{
|
||||
script: "lucide.createIcons();",
|
||||
loadTime: "afterDOMReady",
|
||||
contentType: "inline",
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default LucideIcons
|
||||
@ -639,3 +639,9 @@ iframe.pdf {
|
||||
transition: width 0.2s ease;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.lucide {
|
||||
/* render Lucide icons proportional to font size */
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user