diff --git a/README.md b/README.md index 87aab49..1e03635 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,6 @@ Then you can use it like `vitepress` yarn global add vitepress-dg ``` -### ## License diff --git a/src/client/theme-default/styles/code.css b/src/client/theme-default/styles/code.css index 873b790..999b631 100644 --- a/src/client/theme-default/styles/code.css +++ b/src/client/theme-default/styles/code.css @@ -5,6 +5,9 @@ code { padding: 0.25rem 0.5rem; border-radius: 3px; margin: 0; + padding: 2px 5px; + color: #d56161; + background: #f6f7f9; } code .token.deleted { diff --git a/src/client/theme-default/styles/custom-blocks.css b/src/client/theme-default/styles/custom-blocks.css index 85cba91..8f0cb79 100644 --- a/src/client/theme-default/styles/custom-blocks.css +++ b/src/client/theme-default/styles/custom-blocks.css @@ -6,44 +6,44 @@ .custom-block.tip, .custom-block.warning, .custom-block.danger { - padding: 0.1rem 1.5rem; - border-left-width: 0.5rem; + padding: 10px 20px; + border-left-width: 3px; border-left-style: solid; - margin: 1rem 0; + margin: 12px 0 24px 0; + box-shadow: 0 6px 16px -2px rgba(0, 0, 0, 0.06); + background-color: #fff; + font-size: 14px; +} + +.custom-block p { + line-height: 1; + margin: 0; } .custom-block.tip { - background-color: #f3f5f7; border-color: #42b983; } .custom-block.warning { - background-color: rgba(255, 229, 100, 0.3); - border-color: #e7c000; - color: #6b5900; + border-color: #ffc121; } .custom-block.warning .custom-block-title { color: #b29400; } -.custom-block.warning a { - color: var(--text-color); +.custom-block a { + color: var(--accent-color); } .custom-block.danger { - background-color: #ffe6e6; border-color: #c00; - color: #4d0000; } .custom-block.danger .custom-block-title { color: #900; } -.custom-block.danger a { - color: var(--text-color); -} .custom-block.details { display: block; diff --git a/src/client/theme-default/styles/vars.css b/src/client/theme-default/styles/vars.css index de9631f..aa95bc1 100644 --- a/src/client/theme-default/styles/vars.css +++ b/src/client/theme-default/styles/vars.css @@ -1,12 +1,13 @@ .theme { --border-color: #ebedf1; --header-height: 3.6rem; - --sidebar-width: 20rem; + --sidebar-width: 16rem; --slug-width: 10rem; --text-color: #454d64; --text-color-light: #476582; --code-bg-color: #f9fafb; - --accent-color: #3eaf7c; + /* --accent-color: #3eaf7c; */ + --accent-color: #4569d4; --placeholder-color: #c0c4cc; /* responsive breakpoints */ diff --git a/src/node/build/build.ts b/src/node/build/build.ts index 7103ac7..08b9386 100644 --- a/src/node/build/build.ts +++ b/src/node/build/build.ts @@ -39,15 +39,19 @@ export async function build(buildOptions: BuildOptions = {}) { const hashMapStirng = JSON.stringify(JSON.stringify(pageToHashMap)) for (const page of siteConfig.pages) { - await renderPage( - siteConfig, - page, - clientResult, - appChunk, - cssChunk, - pageToHashMap, - hashMapStirng - ) + try { + await renderPage( + siteConfig, + page, + clientResult, + appChunk, + cssChunk, + pageToHashMap, + hashMapStirng + ) + } catch { + // + } } } finally { await fs.remove(siteConfig.tempDir) diff --git a/src/node/genTemporary.ts b/src/node/genTemporary.ts deleted file mode 100644 index 4a978c7..0000000 --- a/src/node/genTemporary.ts +++ /dev/null @@ -1,136 +0,0 @@ -import globby from 'globby' -import fsExtra from 'fs-extra' -import { cachedRead, ServerConfig } from 'vite' -import { basename, extname, join } from 'path' -import { resolveConfig } from './' -import matter from 'gray-matter' -import { clearSuffix } from './utils/parseHeader' -import { LocaleConfig } from '/@types/shared' - -export const TempFileName = '.temp' -export const DefaultSrcIncludes = ['src'] - -// generate a .temp dir -export async function genTemporary(options: ServerConfig = {}) { - const root = options.root! - const config = await resolveConfig(join(root, '..')) - const userConfig = config.userConfig - const langToPathMapping = getLangToPathMapping( - userConfig.locales ?? userConfig.themeConfig?.locales, - config.userConfig.lang - ) - - const { - userConfig: { srcIncludes: srcIncludes = DefaultSrcIncludes } - } = config - - await fsExtra.remove(root) - await fsExtra.ensureDir(root) - - await Promise.all([ - copyDocs(root, langToPathMapping), - copySrc(root, srcIncludes, langToPathMapping) - ]) - - console.log('copy done.') -} - -// copy all file at root to .temp dir -async function copyDocs( - root: string, - langToPathMapping: Record | null -) { - const docsPath = join(root, '..') - const files = await globby([`**`, `!${TempFileName}`, '!dist'], { - dot: true, - cwd: docsPath - }) - files.forEach((file) => { - const descFile = join(root, tolocalePath(langToPathMapping, file)) - // console.log(file + ' -> ' + descFile) - fsExtra.copy(join(docsPath, file), descFile) - }) -} - -// copy userConfig.includes (default to ['src']) *.md to .temp -// dest file is frontmatter.map?.path or real path at .temp -async function copySrc( - root: string, - srcIncludes: string[], - langToPathMapping: Record | null -) { - const srcPaths = srcIncludes.map((src) => `${clearSuffix(src)}/**/*.md`) - const files = await globby(srcPaths, { - dot: true, - cwd: process.cwd(), - ignore: ['node_modules', '**/node_modules'] - }) - - await Promise.all( - files.map(async (file) => { - const fileBuffer = await cachedRead(null, file) - const { data: frontmatter, content } = matter(fileBuffer) - - const fileName = basename(file) - let destPath = file - if (frontmatter.map?.path) { - destPath = frontmatter.map?.path - // maybe path includes fileName - if (!destPath.endsWith(fileName)) { - destPath = join(destPath, fileName) - } - } - frontmatter.map = { - ...frontmatter.map, - realPath: file - } - const destFile = join(root, tolocalePath(langToPathMapping, destPath)) - - // console.log(file + ' -> ' + destFile) - - await fsExtra.ensureFile(destFile) - await fsExtra.writeFile(destFile, matter.stringify(content, frontmatter)) - }) - ) -} - -// resolve a mapping from localeConfig -// like { 'zh-CN: '/', 'en-US': '/en/', '': '/' } -function getLangToPathMapping( - locale: Record | undefined, - lang: string | undefined -) { - if (!locale) { - return null - } - const mapping = Object.entries(locale).reduce((map, [path, localeConfig]) => { - map[localeConfig.lang] = path.slice(1) - return map - }, {} as Record) - - // ensure default lang - let defaultLangPrefix - if (lang && mapping[lang]) { - defaultLangPrefix = mapping[lang] - } else { - defaultLangPrefix = Object.values(mapping)[0] - } - mapping[''] = defaultLangPrefix - - return mapping -} - -// resolve /comp/foo.zh-CN.md -> /zh/comp/foo.md -function tolocalePath(mapping: Record | null, path: string) { - if (!mapping) { - return path - } - const fileName = basename(path) - // .md - const ext = extname(fileName) - // .zh-CN - const lang = extname(fileName.slice(0, -ext.length)) - // en/ - const langPrefix = mapping[lang.slice(1)] - return `${langPrefix}${path.slice(0, -(ext + lang).length)}${ext}` -} diff --git a/src/node/index.ts b/src/node/index.ts index d7cee32..301354c 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -1,4 +1,4 @@ export * from './server' export * from './build/build' export * from './config' -export * from './genTemporary' +export * from './temporary/genTemp' diff --git a/src/node/markdown/plugins/containers.ts b/src/node/markdown/plugins/containers.ts index be9cf48..4c598ef 100644 --- a/src/node/markdown/plugins/containers.ts +++ b/src/node/markdown/plugins/containers.ts @@ -29,11 +29,9 @@ function createContainer(klass: string, defaultTitle: string): ContainerArgs { { render(tokens, idx) { const token = tokens[idx] - const info = token.info.trim().slice(klass.length).trim() + // const info = token.info.trim().slice(klass.length).trim() if (token.nesting === 1) { - return `

${ - info || defaultTitle - }

\n` + return `
` } else { return `
\n` } diff --git a/src/node/resolver.ts b/src/node/resolver.ts index a3c165b..fe3f632 100644 --- a/src/node/resolver.ts +++ b/src/node/resolver.ts @@ -1,7 +1,7 @@ import path from 'path' import { Resolver } from 'vite' import { UserConfig } from './config' -import { DefaultSrcIncludes } from './genTemporary' +import { DefaultSrcIncludes } from './temporary/genTemp' import { clearSuffix } from './utils/parseHeader' export const APP_PATH = path.join(__dirname, '../client/app') diff --git a/src/node/temporary/copy.ts b/src/node/temporary/copy.ts new file mode 100644 index 0000000..c267ef9 --- /dev/null +++ b/src/node/temporary/copy.ts @@ -0,0 +1,112 @@ +import matter from 'gray-matter' +import { clearSuffix } from '../utils/parseHeader' +import globby from 'globby' +import fsExtra from 'fs-extra' +import { cachedRead } from 'vite' +import { basename, extname, join } from 'path' +import { TempFileName } from './genTemp' +import chokidar from 'chokidar' + +// copy userConfig.includes (default to ['src']) *.md to .temp +// dest file is frontmatter.map?.path or real path at .temp +export async function copyAndWatchSrc( + root: string, + srcIncludes: string[], + langToPathMapping: Record | null +) { + const srcPaths = srcIncludes.map((src) => `${clearSuffix(src)}/**/*.md`) + const files = await globby(srcPaths, { + dot: true, + cwd: process.cwd(), + ignore: ['node_modules', '**/node_modules'] + }) + + async function injectMatterAndCopy(file: string, isRemove?: boolean) { + const fileBuffer = await cachedRead(null, file) + const { data: frontmatter, content } = matter(fileBuffer) + + const fileName = basename(file) + let destPath = file + if (frontmatter.map?.path) { + destPath = frontmatter.map?.path + // maybe path includes fileName + if (!destPath.endsWith(fileName)) { + destPath = join(destPath, fileName) + } + } + frontmatter.map = { + ...frontmatter.map, + realPath: file + } + const destFile = join(root, tolocalePath(langToPathMapping, destPath)) + + if (isRemove) { + // console.log('remove' + destFile) + await fsExtra.remove(destFile) + } else { + // console.log(file + ' -> ' + destFile) + await fsExtra.ensureFile(destFile) + await fsExtra.writeFile(destFile, matter.stringify(content, frontmatter)) + } + } + + await Promise.all(files.map((file) => injectMatterAndCopy(file))) + + chokidar + .watch(srcPaths, { + cwd: process.cwd(), + ignored: ['node_modules', '**/node_modules'] + }) + .on('change', (file) => injectMatterAndCopy(file)) + .on('add', (file) => injectMatterAndCopy(file)) + .on('unlink', (file) => injectMatterAndCopy(file, true)) +} + +// copy all file at root to .temp dir +export async function copyAndWatchRoot( + root: string, + langToPathMapping: Record | null +) { + const docsPath = join(root, '..') + const files = await globby([`**`, `!${TempFileName}`, '!dist'], { + dot: true, + cwd: docsPath + }) + + function copyFile(file: string, isRemove?: boolean) { + const descFile = join(root, tolocalePath(langToPathMapping, file)) + if (isRemove) { + // console.log('remove ' + descFile) + fsExtra.remove(descFile) + } else { + // console.log(file + ' -> ' + descFile) + fsExtra.copy(join(docsPath, file), descFile) + } + } + + await Promise.all(files.map((file) => copyFile(file))) + + chokidar + .watch('.', { + cwd: docsPath, + ignored: [`${TempFileName}`, 'dist'] + }) + .on('change', (file) => copyFile(file)) + .on('add', (file) => copyFile(file)) + .on('unlink', (file) => copyFile(file, true)) +} + +// resolve /comp/foo.zh-CN.md -> /zh/comp/foo.md +function tolocalePath(mapping: Record | null, path: string) { + if (!mapping) { + return path + } + const fileName = basename(path) + // .md + const ext = extname(fileName) + // .zh-CN + const lang = extname(fileName.slice(0, -ext.length)) + // en/ + const langPrefix = mapping[lang.slice(1)] + return `${langPrefix}${path.slice(0, -(ext + lang).length)}${ext}` +} diff --git a/src/node/temporary/genTemp.ts b/src/node/temporary/genTemp.ts new file mode 100644 index 0000000..e0206c2 --- /dev/null +++ b/src/node/temporary/genTemp.ts @@ -0,0 +1,60 @@ +import fsExtra from 'fs-extra' +import { ServerConfig } from 'vite' +import { resolveConfig } from '..' +import { LocaleConfig } from '/@types/shared' +import { copyAndWatchRoot, copyAndWatchSrc } from './copy' +import { join } from 'path' + +export const TempFileName = '.temp' +export const DefaultSrcIncludes = ['src'] + +// generate a .temp dir +export async function genTemporary(options: ServerConfig = {}) { + const root = options.root! + const config = await resolveConfig(join(root, '..')) + const userConfig = config.userConfig + const langToPathMapping = getLangToPathMapping( + userConfig.locales ?? userConfig.themeConfig?.locales, + config.userConfig.lang + ) + + const { + userConfig: { srcIncludes: srcIncludes = DefaultSrcIncludes } + } = config + + await fsExtra.remove(root) + await fsExtra.ensureDir(root) + + await Promise.all([ + copyAndWatchRoot(root, langToPathMapping), + copyAndWatchSrc(root, srcIncludes, langToPathMapping) + ]) + + console.log('copy done.') +} + +// resolve a mapping from localeConfig +// like { 'zh-CN: '/', 'en-US': '/en/', '': '/' } +function getLangToPathMapping( + locale: Record | undefined, + lang: string | undefined +) { + if (!locale) { + return null + } + const mapping = Object.entries(locale).reduce((map, [path, localeConfig]) => { + map[localeConfig.lang] = path.slice(1) + return map + }, {} as Record) + + // ensure default lang + let defaultLangPrefix + if (lang && mapping[lang]) { + defaultLangPrefix = mapping[lang] + } else { + defaultLangPrefix = Object.values(mapping)[0] + } + mapping[''] = defaultLangPrefix + + return mapping +}