diff --git a/packages/duoyun-ui/docs/.gitignore b/packages/duoyun-ui/docs/.gitignore deleted file mode 100644 index 7dfce7af..00000000 --- a/packages/duoyun-ui/docs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/* -!.* -!/*/ -!template.html \ No newline at end of file diff --git a/packages/gem-book/docs/zh/002-guide/002-i18n.md b/packages/gem-book/docs/zh/002-guide/002-i18n.md index 614fa17e..b71337a1 100644 --- a/packages/gem-book/docs/zh/002-guide/002-i18n.md +++ b/packages/gem-book/docs/zh/002-guide/002-i18n.md @@ -1,21 +1,27 @@ # 国际化 -只需要将文档移动到以语言代码命名的文件夹中即可,例如: - -``` -docs/ -├── en -│ ├── 002-guide -│ │ ├── README.md -│ │ └── installation.md -│ ├── 003-about.md -│ └── README.md -└── zh - ├── 002-guide - │ ├── README.md - │ └── installation.md - └── README.md -``` +GemBook 很容易让文档站支持多语言,语言代码显示在 URL 路径中:`/{lang}/path`。 +访问网站时如果路径中包含语言代码,则会显示该语言版本,如果没有则根据浏览器设置选择最合适的语言并进行重定向。 + +## 启用国际化 + +1. 使用 [`--i18n`](./003-cli.md#--i18n) 启用国际化,这让 GemBook 自动重定向 +2. 将文档移动到以语言代码命名的文件夹中,例如: + + ``` + docs/ + ├── en + │ ├── 002-guide + │ │ ├── README.md + │ │ └── installation.md + │ ├── 003-about.md + │ └── README.md + └── zh + ├── 002-guide + │ ├── README.md + │ └── installation.md + └── README.md + ``` 语言代码的支持请查看[这里](https://github.com/mantou132/gem/tree/master/packages/gem-book/src/bin/lang.json)。 diff --git a/packages/gem-book/docs/zh/002-guide/003-cli.md b/packages/gem-book/docs/zh/002-guide/003-cli.md index 7c59d78a..a5df7f83 100644 --- a/packages/gem-book/docs/zh/002-guide/003-cli.md +++ b/packages/gem-book/docs/zh/002-guide/003-cli.md @@ -12,7 +12,7 @@ npx gem-book -h > [!TIP] > 如果用 `json` 格式,可以添加 `"$schema": "https://unpkg.com/gem-book/schema.json"` 以获取类型提示, -> 如果使用 `js` 格式,可以导入类型 `import('gem-book/common/config').CliConfig`。 +> 如果使用 `js` 格式,可以使用 [jsdoc](https://jsdoc.app/tags-type) 导入类型 `import('gem-book/common/config').CliConfig`。 ## 命令行选项 @@ -26,7 +26,7 @@ npx gem-book -h #### `-o, --output ` -指定输出文件目录,默认为指定的文档目录;如果是 `json` 文件路径则只输出 [`json`](#--json) 文件。 +指定输出文件目录,默认是 `dist`;如果是 `json` 文件路径则只输出 [`json`](#--json) 文件。 #### `--github ` @@ -38,7 +38,7 @@ npx gem-book -h #### `--base ` -指定项目的基础目录,默认会读取 `package.json` 的 `repository.directory` 字段,这在 monorepo 项目中很有用。 +指定项目的基础目录,默认会读取 `package.json` 的 `repository.directory` 字段,这在 Monorepo 项目中很有用。 #### `-d, --source-dir ` @@ -47,7 +47,7 @@ npx gem-book -h #### `--build` -输出所有前端资源。 +构建文档站。 #### `--home-mode` @@ -69,7 +69,7 @@ npx gem-book docs \ #### `--template ` -指定 HTML 模版路径,可以在模版中执行额外的 `Javascript` 或者其他 `meta` 元素。 +指定 HTML 模版路径,可以在模版中执行额外的 JavaScript 或者插入一些元素。 #### `--i18n` @@ -77,7 +77,7 @@ npx gem-book docs \ #### `--plugin ` -加载插件,可添加多个。也可以使用 URL 或者相对路径提供自定义插件。 +加载插件,可添加多个。也可以使用 URL 或者相对路径提供自定义插件,支持 TypeScript 模块。 #### `--theme ` @@ -85,7 +85,7 @@ npx gem-book docs \ #### `--footer ` -使用 Markdown 自定义渲染页脚。 +自定义页脚,支持 Markdown 格式。 #### `--display-rank` diff --git a/packages/gem-book/docs/zh/002-guide/005-theme.md b/packages/gem-book/docs/zh/002-guide/005-theme.md index 7b9dd846..91267329 100644 --- a/packages/gem-book/docs/zh/002-guide/005-theme.md +++ b/packages/gem-book/docs/zh/002-guide/005-theme.md @@ -8,7 +8,7 @@ ## 自定义主题 -可以直接使用命令行参数提供 `json`/`CommonJs/ESM` 格式的主题文件路径或者[内置主题](https://github.com/mantou132/gem/tree/master/packages/gem-book/themes)名称: +可以直接使用命令行参数提供 `JSON`/`CommonJS`/`ESM` 格式的主题文件路径或者[内置主题](https://github.com/mantou132/gem/tree/master/packages/gem-book/themes)名称: ```bash gem-book docs --theme path/my-theme.mjs diff --git a/packages/gem-book/docs/zh/002-guide/006-deploy.md b/packages/gem-book/docs/zh/002-guide/006-deploy.md index cd71e657..2697b0e4 100644 --- a/packages/gem-book/docs/zh/002-guide/006-deploy.md +++ b/packages/gem-book/docs/zh/002-guide/006-deploy.md @@ -1,13 +1,13 @@ # 部署 -只需要使用 `--build` 构建前端资源(`index.html`,`*.js`...),然后为输出目录提供静态服务即可。 +只需要使用 `--build` 构建前端资源(`index.html`,`*.js`...),然后为输出目录(默认为 `dist`)提供静态服务即可。 > [!WARNING] > 由于 `` 使用了 [History API](https://developer.mozilla.org/en-US/docs/Web/API/History),所以默认不支持 Github Pages ## Netlify -Netlify 中配置构建脚本(`gem-book docs --build`)和发布目录(`docs`),然后在项目中 `netlify.toml` 配置重定向规则: +Netlify 中配置构建脚本(`gem-book docs --build`)和输出目录,然后在项目中 `netlify.toml` 配置重定向规则: ```toml [[redirects]] @@ -18,7 +18,7 @@ Netlify 中配置构建脚本(`gem-book docs --build`)和发布目录(`doc ## Vercel -Vercel 中配置构建脚本(`gem-book docs --build`)和发布目录(`docs`),然后在项目中 `vercel.json` 配置重定向规则: +Vercel 中配置构建脚本(`gem-book docs --build`)和输出目录,然后在项目中 `vercel.json` 配置重定向规则: ```json { diff --git a/packages/gem-book/docs/zh/002-guide/007-extension.md b/packages/gem-book/docs/zh/002-guide/007-extension.md index 72585a7a..4b361f21 100644 --- a/packages/gem-book/docs/zh/002-guide/007-extension.md +++ b/packages/gem-book/docs/zh/002-guide/007-extension.md @@ -1,9 +1,9 @@ # 扩展 -GemBook 使用 [`marked`](https://github.com/markedjs/marked) 渲染 Markdown,默认支持 [CommonMark](http://spec.commonmark.org/0.30/) 和 [GitHub Flavored Markdown](https://github.github.com/gfm/),GemBook 扩展了 Markdown 语法,另外还提供一些方法让用户自定义 GemBook。 - ## Markdown 增强 +GemBook 使用 [`marked`](https://github.com/markedjs/marked) 渲染 Markdown,默认支持 [CommonMark](http://spec.commonmark.org/0.30/) 和 [GitHub Flavored Markdown](https://github.github.com/gfm/),GemBook 扩展了 Markdown 语法。 + ### 代码块信息 ````md @@ -35,14 +35,24 @@ GemBook 使用 [`marked`](https://github.com/markedjs/marked) 渲染 Markdown, ### 高亮引用块 ```md -> [!TIP] -> 这是[高亮引用块](https://github.com/orgs/community/discussions/16925) +> [!NOTE] +> 这是 [高亮引用块](https://github.com/orgs/community/discussions/16925) ``` +> [!NOTE] +> 这是 `[!NOTE]` + > [!TIP] -> 这是[高亮引用块](https://github.com/orgs/community/discussions/16925) +> 这是 `[!TIP]` + +> [!IMPORTANT] +> 这是 `[!IMPORTANT]` + +> [!WARNING] +> 这是 `[!WARNING]` -支持 `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]` 和 `[!CAUTION]`。 +> [!CAUTION] +> 这是 `[!CAUTION]` ## 插槽 @@ -51,7 +61,7 @@ GemBook 使用 [`marked`](https://github.com/markedjs/marked) 渲染 Markdown, > [!NOTE] -> 使用 `--template` 指定模板文件才能使用插槽 +> 使用 [`--template`](./003-cli.md#--template-path) 指定模板文件才能使用插槽 ## 插件 {#plugins} diff --git a/packages/gem-book/docs/zh/002-guide/README.md b/packages/gem-book/docs/zh/002-guide/README.md index b014efc3..9b613d29 100644 --- a/packages/gem-book/docs/zh/002-guide/README.md +++ b/packages/gem-book/docs/zh/002-guide/README.md @@ -9,6 +9,8 @@ GemBook 将 [Markdown](https://zh.wikipedia.org/wiki/Markdown) 内容渲染成 ## 快速开始 +可以直接在 [StackBlitz](https://stackblitz.com/edit/node-c7iw5d?file=README.md) 上进行在线尝试。 + > [!WARNING] GemBook 依赖 [Node.js v18+](https://nodejs.org/),请确保 `node -v` 命令能够执行 ```bash @@ -44,19 +46,17 @@ npx gem-book docs -t MyApp -i logo.png --home-mode --build --output dist 上面的命令使用 `webpack` 打包完整的前端项目,但你也可以直接在 HTML 中使用 `` 元素。 ```bash -# 仅生成 需要的 json 文件 -npx gem-book docs -t MyApp -i logo.png --home-mode --build --json - # 安装成依赖 npm install gem-book + +# 仅生成 需要的 json 文件 +npx gem-book docs -t MyApp -i logo.png --home-mode --build --json ``` 然后在你的项目中使用 ``: ```js import { html, render } from '@mantou/gem'; - -// 导入 import 'gem-book'; import config from './gem-book.json'; diff --git a/packages/gem-book/package.json b/packages/gem-book/package.json index eb2af9ec..17cf9815 100644 --- a/packages/gem-book/package.json +++ b/packages/gem-book/package.json @@ -1,6 +1,6 @@ { "name": "gem-book", - "version": "1.5.28", + "version": "1.5.30", "description": "Create your document website easily and quickly", "keywords": [ "doc", @@ -28,7 +28,7 @@ ], "scripts": { "schema": "npx ts-json-schema-generator -p src/common/config.ts -t CliConfig -o schema.json", - "build:cli": "esbuild ./src/bin/index.ts --outdir=./bin --platform=node --sourcemap --bundle --external:jsdom --external:lodash --external:yaml --external:front-matter --external:commander --external:webpack --external:ts-loader --external:typescript --external:webpack-dev-server --external:html-webpack-plugin --external:copy-webpack-plugin --external:workbox-webpack-plugin", + "build:cli": "esbuild ./src/bin/index.ts --outdir=./bin --platform=node --sourcemap --bundle --external:jsdom --external:anymatch --external:chokidar --external:jimp --external:marked --external:yaml --external:front-matter --external:commander --external:webpack --external:ts-loader --external:typescript --external:webpack-dev-server --external:html-webpack-plugin --external:copy-webpack-plugin --external:workbox-webpack-plugin", "start:cli": "yarn build:cli --watch", "docs": "node ./bin docs", "start:docs": "cross-env PORT=8090 GEM_BOOK_DEV=true nodemon --watch bin --exec \"yarn docs\"", @@ -40,6 +40,8 @@ }, "dependencies": { "@mantou/gem": "^1.7.8", + "anymatch": "^3.1.3", + "chokidar": "^3.5.3", "commander": "^7.2.0", "copy-webpack-plugin": "^11.0.0", "front-matter": "^4.0.2", @@ -48,7 +50,6 @@ "html-webpack-plugin": "^5.5.3", "jimp": "^0.16.1", "jsdom": "^16.5.3", - "lodash": "^4.17.21", "marked": "^10.0.0", "chalk": "^2.4.2", "mkdirp": "^1.0.4", @@ -66,7 +67,6 @@ "@gemjs/config": "^1.6.11", "@open-wc/testing": "^2.5.33", "@types/jsdom": "^16.2.10", - "@types/lodash": "^4.14.169", "@types/marked": "^2.0.2", "@types/mkdirp": "^1.0.1", "@types/parse-github-url": "^1.0.0", diff --git a/packages/gem-book/src/bin/builder.ts b/packages/gem-book/src/bin/builder.ts index 4ca542d8..118f4e6c 100644 --- a/packages/gem-book/src/bin/builder.ts +++ b/packages/gem-book/src/bin/builder.ts @@ -7,7 +7,6 @@ import WebpackDevServer from 'webpack-dev-server'; import HtmlWebpackPlugin from 'html-webpack-plugin'; import CopyWebpackPlugin from 'copy-webpack-plugin'; import { GenerateSW } from 'workbox-webpack-plugin'; -import chalk from 'chalk'; import { BookConfig, CliUniqueConfig } from '../common/config'; import { STATS_FILE } from '../common/constant'; @@ -38,7 +37,8 @@ export async function startBuilder(dir: string, options: Required = { icon: '', - output: '', + output: DEFAULT_OUTPUT, i18n: false, plugin: [], ga: '', template: '', theme: '', build: false, + ignored: ['**/node_modules/**'], json: false, debug: false, config: '', @@ -64,7 +72,7 @@ let cliConfig: Required = { // 将配置文件和 cli 选项合并,并将 book 选项同步到 bookConfig async function syncConfig(fullPath?: string) { - const obj: CliConfig = (await importObject(resolveModule(fullPath))) || {}; + const obj: CliConfig = (await importObject(fullPath)) || {}; Object.keys(cliConfig).forEach((key: keyof CliUniqueConfig) => { if (key in obj) { const value = obj[key]; @@ -106,6 +114,7 @@ function readFiles(filenames: string[], dir: string, link: string, config?: Fron }) .forEach((filename) => { const fullPath = path.join(dir, filename); + if (anymatch(cliConfig.ignored, fullPath)) return; if (fs.statSync(fullPath).isFile()) { if (isMdFile(fullPath)) { if (cliConfig.debug) { @@ -216,6 +225,8 @@ async function generateBookConfig(dir: string) { data: readDir(path.join(docsRootDir, code)), name: lang[code as keyof typeof lang], }; + } else { + print(chalk.yellow(`Not support lang: ${code}`)); } } }); @@ -298,6 +309,9 @@ program .option('--plugin ', 'load plugin', (name: string) => { cliConfig.plugin.push(name); }) + .option('--ignored ', 'html template path', (path) => { + cliConfig.ignored.push(path); + }) .option('--ga ', 'google analytics ID', (id: string) => { cliConfig.ga = id; }) @@ -333,80 +347,88 @@ program docsRootDir = path.resolve(process.cwd(), dir); - const configPath = resolveModule(cliConfig.config || DEFAULT_CLI_FILE); + const configPath = resolveModule(cliConfig.config || DEFAULT_CLI_FILE, { silent: !cliConfig.config }); + if (cliConfig.config && !configPath) process.exit(1); + await syncConfig(configPath); await generateBookConfig(dir); - const updateBookConfig = throttle(async () => { - await generateBookConfig(dir); - devServerEventTarget.dispatchEvent( - Object.assign(new Event(UPDATE_EVENT), { - detail: { config: bookConfig }, - }), - ); - }, 100); + let updateBookTimer: ReturnType; + const updateBookConfig = () => { + clearTimeout(updateBookTimer); + updateBookTimer = setTimeout(async () => { + await generateBookConfig(dir); + devServerEventTarget.dispatchEvent( + Object.assign(new Event(UPDATE_EVENT), { + detail: { config: bookConfig }, + }), + ); + }, 100); + }; const watchTheme = () => { const themePath = resolveTheme(cliConfig.theme); if (themePath) { - return fs.watch( - themePath, - throttle(async () => { - devServerEventTarget.dispatchEvent( - Object.assign(new Event(UPDATE_EVENT), { - detail: { theme: await importObject(themePath) }, - }), - ); - }, 100), - ); + return watch(themePath).on('change', async () => { + devServerEventTarget.dispatchEvent( + Object.assign(new Event(UPDATE_EVENT), { + detail: { theme: await importObject(themePath) }, + }), + ); + }); } }; let server = cliConfig.json ? undefined : await startBuilder(dir, cliConfig, bookConfig); if (!cliConfig.build) { - devServerEventTarget.addEventListener(UPDATE_EVENT, ({ detail }: CustomEvent) => { + devServerEventTarget.addEventListener(UPDATE_EVENT, ({ detail }: CustomEvent) => { server?.sendMessage(server.webSocketServer?.clients || [], UPDATE_EVENT, detail); }); let themeWatcher = watchTheme(); if (configPath) { - fs.watch( - configPath, - throttle(async () => { - cliConfig = structuredClone(initCliOptions); - bookConfig = structuredClone(initBookConfig); - await syncConfig(configPath); - await generateBookConfig(dir); - await server?.stop(); - server = await startBuilder(dir, cliConfig, bookConfig); - devServerEventTarget.dispatchEvent( - Object.assign(new Event(UPDATE_EVENT), { - detail: { config: bookConfig }, - }), - ); - themeWatcher?.close(); - themeWatcher = watchTheme(); - }, 100), - ); + watch(configPath).on('change', async () => { + cliConfig = structuredClone(initCliOptions); + bookConfig = structuredClone(initBookConfig); + await syncConfig(configPath); + await generateBookConfig(dir); + await server?.stop(); + server = await startBuilder(dir, cliConfig, bookConfig); + devServerEventTarget.dispatchEvent( + Object.assign(new Event(UPDATE_EVENT), { + detail: { config: bookConfig }, + }), + ); + await themeWatcher?.close(); + themeWatcher = watchTheme(); + }); } - fs.watch(dir, { recursive: true }, async (type, filePath) => { - if (filePath && !isDirConfigFile(filePath) && !isMdFile(filePath)) { + watch(dir, { + ignoreInitial: true, + ignored: cliConfig.ignored || undefined, + }).on('all', (type, filePathWithDir) => { + if (type !== 'change') { + return updateBookConfig(); + } + + const filePath = path.relative(dir, filePathWithDir); + + if (!isDirConfigFile(filePath) && !isMdFile(filePath)) { devServerEventTarget.dispatchEvent( Object.assign(new Event(UPDATE_EVENT), { detail: { reload: true }, }), ); + return; } - if (type === 'rename' || !filePath || isDirConfigFile(filePath)) { + if (isDirConfigFile(filePath)) { return updateBookConfig(); } - const { content, metadataChanged } = getFile(path.resolve(dir, filePath), bookConfig.displayRank); - // hot reload - // https://nodejs.org/api/events.html#class-customevent + const { content, metadataChanged } = getMdFile(path.join(docsRootDir, filePath), bookConfig.displayRank); devServerEventTarget.dispatchEvent( Object.assign(new Event(UPDATE_EVENT), { detail: { filePath, content }, diff --git a/packages/gem-book/src/bin/utils.ts b/packages/gem-book/src/bin/utils.ts index 036cf55d..ee62f140 100644 --- a/packages/gem-book/src/bin/utils.ts +++ b/packages/gem-book/src/bin/utils.ts @@ -10,12 +10,11 @@ import { JSDOM } from 'jsdom'; import { marked } from 'marked'; import fm from 'front-matter'; import YAML from 'yaml'; -import { startCase } from 'lodash'; import Jimp from 'jimp'; import chalk from 'chalk'; import { FrontMatter } from '../common/frontmatter'; -import { isIndexFile, parseFilename, CUSTOM_HEADING_REG } from '../common/utils'; +import { isIndexFile, parseFilename, parseTitle } from '../common/utils'; export async function getGithubUrl() { const repoDir = process.cwd(); @@ -46,7 +45,7 @@ export function getRepoTitle() { if (!repoPkg.title) throw 'no title'; return repoPkg.title; } catch { - return startCase(path.basename(process.cwd())); + return path.basename(process.cwd()).replace(/^./, ($1) => $1.toUpperCase()); } } @@ -73,7 +72,10 @@ export function resolveLocalPlugin(p: string) { if (p) print(chalk.red(`Plugin not found:`), p); } -export function resolveModule(p?: string, builtInDirs: string[] = []) { +export function resolveModule( + p?: string, + { builtInDirs = [], silent = false }: { builtInDirs?: string[]; silent?: boolean } = {}, +) { if (!p) return; const modulePath = [ @@ -84,14 +86,14 @@ export function resolveModule(p?: string, builtInDirs: string[] = []) { .flat() .find((e) => existsSync(e)); - if (!modulePath) print(chalk.red(`Module not found:`), p); + if (!silent && !modulePath) print(chalk.red(`Module not found:`), p); return modulePath; } // Prefer built-in export function resolveTheme(p: string) { - return resolveModule(p, ['../themes/']); + return resolveModule(p, { builtInDirs: ['../themes/'] }); } export async function importObject(fullPath?: string) { @@ -154,13 +156,10 @@ export function getHash(fullPath: string) { return hash.digest('hex').substring(0, 8); } -export function getFile(fullPath: string, displayRank: boolean | undefined) { - const content = fullPath ? readFileSync(fullPath, 'utf-8') : ''; +export function getMdFile(fullPath: string, displayRank: boolean | undefined) { return { - content, - metadataChanged: isMdFile(fullPath) - ? JSON.stringify(metadataRecord[fullPath]) !== JSON.stringify(getMetadata(fullPath, displayRank)) - : false, + content: readFileSync(fullPath, 'utf-8'), + metadataChanged: JSON.stringify(metadataRecord[fullPath]) !== JSON.stringify(getMetadata(fullPath, displayRank)), }; } @@ -181,7 +180,7 @@ export function getMetadata(fullPath: string, displayRank: boolean | undefined) const h1 = window.document.querySelector('h1'); return { ...(attributes as FrontMatter), - title: (attributes.title || h1?.textContent || getTitle()).match(CUSTOM_HEADING_REG)![1], + title: parseTitle(attributes.title || h1?.textContent || getTitle()).text, }; }; diff --git a/packages/gem-book/src/common/config.ts b/packages/gem-book/src/common/config.ts index 0d561e5f..916fa730 100644 --- a/packages/gem-book/src/common/config.ts +++ b/packages/gem-book/src/common/config.ts @@ -41,6 +41,7 @@ export interface CliUniqueConfig { plugin?: string[]; ga?: string; template?: string; + ignored?: string[]; theme?: string; build?: boolean; json?: boolean; diff --git a/packages/gem-book/src/common/constant.ts b/packages/gem-book/src/common/constant.ts index 8cca905f..827872b2 100644 --- a/packages/gem-book/src/common/constant.ts +++ b/packages/gem-book/src/common/constant.ts @@ -2,5 +2,6 @@ export const UPDATE_EVENT = 'gen-book-update'; export const DEFAULT_CLI_FILE = 'gem-book.cli'; export const DEFAULT_FILE = 'gem-book.json'; +export const DEFAULT_OUTPUT = 'dist'; export const STATS_FILE = 'stats.json'; export const DEFAULT_SOURCE_BRANCH = 'main'; diff --git a/packages/gem-book/src/common/utils.ts b/packages/gem-book/src/common/utils.ts index d2f22b3a..0ba0bd91 100644 --- a/packages/gem-book/src/common/utils.ts +++ b/packages/gem-book/src/common/utils.ts @@ -1,4 +1,7 @@ -export const CUSTOM_HEADING_REG = /^(.*?)\s*(?:{#(.*)})?$/s; +export function parseTitle(fullText: string) { + const [, text, customId] = fullText.match(/^(.*?)\s*(?:{#(.*)})?$/s)!; + return { text, customId }; +} export function normalizeId(text: string) { return text.trim().toLowerCase().replace(/\s+/g, '-').replaceAll('<', '').replaceAll('>', ''); diff --git a/packages/gem-book/src/element/elements/main.ts b/packages/gem-book/src/element/elements/main.ts index 54330a51..830d5fee 100644 --- a/packages/gem-book/src/element/elements/main.ts +++ b/packages/gem-book/src/element/elements/main.ts @@ -118,33 +118,29 @@ export class Main extends GemElement { margin-top: 0; } details { + background: rgba(${theme.noteColorRGB}, 0.05); border-radius: ${theme.normalRound}; - border: 1px solid ${theme.borderColor}; - padding: 0.5em 1em; + padding: 1rem; margin: 2rem 0; } details p:first-of-type { margin-block-start: 0; } - details p:first-of-type { + details p:last-of-type { margin-block-end: 0; } details[open] summary { - margin-block-end: 0.5em; - background: rgba(${theme.textColorRGB}, 0.02); - border-bottom: 1px solid ${theme.borderColor}; + margin-block-end: 0; } summary { + font-weight: bolder; cursor: pointer; - margin: -0.5em -1em; - padding: 0.5em 1em; + margin: -1rem; + padding: 1rem; } summary p { display: contents; } - summary:hover { - background: rgba(${theme.textColorRGB}, 0.02); - } a > img + svg { display: none; } @@ -315,7 +311,7 @@ export class Main extends GemElement { } h1 { font-size: 2.3rem; - margin: 0 0 1rem; + margin: 1rem 0 2rem; } } diff --git a/packages/gem-book/src/element/elements/meta.ts b/packages/gem-book/src/element/elements/meta.ts index 56a77036..01208938 100644 --- a/packages/gem-book/src/element/elements/meta.ts +++ b/packages/gem-book/src/element/elements/meta.ts @@ -2,6 +2,7 @@ import { connectStore, customElement, GemElement, html } from '@mantou/gem'; import { mediaQuery } from '@mantou/gem/helper/mediaquery'; import { getRemotePath, getURL } from '../lib/utils'; +import { themeStore } from '../helper/theme'; import { bookStore, locationStore } from '../store'; import '@mantou/gem/elements/reflect'; @@ -29,6 +30,7 @@ export class Meta extends GemElement { const description = isHomePage && navItem?.hero?.desc; return html` + ${description ? html`` : ''} ${mediaQuery.isDataReduce ? null diff --git a/packages/gem-book/src/element/elements/pre.ts b/packages/gem-book/src/element/elements/pre.ts index 19f77d94..caa55478 100644 --- a/packages/gem-book/src/element/elements/pre.ts +++ b/packages/gem-book/src/element/elements/pre.ts @@ -479,15 +479,12 @@ export class Pre extends GemElement { place-content: start; } .linenumber-ignore { - place-content: center; + place-content: flex-end; } .linenumber-ignore::before { - content: ''; - width: 2px; - height: 2px; - background: currentColor; + content: '·'; border-radius: 1em; - box-shadow: + text-shadow: 0 0.34em, 0 -0.34em; } diff --git a/packages/gem-book/src/element/elements/rel-link.ts b/packages/gem-book/src/element/elements/rel-link.ts index 08d1cc43..86e210ed 100644 --- a/packages/gem-book/src/element/elements/rel-link.ts +++ b/packages/gem-book/src/element/elements/rel-link.ts @@ -20,6 +20,7 @@ export class RelLink extends GemElement { const index = currentLinks.findIndex((item) => currentLink.originLink === item.originLink); const prev = currentLinks[index - 1]; const next = currentLinks[index + 1]; + if (!prev && !next) return null; return html`