2024-07-10 00:56:53 +08:00

91 lines
2.7 KiB
TypeScript

import type { App, Page } from 'vuepress/core'
import { createFilter } from 'create-filter'
import { removeLeadingSlash } from '@vuepress/helper'
import { logger, normalizePath, resolveContent, writeTemp } from '../utils/index.js'
import type {
PlumeThemeBlogPostData,
PlumeThemeBlogPostItem,
PlumeThemeEncrypt,
PlumeThemeLocaleOptions,
PlumeThemePageData,
PlumeThemePostFrontmatter,
} from '../../shared/index.js'
import { resolveNotesOptions } from '../config/index.js'
import { isEncryptPage } from './prepareEncrypt.js'
const HEADING_RE = /<h(\d)[^>]*>.*?<\/h\1>/gi
const EXCERPT_SPLIT = '<!-- more -->'
function getTimestamp(time: Date): number {
return new Date(time).getTime()
}
export async function preparedBlogData(
app: App,
localeOptions: PlumeThemeLocaleOptions,
encrypt?: PlumeThemeEncrypt,
): Promise<void> {
const start = performance.now()
const blog = localeOptions.blog || {}
const notesList = resolveNotesOptions(localeOptions)
const notesDirList = notesList
.map(notes => removeLeadingSlash(normalizePath(`${notes.dir}/**`)))
.filter(Boolean)
const filter = createFilter(
blog.include ?? ['**/*.md'],
[
'**/{README,readme,index}.md',
'.vuepress/',
'node_modules/',
...(blog.exclude ?? []),
...notesDirList,
].filter(Boolean),
{ resolve: false },
)
const pages = app.pages.filter(page =>
page.filePathRelative
&& filter(page.filePathRelative)
&& page.frontmatter.draft !== true,
).sort((prev, next) =>
getTimestamp((prev.frontmatter.createTime as Date) || prev.date)
< getTimestamp(next.frontmatter.createTime as Date || next.date)
? 1
: -1,
) as Page<PlumeThemePageData, PlumeThemePostFrontmatter>[]
const blogData: PlumeThemeBlogPostData = pages.map((page) => {
const tags = page.frontmatter.tags
const data: PlumeThemeBlogPostItem = {
path: page.path,
title: page.title,
categoryList: page.data.categoryList,
tags,
sticky: page.frontmatter.sticky,
createTime: page.data.frontmatter.createTime! || page.date?.replaceAll('-', '/') || '',
lang: page.lang,
excerpt: '',
}
isEncryptPage(page, encrypt) && (data.encrypt = true)
if (page.contentRendered.includes(EXCERPT_SPLIT)) {
const contents = page.contentRendered.split(EXCERPT_SPLIT)
let excerpt = contents[0]
// 删除摘要中的标题
excerpt = excerpt.replace(HEADING_RE, '')
data.excerpt = excerpt
}
return data
})
const content = resolveContent(app, { name: 'blogPostData', content: blogData })
await writeTemp(app, 'internal/blogData.js', content)
if (app.env.isDebug)
logger.info(`prepare blog data time spent: ${(performance.now() - start).toFixed(2)}ms`)
}