Skip to content

Commit

Permalink
refactor: all new
Browse files Browse the repository at this point in the history
  • Loading branch information
bsdayo committed May 4, 2024
1 parent cc36378 commit 98e90a5
Show file tree
Hide file tree
Showing 149 changed files with 2,155 additions and 2,493 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/

# VitePress
content/.vitepress/cache/
content/.vitepress/dist/
.vitepress/cache/
.vitepress/dist/
77 changes: 77 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { defineConfigWithTheme } from 'vitepress'
import { createContainer } from './utils'
import { ThemeConfig } from './theme'
import tags from './tags'

export default defineConfigWithTheme<ThemeConfig>({
title: 'SynBlog',
description: 'SynBlog v4 - Powered by VitePress',

markdown: {
theme: {
light: 'github-light',
dark: 'one-dark-pro',
},

config(md) {
md.use(...createContainer('note', 'NOTE', md))
.use(...createContainer('abstract', 'ABSTRACT', md))
// info already added
// tip already added
.use(...createContainer('success', 'SUCCESS', md))
.use(...createContainer('question', 'QUESTION', md))
// warning already added
.use(...createContainer('failure', 'FAILURE', md))
// danger already added
.use(...createContainer('bug', 'BUG', md))
.use(...createContainer('example', 'EXAMPLE', md))
.use(...createContainer('quote', 'QUOTE', md))
},
},

rewrites: {
'pages/about/index.md': 'about/index.md',
'pages/posts/index.md': 'posts/index.md',
'pages/links/index.md': 'links/index.md',
'pages/tags/index.md': 'tags/index.md',
'pages/tags/:tag.md': 'tags/:tag.md',
},

ignoreDeadLinks: 'localhostLinks',

themeConfig: {
tags,
nav: [
{ text: '文章', link: '/posts/' },
{ text: '友链', link: '/links/' },
{ text: '关于', link: '/about/' },
],

socialLinks: [
{ icon: 'github', link: 'https://github.com/bsdayo' },
{ icon: 'x', link: 'https://twitter.com/konobsdayo' },
],

giscus: {
host: 'https://giscus.app',
repo: 'bsdayo/blog',
repoId: 'R_kgDOJab-4g',
category: 'Comments',
categoryId: 'DIC_kwDOJab-4s4CWGFy',
mapping: 'pathname',
strict: '0',
reactionsEnabled: '0',
emitMetadata: '0',
inputPosition: 'top',
lang: 'zh-CN',
loading: 'lazy',
},

footer: {
message:
'若无特别声明,所有内容均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans" target="_blank">CC BY-NC-SA 4.0</a> 协议授权',
copyright:
'Copyright © 2024 bsdayo | <a href="https://github.com/bsdayo/blog" target="_blank">GitHub</a>',
},
},
})
43 changes: 43 additions & 0 deletions .vitepress/posts.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createContentLoader } from 'vitepress'
import { Post } from './theme'

const loader = createContentLoader('posts/**/index.md')
export default {
...loader,
async load(): Promise<Post[]> {
const data = await loader.load()
return data
.map((content) => {
const post: Post = {
...content,
id: /(?<=\/posts\/).*(?=\/)/.exec(content.url)![0],
title: content.frontmatter.title,
description: content.frontmatter.description,
create: content.frontmatter.create
? new Date(content.frontmatter.create).getTime()
: Date.now(),
tags: content.frontmatter.tags ?? [],
}
return post

// return {
// frontmatter: post.frontmatter,
// id: /(?<=\/posts\/).*(?=\/)/.exec(post.url)![0],
// title: post.frontmatter.title ?? 'Untitled Post',
// cover: post.frontmatter.cover,
// description: post.frontmatter.description,
// create: post.frontmatter.create
// ? new Date(post.frontmatter.create).getTime()
// : Date.now(),
// category: post.frontmatter.category,
// tags: post.frontmatter.tags ?? [],
// url: post.url.replace('index.html', ''),
// comment: !!(post.frontmatter.comment ?? true),
// }
})
.sort((a, b) => b.create - a.create)
},
}

declare const data: Post[]
export { data } // 已经按时间顺序排序
4 changes: 2 additions & 2 deletions content/.vitepress/tags.ts → .vitepress/tags.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Tag } from '../../theme/types/config'
import { ThemeConfig } from './theme'

const tags: Record<string, Tag> = {
const tags: ThemeConfig['tags'] = {
archlinux: ['Arch Linux', '#1793D1'],
cpp: ['C++', '#00599C'],
csharp: ['C#', '#239120'],
Expand Down
125 changes: 125 additions & 0 deletions .vitepress/theme/Layout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<n-config-provider :theme="isDark ? darkTheme : lightTheme">
<Layout>
<template #doc-before v-if="currentPost">
<n-thing class="post-header">
<template #header>
<h1 class="post-title">{{ currentPost.title }}</h1>
</template>
<template #description>{{ currentPost.description }}</template>
<template #footer>
<n-flex justify="space-between">
<DateTag :time="currentPost.create" />
<n-flex>
<PostTag
v-for="tag in currentPost.tags"
:key="tag"
:tag="tag"
/>
</n-flex>
</n-flex>
</template>
</n-thing>
</template>

<template #doc-after>
<n-divider />
<Giscus
:key="page.relativePath"
v-bind="theme.giscus"
:theme="isDark ? 'transparent_dark' : 'light'"
/>
</template>
</Layout>
</n-config-provider>
</template>

<script lang="ts" setup>
import { computed, nextTick, watch, onMounted } from 'vue'
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { data as posts } from '../posts.data'
import {
NConfigProvider,
NThing,
NDivider,
NFlex,
lightTheme,
darkTheme,
} from 'naive-ui'
import Giscus from '@giscus/vue'
import mediumZoom from 'medium-zoom'
import WebFont from 'webfontloader'
import { ThemeConfig } from '.'
import PostTag from '../../components/PostTag.vue'
import DateTag from '../../components/DateTag.vue'
const { Layout } = DefaultTheme
const { page, theme, isDark } = useData<ThemeConfig>()
const taglines: string[] = [
'<code>(() => &lt;bs moe/&gt;)()</code>',
"<code>h('bs', { moe: true })</code>",
'<code>[moe.things]::bs</code>',
'<code>bs.nyan()</code>',
'<code>Start-Sleep -Duration 365d</code>',
'<code>while (true) { eat() }</code>',
'你是?不能忘记的人,很重要的人',
]
onMounted(() => {
const taglineElement = document.querySelector('.tagline')
if (!taglineElement) return
taglineElement.innerHTML =
taglines[Math.floor(Math.random() * taglines.length)]
})
WebFont.load({
google: {
families: ['JetBrains Mono:400,500,600,700'],
},
})
const currentPost = computed(() => {
const postId = page.value.relativePath.match(/posts\/(.*)\//)?.[1]
if (!postId) return null
return posts.find((post) => post.id === postId)
})
const mdImgSelector = '.vp-doc img'
watch(
() => page.value.relativePath,
() =>
nextTick(() => {
document.querySelectorAll(mdImgSelector).forEach((img) => {
const alt = img.attributes.getNamedItem('alt')
if (!alt) return
const node = document.createElement('div')
node.classList.add('img-alt')
node.innerText = alt.value
const parent = img.parentNode!
if (parent.lastChild === img) parent.appendChild(node)
else parent.insertBefore(node, img.nextSibling)
})
mediumZoom(mdImgSelector, {
background: 'rgba(0, 0, 0, 0.5)',
})
}),
{ immediate: true }
)
</script>

<style lang="scss">
.post-header {
margin-bottom: 64px;
}
.post-title {
font-weight: 600;
outline: none;
line-height: 40px;
font-size: 32px;
}
</style>
72 changes: 72 additions & 0 deletions .vitepress/theme/custom.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
$custom-blocks: (
note: #4481ff,
abstract: #00b0ff,
info: #00b8d4,
tip: #00bfa5,
success: #00c853,
question: #64dd17,
warning: #ff9100,
failure: #ff5252,
danger: #ff1744,
bug: #f50057,
example: #7c4dff,
quote: #9e9e9e,
);

:root {
--vp-font-family-mono: 'JetBrains Mono', ui-monospace, 'Menlo', 'Monaco',
'Consolas', 'Liberation Mono', 'Courier New', monospace;

--vp-c-brand-1: #0d47a1;
--vp-c-brand-2: #1565c0;
--vp-c-brand-3: #1976d2;
}

.dark {
--vp-c-brand-1: #64b5f6;
--vp-c-brand-2: #1976d2;
--vp-c-brand-3: #1565c0;
}

@each $name, $color in $custom-blocks {
:root {
--vp-custom-block-#{$name}-border: #{$color};
--vp-custom-block-#{$name}-bg: #{rgba($color, 0.16)};
--vp-custom-block-#{$name}-code-bg: #{rgba($color, 0.16)};
}

.custom-block.#{$name} {
border-color: var(--vp-custom-block-#{$name}-border);
background-color: var(--vp-custom-block-#{$name}-bg);
color: var(--vp-c-text-1);

code {
background-color: var(--vp-custom-block-#{$name}-code-bg);
}

blockquote {
border-left-color: var(--vp-custom-block-#{$name}-bg);
}
}
}

.medium-zoom-overlay,
.medium-zoom-image--opened {
z-index: 99999;
}

.vp-doc .img-alt {
text-align: center;
color: var(--vp-c-text-2);
margin-top: 8px;
}

.VPHero .image-container {
@media (min-width: 960px) {
transform: none;
}

img {
border-radius: 50%;
}
}
26 changes: 26 additions & 0 deletions .vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { DefaultTheme as DefaultThemeType, Theme, ContentData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import Layout from './Layout.vue'
import { GiscusProps } from '@giscus/vue'
import './custom.scss'

const theme: Theme = {
extends: DefaultTheme,
Layout,
}

export default theme

export interface ThemeConfig extends DefaultThemeType.Config {
giscus: GiscusProps
tags: Record<string, [name: string, color?: string]>
}

export interface Post extends ContentData {
id: string
title: string
description?: string
create: number
category?: string
tags: string[]
}
32 changes: 32 additions & 0 deletions .vitepress/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import container from 'markdown-it-container'

// https://github.com/vuejs/vitepress/blob/main/src/node/markdown/plugins/containers.ts

// [typeof container, string, { render: RenderRule }]
type ContainerArgs = [any, string, { render: Function }]

export function createContainer(
klass: string,
defaultTitle: string,
md: any // MarkdownIt
): ContainerArgs {
return [
container,
klass,
{
render(tokens: any, idx: any, _options: any, env: any) {
const token = tokens[idx]
const info = token.info.trim().slice(klass.length).trim()
const attrs = md.renderer.renderAttrs(token)
if (token.nesting === 1) {
const title = md.renderInline(info || defaultTitle, {
references: env.references,
})
if (klass === 'details')
return `<details class="${klass} custom-block"${attrs}><summary>${title}</summary>\n`
return `<div class="${klass} custom-block"${attrs}><p class="custom-block-title">${title}</p>\n`
} else return klass === 'details' ? `</details>\n` : `</div>\n`
},
},
]
}
Loading

0 comments on commit 98e90a5

Please sign in to comment.