mirror of
https://github.com/alrayyes/wiki.git
synced 2025-05-02 14:58:14 +00:00
fix: parsing wikilinks that have codeblock anchors, scroll to anchor
This commit is contained in:
parent
fd5c8d17d3
commit
24348b24a9
16 changed files with 99 additions and 80 deletions
quartz/plugins
|
@ -14,9 +14,6 @@ export const Description: QuartzTransformerPlugin<Partial<Options> | undefined>
|
|||
const opts = { ...defaultOptions, ...userOpts }
|
||||
return {
|
||||
name: "Description",
|
||||
markdownPlugins() {
|
||||
return []
|
||||
},
|
||||
htmlPlugins() {
|
||||
return [
|
||||
() => {
|
||||
|
|
|
@ -33,9 +33,6 @@ export const FrontMatter: QuartzTransformerPlugin<Partial<Options> | undefined>
|
|||
}
|
||||
]
|
||||
},
|
||||
htmlPlugins() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,6 @@ export const CreatedModifiedDate: QuartzTransformerPlugin<Partial<Options> | und
|
|||
}
|
||||
]
|
||||
},
|
||||
htmlPlugins() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { QuartzTransformerPlugin } from "../types"
|
||||
import { relative, relativeToRoot, slugify, trimPathSuffix } from "../../path"
|
||||
import { relativeToRoot, slugify, trimPathSuffix } from "../../path"
|
||||
import path from "path"
|
||||
import { visit } from 'unist-util-visit'
|
||||
import isAbsoluteUrl from "is-absolute-url"
|
||||
|
@ -24,9 +24,6 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
|
|||
const opts = { ...defaultOptions, ...userOpts }
|
||||
return {
|
||||
name: "LinkProcessing",
|
||||
markdownPlugins() {
|
||||
return []
|
||||
},
|
||||
htmlPlugins() {
|
||||
return [() => {
|
||||
return (tree, file) => {
|
||||
|
@ -34,7 +31,8 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
|
|||
const transformLink = (target: string) => {
|
||||
const targetSlug = slugify(decodeURI(target).trim())
|
||||
if (opts.markdownLinkResolution === 'relative' && !path.isAbsolute(targetSlug)) {
|
||||
return './' + relative(curSlug, targetSlug)
|
||||
// TODO
|
||||
// return './' + relative(curSlug, targetSlug)
|
||||
} else {
|
||||
return './' + relativeToRoot(curSlug, targetSlug)
|
||||
}
|
||||
|
@ -77,9 +75,9 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
|
|||
}
|
||||
}
|
||||
|
||||
// transform all images
|
||||
// transform all other resources that may use links
|
||||
if (
|
||||
node.tagName === 'img' &&
|
||||
["img", "video", "audio", "iframe"].includes(node.tagName) &&
|
||||
node.properties &&
|
||||
typeof node.properties.src === 'string'
|
||||
) {
|
||||
|
|
|
@ -3,6 +3,7 @@ import { QuartzTransformerPlugin } from "../types"
|
|||
import { Root, HTML, BlockContent, DefinitionContent, Code } from 'mdast'
|
||||
import { findAndReplace } from "mdast-util-find-and-replace"
|
||||
import { slugify } from "../../path"
|
||||
import { slug as slugAnchor } from 'github-slugger'
|
||||
import rehypeRaw from "rehype-raw"
|
||||
import { visit } from "unist-util-visit"
|
||||
import path from "path"
|
||||
|
@ -94,21 +95,43 @@ const capitalize = (s: string): string => {
|
|||
return s.substring(0, 1).toUpperCase() + s.substring(1);
|
||||
}
|
||||
|
||||
// Match wikilinks
|
||||
// !? -> optional embedding
|
||||
// \[\[ -> open brace
|
||||
// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name)
|
||||
// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link)
|
||||
// (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias)
|
||||
const backlinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g")
|
||||
|
||||
// Match highlights
|
||||
const highlightRegex = new RegExp(/==(.+)==/, "g")
|
||||
|
||||
// from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts
|
||||
const calloutRegex = new RegExp(/^\[\!(\w+)\]([+-]?)/)
|
||||
|
||||
export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options> | undefined> = (userOpts) => {
|
||||
const opts = { ...defaultOptions, ...userOpts }
|
||||
return {
|
||||
name: "ObsidianFlavoredMarkdown",
|
||||
textTransform(src) {
|
||||
// pre-transform wikilinks (fix anchors to things that may contain illegal syntax e.g. codeblocks, latex)
|
||||
if (opts.wikilinks) {
|
||||
src = src.toString()
|
||||
return src.replaceAll(backlinkRegex, (value, ...capture) => {
|
||||
const [fp, rawHeader, rawAlias] = capture
|
||||
const anchor = rawHeader?.trim().slice(1)
|
||||
const displayAnchor = anchor ? `#${slugAnchor(anchor)}` : ""
|
||||
const displayAlias = rawAlias ?? ""
|
||||
const embedDisplay = value.startsWith("!") ? "!" : ""
|
||||
return `${embedDisplay}[[${fp}${displayAnchor}${displayAlias}]]`
|
||||
})
|
||||
}
|
||||
return src
|
||||
},
|
||||
markdownPlugins() {
|
||||
const plugins: PluggableList = []
|
||||
if (opts.wikilinks) {
|
||||
plugins.push(() => {
|
||||
// Match wikilinks
|
||||
// !? -> optional embedding
|
||||
// \[\[ -> open brace
|
||||
// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name)
|
||||
// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link)
|
||||
// (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias)
|
||||
const backlinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g")
|
||||
return (tree: Root, _file) => {
|
||||
findAndReplace(tree, backlinkRegex, (value: string, ...capture: string[]) => {
|
||||
const [fp, rawHeader, rawAlias] = capture
|
||||
|
@ -170,8 +193,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||
|
||||
if (opts.highlight) {
|
||||
plugins.push(() => {
|
||||
// Match highlights
|
||||
const highlightRegex = new RegExp(/==(.+)==/, "g")
|
||||
return (tree: Root, _file) => {
|
||||
findAndReplace(tree, highlightRegex, (_value: string, ...capture: string[]) => {
|
||||
const [inner] = capture
|
||||
|
@ -186,8 +207,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||
|
||||
if (opts.callouts) {
|
||||
plugins.push(() => {
|
||||
// from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts
|
||||
const calloutRegex = new RegExp(/^\[\!(\w+)\]([+-]?)/)
|
||||
return (tree: Root, _file) => {
|
||||
visit(tree, "blockquote", (node) => {
|
||||
if (node.children.length === 0) {
|
||||
|
|
|
@ -3,9 +3,6 @@ import rehypePrettyCode, { Options as CodeOptions } from "rehype-pretty-code"
|
|||
|
||||
export const SyntaxHighlighting: QuartzTransformerPlugin = () => ({
|
||||
name: "SyntaxHighlighting",
|
||||
markdownPlugins() {
|
||||
return []
|
||||
},
|
||||
htmlPlugins() {
|
||||
return [[rehypePrettyCode, {
|
||||
theme: 'css-variables',
|
||||
|
@ -15,10 +12,12 @@ export const SyntaxHighlighting: QuartzTransformerPlugin = () => ({
|
|||
}
|
||||
},
|
||||
onVisitHighlightedLine(node) {
|
||||
node.properties.className ??= []
|
||||
node.properties.className.push('highlighted')
|
||||
},
|
||||
onVisitHighlightedWord(node) {
|
||||
node.properties.className = ['word']
|
||||
node.properties.className ??= []
|
||||
node.properties.className.push('word')
|
||||
},
|
||||
} satisfies Partial<CodeOptions>]]
|
||||
}
|
||||
|
|
|
@ -52,9 +52,6 @@ export const TableOfContents: QuartzTransformerPlugin<Partial<Options> | undefin
|
|||
}
|
||||
}]
|
||||
},
|
||||
htmlPlugins() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@ type OptionType = object | undefined
|
|||
export type QuartzTransformerPlugin<Options extends OptionType = undefined> = (opts?: Options) => QuartzTransformerPluginInstance
|
||||
export type QuartzTransformerPluginInstance = {
|
||||
name: string
|
||||
markdownPlugins(): PluggableList
|
||||
htmlPlugins(): PluggableList
|
||||
externalResources?(): Partial<StaticResources>
|
||||
textTransform?: (src: string | Buffer) => string | Buffer
|
||||
markdownPlugins?: () => PluggableList
|
||||
htmlPlugins?: () => PluggableList
|
||||
externalResources?: () => Partial<StaticResources>
|
||||
}
|
||||
|
||||
export type QuartzFilterPlugin<Options extends OptionType = undefined> = (opts?: Options) => QuartzFilterPluginInstance
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue