Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/feat/backlinks'
- Loading branch information
Showing
16 changed files
with
1,200 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { defineComponent, h, reactive, watch } from "vue"; | ||
import { useRoute } from "vitepress"; | ||
import DefaultTheme from "vitepress/theme"; | ||
import BacklinkReferences from "./plugins/backlinks/components/Backlinks.vue"; | ||
import Title from "./components/Title.vue"; | ||
|
||
export const Layout = defineComponent({ | ||
name: "Layout", | ||
|
||
setup() { | ||
const route = useRoute(); | ||
const state = reactive({ key: route.path }); | ||
|
||
watch( | ||
() => route.path, | ||
(path) => (state.key = path), | ||
); | ||
|
||
return () => | ||
h(DefaultTheme.Layout, null, { | ||
"doc-before": () => h(Title, { key: `${state.key}` }), | ||
"aside-outline-after": () => | ||
h(BacklinkReferences, { key: `${state.key}` }), | ||
}); | ||
}, | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import MarkdownIt from "markdown-it"; | ||
import { backlinksMarkdownIt as mdBacklinks } from "./plugins/backlinks/backlinksMarkdownIt"; | ||
import { collection } from "./plugins/backlinks"; | ||
import fs from "fs"; | ||
import matter from "gray-matter"; | ||
|
||
const md = new MarkdownIt(); | ||
md.use(mdBacklinks, { vault: "/" }); | ||
|
||
export default { | ||
watch: "**/*.md", // TODO: Fix adding `private/` with fast-glob | ||
async load(files?: string[]) { | ||
if (!files) { | ||
return { | ||
data: [], | ||
}; | ||
} | ||
|
||
for await (const file of files) { | ||
if (!file.endsWith(".md")) { | ||
continue; | ||
} | ||
|
||
const src = fs.readFileSync(file, "utf-8"); | ||
const { data: frontmatter } = matter(src); | ||
|
||
await md.render(src, { | ||
relativePath: file, | ||
frontmatter, | ||
}); | ||
} | ||
|
||
return { | ||
data: Object.fromEntries(collection), | ||
}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<template> | ||
<div class="vp-doc"> | ||
<h1 v-if="!$frontmatter.customHeader"> | ||
{{ $frontmatter.title }} | ||
<a class="header-anchor" href="#"></a> | ||
</h1> | ||
</div> | ||
</template> | ||
|
||
<script setup /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
// https://vitepress.dev/guide/custom-theme | ||
import Theme from "vitepress/theme"; | ||
import Title from "./LayoutWithTitle.vue"; | ||
import "./style.css"; | ||
import { Layout } from "./Layout"; | ||
|
||
export default { | ||
Layout: Title, | ||
extends: Theme, | ||
Layout, | ||
enhanceApp({ app, router, siteData }) {}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export interface Backlink { | ||
title: string; | ||
path: string; | ||
} | ||
|
||
export const collection: Map<string, Backlink[]> = new Map(); | ||
|
||
import type { PageData } from "vitepress"; | ||
|
||
// NOTE: collection here is lazy collected during the dev runtime. | ||
// it won't generate the backlink references information until you visit the | ||
// page. | ||
export const getBacklinksCollection = async (pageData: PageData) => { | ||
const relativePath = pageData.relativePath.replace(".md", ""); | ||
// console.log(relativePath); | ||
// console.log(collection); | ||
|
||
if (!collection.has(relativePath)) { | ||
return []; | ||
} | ||
return collection.get(relativePath); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type { PluginWithParams } from "markdown-it"; | ||
import { collection } from "./backlinksCollection.js"; | ||
|
||
export const regexp = /\[{2}\s*(.+?)\s*\]{2}/gi; | ||
|
||
const linkMatcher = (cap: RegExpExecArray) => { | ||
const backlink = cap[1].split("|"); | ||
const path = backlink[0]; | ||
const title = backlink[backlink.length - 1]; | ||
|
||
return { path, title }; | ||
}; | ||
|
||
export const backlinksMarkdownIt: PluginWithParams = (md, { vault }): void => { | ||
md.core.ruler.before("normalize", "backlinks", (state) => { | ||
// console.log(state); | ||
let relativePath = state.env.relativePath?.replace(".md", ""); | ||
let selfTitle = state.env.frontmatter?.title; | ||
|
||
state.src = ((src) => { | ||
let cap: RegExpExecArray | null; | ||
while ((cap = regexp.exec(src))) { | ||
const { title, path } = linkMatcher(cap); | ||
|
||
if (selfTitle != undefined && relativePath != undefined) { | ||
let backlinks = collection.get(path) ?? []; | ||
|
||
// TODO: use set to exclude duplicate backlinks | ||
let found = false; | ||
for (const backlink of backlinks) { | ||
if (backlink.path == relativePath) { | ||
found = true; | ||
break; | ||
} | ||
} | ||
if (!found) { | ||
backlinks.push({ | ||
title: selfTitle, | ||
path: relativePath, | ||
}); | ||
collection.set(path, backlinks); | ||
} | ||
} | ||
|
||
// console.log(collection); | ||
} | ||
|
||
return src; | ||
})(state.src); | ||
}); | ||
}; |
56 changes: 56 additions & 0 deletions
56
.vitepress/theme/plugins/backlinks/components/Backlinks.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<template> | ||
<div v-if="backlinks.length" class="backlinks"> | ||
<div class="content"> | ||
<div class="backlinks-title">{{ backlinks.length }} linked note{{ backlinks.length > 1 ? "s" : "" }}</div> | ||
<ul> | ||
<li v-for="backlink in backlinks"> | ||
<a class="backlink" :href="`/` + backlink.path">{{ backlink.title }}</a> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { useRoute } from "vitepress"; | ||
import { data as backlinksCollection } from "../../../backlinks.data"; | ||
const route = useRoute(); | ||
const backlinks = backlinksCollection.data[route.path.replace(".html", "").slice(1)] || []; | ||
</script> | ||
|
||
<style scoped lang="scss"> | ||
.backlinks { | ||
.content { | ||
position: relative; | ||
border-left: 1px solid var(--vp-c-divider); | ||
padding-left: 16px; | ||
font-size: 13px; | ||
font-weight: 500; | ||
} | ||
.backlinks-title { | ||
letter-spacing: 0.4px; | ||
line-height: 28px; | ||
font-size: 13px; | ||
font-weight: 600; | ||
} | ||
.backlink { | ||
display: block; | ||
line-height: 28px; | ||
color: var(--vp-c-text-2); | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
transition: color 0.5s; | ||
font-weight: 500; | ||
&:hover { | ||
color: var(--vp-c-text-1); | ||
transition: color 0.25s; | ||
} | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./backlinksCollection"; | ||
export * from "./backlinksMarkdownIt"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import glob from "fast-glob"; | ||
import MarkdownIt from "markdown-it"; | ||
import { backlinksMarkdownIt as mdBacklinks } from "./.vitepress/theme/plugins/backlinks/backlinksMarkdownIt.js"; | ||
import { collection } from "./.vitepress/theme/plugins/backlinks/backlinksCollection.js"; | ||
|
||
const md = new MarkdownIt(); | ||
|
||
const files = glob.md.use(mdBacklinks, { vault: "/" }); | ||
|
||
// const x = md.parse("Hello [[world]]!", {}); | ||
// console.log(x); | ||
console.log(collection); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
https://www.youtube.com/watch?v=YcM-nR7lE40 - 1h eee heee |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"compilerOptions": { | ||
"outDir": "./dist", | ||
"declaration": true, | ||
"target": "es6", | ||
"module": "Node16", | ||
"strict": true, | ||
"esModuleInterop": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"lib": ["ES2020", "DOM"] | ||
} | ||
// "include": ["src/**/*"] | ||
} |
Oops, something went wrong.