mirror of
https://github.com/alrayyes/wiki.git
synced 2025-05-02 06:58:13 +00:00
basic search implementation
This commit is contained in:
parent
c4cf0dcb02
commit
fd5c8d17d3
26 changed files with 751 additions and 182 deletions
quartz/plugins
|
@ -1,20 +1,7 @@
|
|||
import { visit } from "unist-util-visit"
|
||||
import { QuartzEmitterPlugin } from "../types"
|
||||
import { Element } from "hast"
|
||||
import path from "path"
|
||||
import { trimPathSuffix } from "../../path"
|
||||
|
||||
interface Options {
|
||||
indexAnchorLinks: boolean,
|
||||
indexExternalLinks: boolean,
|
||||
}
|
||||
|
||||
const defaultOptions: Options = {
|
||||
indexAnchorLinks: false,
|
||||
indexExternalLinks: false,
|
||||
}
|
||||
|
||||
export type ContentIndex = Map<string, ContentDetails>
|
||||
export type ContentIndex = Map<string, ContentDetails>
|
||||
export type ContentDetails = {
|
||||
title: string,
|
||||
links?: string[],
|
||||
|
@ -22,39 +9,17 @@ export type ContentDetails = {
|
|||
content: string,
|
||||
}
|
||||
|
||||
export const ContentIndex: QuartzEmitterPlugin<Options> = (userOpts) => {
|
||||
const opts = { ...userOpts, ...defaultOptions }
|
||||
export const ContentIndex: QuartzEmitterPlugin = () => {
|
||||
return {
|
||||
name: "ContentIndex",
|
||||
async emit(_contentDir, _cfg, content, _resources, emit) {
|
||||
const fp = path.join("static", "contentIndex")
|
||||
const linkIndex: ContentIndex = new Map()
|
||||
for (const [tree, file] of content) {
|
||||
let slug = trimPathSuffix(file.data.slug!)
|
||||
|
||||
const outgoing: Set<string> = new Set()
|
||||
visit(tree, 'element', (node: Element) => {
|
||||
if (node.tagName === 'a' && node.properties && typeof node.properties.href === 'string') {
|
||||
let dest = node.properties.href
|
||||
if (dest.startsWith(".")) {
|
||||
const normalizedPath = path.normalize(path.join(slug, dest))
|
||||
dest = trimPathSuffix(normalizedPath)
|
||||
outgoing.add(dest)
|
||||
} else if (dest.startsWith("#")) {
|
||||
if (opts.indexAnchorLinks) {
|
||||
outgoing.add(dest)
|
||||
}
|
||||
} else {
|
||||
if (opts.indexExternalLinks) {
|
||||
outgoing.add(dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for (const [_tree, file] of content) {
|
||||
let slug = file.data.slug!
|
||||
linkIndex.set(slug, {
|
||||
title: file.data.frontmatter?.title!,
|
||||
links: [...outgoing],
|
||||
links: file.data.links ?? [],
|
||||
tags: file.data.frontmatter?.tags,
|
||||
content: file.data.text ?? ""
|
||||
})
|
||||
|
|
|
@ -33,7 +33,7 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
|
|||
},
|
||||
async emit(_contentDir, cfg, content, resources, emit): Promise<string[]> {
|
||||
const fps: string[] = []
|
||||
|
||||
const allFiles = content.map(c => c[1].data)
|
||||
for (const [tree, file] of content) {
|
||||
const baseDir = resolveToRoot(file.data.slug!)
|
||||
const pageResources: StaticResources = {
|
||||
|
@ -50,13 +50,14 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
|
|||
externalResources: pageResources,
|
||||
cfg,
|
||||
children: [],
|
||||
tree
|
||||
tree,
|
||||
allFiles
|
||||
}
|
||||
|
||||
const Content = opts.content
|
||||
const doc = <html>
|
||||
<Head {...componentData} />
|
||||
<body data-slug={trimPathSuffix(file.data.slug ?? "")}>
|
||||
<body data-slug={file.data.slug ?? ""}>
|
||||
<div id="quartz-root" class="page">
|
||||
<Header {...componentData} >
|
||||
{header.map(HeaderComponent => <HeaderComponent {...componentData} />)}
|
||||
|
|
|
@ -51,6 +51,7 @@ export function emitComponentResources(cfg: GlobalConfiguration, resources: Stat
|
|||
componentResources.afterDOMLoaded.push(spaRouterScript)
|
||||
} else {
|
||||
componentResources.afterDOMLoaded.push(`
|
||||
window.spaNavigate = (url, _) => window.location.assign(url)
|
||||
const event = new CustomEvent("nav", { detail: { slug: document.body.dataset.slug } })
|
||||
document.dispatchEvent(event)`
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ export { GitHubFlavoredMarkdown } from './gfm'
|
|||
export { CreatedModifiedDate } from './lastmod'
|
||||
export { Katex } from './latex'
|
||||
export { Description } from './description'
|
||||
export { ResolveLinks } from './links'
|
||||
export { CrawlLinks } from './links'
|
||||
export { ObsidianFlavoredMarkdown } from './ofm'
|
||||
export { SyntaxHighlighting } from './syntax'
|
||||
export { TableOfContents } from './toc'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { QuartzTransformerPlugin } from "../types"
|
||||
import { relative, relativeToRoot, slugify } from "../../path"
|
||||
import { relative, relativeToRoot, slugify, trimPathSuffix } from "../../path"
|
||||
import path from "path"
|
||||
import { visit } from 'unist-util-visit'
|
||||
import isAbsoluteUrl from "is-absolute-url"
|
||||
|
@ -9,14 +9,18 @@ interface Options {
|
|||
markdownLinkResolution: 'absolute' | 'relative'
|
||||
/** Strips folders from a link so that it looks nice */
|
||||
prettyLinks: boolean
|
||||
indexAnchorLinks: boolean
|
||||
indexExternalLinks: boolean
|
||||
}
|
||||
|
||||
const defaultOptions: Options = {
|
||||
markdownLinkResolution: 'absolute',
|
||||
prettyLinks: true
|
||||
prettyLinks: true,
|
||||
indexAnchorLinks: false,
|
||||
indexExternalLinks: false,
|
||||
}
|
||||
|
||||
export const ResolveLinks: QuartzTransformerPlugin<Partial<Options> | undefined> = (userOpts) => {
|
||||
export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> = (userOpts) => {
|
||||
const opts = { ...defaultOptions, ...userOpts }
|
||||
return {
|
||||
name: "LinkProcessing",
|
||||
|
@ -36,6 +40,7 @@ export const ResolveLinks: QuartzTransformerPlugin<Partial<Options> | undefined>
|
|||
}
|
||||
}
|
||||
|
||||
const outgoing: Set<string> = new Set()
|
||||
visit(tree, 'element', (node, _index, _parent) => {
|
||||
// rewrite all links
|
||||
if (
|
||||
|
@ -43,13 +48,27 @@ export const ResolveLinks: QuartzTransformerPlugin<Partial<Options> | undefined>
|
|||
node.properties &&
|
||||
typeof node.properties.href === 'string'
|
||||
) {
|
||||
node.properties.className = isAbsoluteUrl(node.properties.href) ? "external" : "internal"
|
||||
let dest = node.properties.href
|
||||
node.properties.className = isAbsoluteUrl(dest) ? "external" : "internal"
|
||||
|
||||
|
||||
// don't process external links or intra-document anchors
|
||||
if (!(isAbsoluteUrl(node.properties.href) || node.properties.href.startsWith("#"))) {
|
||||
node.properties.href = transformLink(node.properties.href)
|
||||
if (!(isAbsoluteUrl(dest) || dest.startsWith("#"))) {
|
||||
node.properties.href = transformLink(dest)
|
||||
}
|
||||
|
||||
dest = node.properties.href
|
||||
if (dest.startsWith(".")) {
|
||||
const normalizedPath = path.normalize(path.join(curSlug, dest))
|
||||
outgoing.add(trimPathSuffix(normalizedPath))
|
||||
} else if (dest.startsWith("#")) {
|
||||
if (opts.indexAnchorLinks) {
|
||||
outgoing.add(dest)
|
||||
}
|
||||
} else {
|
||||
|
||||
if (opts.indexExternalLinks) {
|
||||
outgoing.add(dest)
|
||||
}
|
||||
}
|
||||
|
||||
// rewrite link internals if prettylinks is on
|
||||
|
@ -70,8 +89,16 @@ export const ResolveLinks: QuartzTransformerPlugin<Partial<Options> | undefined>
|
|||
}
|
||||
}
|
||||
})
|
||||
|
||||
file.data.links = [...outgoing]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vfile' {
|
||||
interface DataMap {
|
||||
links: string[]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue