From 4349ab023ca3762f521c33a04301aae39b6c102d Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 5 Apr 2024 00:15:46 +0800 Subject: [PATCH] docs: update doc --- .markdownlint.json | 5 +- docs/.vuepress/notes.ts | 15 +- docs/README.md | 2 +- docs/notes/plugins/README.md | 2 + docs/notes/plugins/md-power.md | 282 ++++ .../theme/config/plugins/markdownPower.md | 42 + .../theme/config/plugins/markdown增强.md | 2 +- docs/notes/theme/guide/markdown/扩展.md | 377 ------ docs/notes/theme/guide/markdown/进阶.md | 598 +-------- docs/notes/theme/guide/介绍.md | 4 +- docs/notes/theme/guide/代码/codeSandbox.md | 82 ++ docs/notes/theme/guide/代码/codepen.md | 89 ++ docs/notes/theme/guide/代码/jsFiddle.md | 73 + docs/notes/theme/guide/代码/replit.md | 64 + .../{markdown/试验性.md => 代码/twoslash.md} | 3 +- docs/notes/theme/guide/代码/介绍.md | 75 ++ docs/notes/theme/guide/代码/代码演示.md | 462 +++++++ docs/notes/theme/guide/代码/代码组.md | 72 + docs/notes/theme/guide/代码/导入代码.md | 44 + docs/notes/theme/guide/代码/特性支持.md | 247 ++++ docs/notes/theme/guide/安装与使用.md | 2 +- docs/notes/theme/guide/编写文章.md | 2 +- .../notes/theme/snippet/code-block.snippet.md | 1176 +++++++++++++++++ plugins/plugin-md-power/README.md | 38 + 24 files changed, 2771 insertions(+), 987 deletions(-) create mode 100644 docs/notes/plugins/md-power.md create mode 100644 docs/notes/theme/config/plugins/markdownPower.md create mode 100644 docs/notes/theme/guide/代码/codeSandbox.md create mode 100644 docs/notes/theme/guide/代码/codepen.md create mode 100644 docs/notes/theme/guide/代码/jsFiddle.md create mode 100644 docs/notes/theme/guide/代码/replit.md rename docs/notes/theme/guide/{markdown/试验性.md => 代码/twoslash.md} (99%) create mode 100644 docs/notes/theme/guide/代码/介绍.md create mode 100644 docs/notes/theme/guide/代码/代码演示.md create mode 100644 docs/notes/theme/guide/代码/代码组.md create mode 100644 docs/notes/theme/guide/代码/导入代码.md create mode 100644 docs/notes/theme/guide/代码/特性支持.md create mode 100644 docs/notes/theme/snippet/code-block.snippet.md diff --git a/.markdownlint.json b/.markdownlint.json index a991f3ff..967af391 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -21,5 +21,8 @@ }, "fenced-code-language": false, "code-block-style": false, - "emphasis-style": false + "emphasis-style": false, + "no-hard-tabs": { + "spaces_per_tab": 2 + } } diff --git a/docs/.vuepress/notes.ts b/docs/.vuepress/notes.ts index 9ff61d0c..fb958cae 100644 --- a/docs/.vuepress/notes.ts +++ b/docs/.vuepress/notes.ts @@ -12,20 +12,24 @@ export const zhNotes = definePlumeNotesConfig({ text: '快速开始', collapsed: false, icon: 'carbon:idea', - items: ['介绍', '安装与使用', '博客', '知识笔记', '部署'], + items: ['介绍', '安装与使用', '博客', '知识笔记', '编写文章', '国际化', '部署'], }, { text: '写作', icon: 'fluent-mdl2:edit-create', collapsed: false, items: [ - '编写文章', - '国际化', { text: 'markdown', icon: 'material-symbols:markdown-outline', dir: 'markdown', - items: ['基础', '扩展', '进阶', '试验性'], + items: ['基础', '扩展', '进阶'], + }, + { + text: '代码块', + dir: '代码', + icon: 'ph:code-bold', + items: ['介绍', '特性支持', '代码组', '导入代码', 'codepen', 'jsFiddle', 'codeSandbox', 'replit', 'twoslash', '代码演示'], }, { text: '图表', @@ -87,7 +91,7 @@ export const zhNotes = definePlumeNotesConfig({ text: '内置插件', dir: 'plugins', collapsed: false, - items: ['', '代码复制', '代码高亮', '搜索', '阅读统计', 'markdown增强', '百度统计'], + items: ['', '代码复制', '代码高亮', '搜索', '阅读统计', 'markdown增强', 'markdownPower', '百度统计'], }, ], }, @@ -102,6 +106,7 @@ export const zhNotes = definePlumeNotesConfig({ 'caniuse', 'iconify', 'shiki', + 'md-power', 'content-updated', { text: 'plugin-netlify-functions', diff --git a/docs/README.md b/docs/README.md index 60737bc4..ef215379 100644 --- a/docs/README.md +++ b/docs/README.md @@ -78,7 +78,7 @@ config: description: 支持全站加密、部分加密(加密目录、加密文章)。 - title: 代码 - description: 代码复制,CodePen演示,Replit演示 + description: 代码复制,CodePen演示,Replit演示,JSFiddle演示,CodeSandbox演示,\n代码组,行高亮,行聚焦,行警告,差异对比等。\n - title: 资源嵌入 description: 图表,视频,PDF diff --git a/docs/notes/plugins/README.md b/docs/notes/plugins/README.md index 534aa323..df6dacf3 100644 --- a/docs/notes/plugins/README.md +++ b/docs/notes/plugins/README.md @@ -14,4 +14,6 @@ permalink: /plugins/ - [@vuepress-plume/plugin-caniuse](/plugins/plugin-caniuse/) - [@vuepress-plume/plugin-iconify](/plugins/plugin-iconify/) - [@vuepress-plume/plugin-shikiji](/plugins/plugin-shikiji/) +- [@vuepress-plume/plugin-content-update](/plugins/plugin-content-update/) - [vuepress-plugin-netlify-functions](/plugins/plugin-netlify-functions/) +- [vuepress-plugin-md-power](/plugins/plugin-md-power/) diff --git a/docs/notes/plugins/md-power.md b/docs/notes/plugins/md-power.md new file mode 100644 index 00000000..4aa7243a --- /dev/null +++ b/docs/notes/plugins/md-power.md @@ -0,0 +1,282 @@ +--- +title: plugin-md-power +author: pengzhanbo +createTime: 2024/04/04 18:44:57 +permalink: /plugins/plugin-md-power/ +--- + +## 指南 + +插件为 vuepress markdown 注入更多的功能支持。 + +其中,`@[xxx](xx)` 形式的语法,主要用于 资源嵌入类型的支持,包括 嵌入 PDF、视频、代码演示等。 + +同时,还提供了其它的语法支持。 + +## 安装 + +::: code-tabs +@tab npm + +``` sh +npm install vuepress-plugin-md-power +``` + +@tab:active yarn + +``` sh +yarn add vuepress-plugin-md-power +``` + +@tab pnpm + +``` sh +pnpm add vuepress-plugin-md-power +``` + +::: + +## 使用 + +```ts +// .vuepress/config.ts +import { markdownPowerPlugin } from 'vuepress-plugin-md-power' +module.exports = { + // ... + plugins: [ + markdownPowerPlugin({ + pdf: true + }) + ] + // ... +} +``` + +## Options + +```ts +interface MarkdownPowerPluginOptions { + pdf?: boolean | PDFOptions + + // new syntax + icons?: boolean | IconsOptions + + // video embed + bilibili?: boolean + youtube?: boolean + + // code embed + codepen?: boolean + replit?: boolean + codeSandbox?: boolean + jsfiddle?: boolean + + caniuse?: boolean | CanIUseOptions +} +``` + +## 使用 + +### caniuse + +插件默认不启用该功能,你需要手动设置 `caniuse` 为 `true` + +#### 语法 + +```md +@[caniuse](feature) +@[caniuse image](feature) +@[caniuse embed{versions}](feature) +``` + +你可以从 [caniuse](https://caniuse.bitsofco.de/) 获取 feature 的值。 + +默认情况下,插件通过 `iframe` 嵌入 `caniuse` 的支持情况查看器。 +你也可以使用 `@[caniuse image](feature)` 直接嵌入图片。 + +caniuse 默认查看最近的5个浏览器版本。你可以通过 `{versions}` 手动设置查看的浏览器版本。 +格式为 `{number,number,...}`。取值范围为 `-5 ~ 3` 。 + +- 小于0 表示低于当前浏览器版本的支持情况 +- 0 表示当前浏览器版本的支持情况 +- 大于0 表示高于当前浏览器版本的支持情况 + +如 `{-2,-1,1,2}` 表示查看低于当前 2 个版本 到 高于当前 2 个版本的支持情况。 + +### pdf + +插件默认不启用该功能,你需要手动设置 `pdf` 为 `true` + +#### 语法 + +```md +@[pdf](url) +@[pdf 1](url) +@[pdf 1 no-toolbar width="100%" height="600px" zoom="1" ratio="16:9"](url) +``` + +`url` 只支持绝对路径以及完整的资源链接地址,请勿传入相对路径。 + +你可以在 `pdf` 后紧跟空格,设置一个数字表示默认显示的 pdf 页码 + +- `no-toolbar` 表示不显示工具栏 +- `width` 设置宽度 +- `height` 设置高度 +- `zoom` 设置缩放 +- `ratio` 设置宽高比, 仅当 `width` 有值, `height` 未设置时有效 + +### icons + +插件默认不启用该功能,你需要手动设置 `icons` 为 `true`。 + +你还需要手动安装 `@iconify/json` 依赖。 + +```sh +pnpm add @iconify/json +``` + +#### 语法 + +```md +:[collect:icon]: +:[collect:icon size]: +:[collect:icon /color]: +:[collect:icon size/color]: +``` + +你可以从 [icon-sets.iconify](https://icon-sets.iconify.design/) 获取 图标集。 + +显示 `logos` 图标集合下的 `vue` 图标 + +```md +:[logos:vue]: +``` + +图标默认大小为 `1em` ,你可以通过 `size` 设置图标大小 + +```md +:[logos:vue 1.2em]: +``` + +图标默认颜色为 `currentColor` 你可以通过 `/color` 设置图标颜色 + +```md +:[logos:vue /blue]: +``` + +也可以通过 `size/color` 设置图标大小和颜色 + +```md +:[logos:vue 1.2em/blue]: +``` + +### bilibili + +插件默认不启用该功能,你需要手动设置 `bilibili` 为 `true` + +#### 语法 + +```md +@[bilibili](bvid) +@[bilibili autoplay time="0"](bvid) +@[bilibili p1 autoplay time="0" ratio="16:9"](aid cid) +``` + +- 设置 `autoplay` 以自动播放视频。 +- 设置 `time` 以指定开始播放的时间点,单位为秒。还可以传入 `mm:ss` 或者 `hh:mm:ss`。 +- 如果为 分p(非合集),还可以设置 `p\d` (第\d 个分p),此时可以只传入 `aid` 和 `cid`。 +- 设置 `ratio` 以指定视频的宽高比。 + +### youtube + +插件默认不启用该功能,你需要手动设置 `youtube` 为 `true` + +#### 语法 + +```md +@[youtube](id) +@[youtube autoplay loop ratio="16:9" star="0" end="0"](id) +``` + +- `id` 为 YouTube 视频 ID +- `autoplay` 为是否自动播放 +- `loop` 为是否循环播放 +- `ratio` 为视频的宽高比 +- `star` 为开始时间,单位为秒,还可以传入 `mm:ss` 或者 `hh:mm:ss`。 +- `end` 为结束时间,单位为秒,还可以传入 `mm:ss` 或者 `hh:mm:ss`。 + +### CodePen + +插件默认不启用该功能,你需要手动设置 `codepen` 为 `true` + +#### 语法 + +```md +@[codepen](user/slash) +@[codepen preview editable title="" height="400px" tab="css,result" theme="dark"](user/slash) +``` + +- `user` 为 CodePen 用户名 +- `slash` 为 CodePen slash +- `preview` 为是否为预览模式 +- `editable` 为是否为可编辑模式 +- `title` 为标题 +- `height` 为高度 +- `tab` 为选项卡,默认为 `result`, 多个以逗号分隔,如 `css,result` +- `theme` 为主题, 可选值包括 `dark` 和 `light` + +### Replit + +插件默认不启用该功能,你需要手动设置 `replit` 为 `true` + +#### 语法 + +```md +@[replit](user/repl-name) +@[replit title="" height="450px" theme="dark"](user/repl-name#filepath) +``` + +- `user` 为 Replit 用户名 +- `repl-name` 为 Replit Repl 名 +- `filepath` 为文件路径 +- `title` 为标题 +- `height` 为高度 +- `theme` 为主题, 可选值包括 `dark` 和 `light` + +### CodeSandbox + +插件默认不启用该功能,你需要手动设置 `codesandbox` 为 `true` + +#### 语法 + +```md +@[codesandbox](id) +@[codesandbox button](workspace/id) +@[codesanbox title="xxx" layout="Editor+Preview" height="500px" navbar="false" console](id#filepath) +``` + +- `id`: Code Sandbox ID +- `title`: Code Sandbox 标题 +- `layout`: 代码预览布局 可选值: `Preview`, `Editor`, `Editor+Preview` +- `height`: 代码预览高度 +- `navbar`: 是否显示导航栏,默认为 true +- `console`: 是否显示控制台,默认为 false +- `filepath`: 文件路径 + +### JSFiddle + +插件默认不启用该功能,你需要手动设置 `jsfiddle` 为 `true` + +#### 语法 + +```md +@[jsfiddle](user/id) +@[jsfiddle theme="dark" tab="js,css,html,result" height="500px"](user/id) +``` + +- `user`: 用户 +- `id`: jsfiddle id +- `theme`: 主题模式, 可选值: `"light" | "dark"` +- `tab`: 选项卡, 可选值:`"js" | "css" | "html" | "result"`, 多个用 `","` 分割, + 顺序将决定选项卡的排序,默认为 `js,css,html,result` +- `height`: 高度 diff --git a/docs/notes/theme/config/plugins/markdownPower.md b/docs/notes/theme/config/plugins/markdownPower.md new file mode 100644 index 00000000..a49554f0 --- /dev/null +++ b/docs/notes/theme/config/plugins/markdownPower.md @@ -0,0 +1,42 @@ +--- +title: Markdown Power +author: pengzhanbo +createTime: 2024/04/04 06:56:33 +permalink: /config/plugin/markdown-power/ +--- + +## 概述 + +提供 Markdown 增强功能。 + +关联插件: [@vuepress-plume/plugin-md-power](/) + +默认配置: + +```ts +import { plumeTheme } from 'vuepress-theme-plume' +import { defineUserConfig } from 'vuepress' + +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownPower: { + // 默认不启用任何功能,你需要手动开启它们 + // pdf: true, // @[pdf](url) 嵌入 PDF 文件 + // icons: true, // :[collect:name]: 内联 iconify 图标 + // bilibili: true, // @[bilibili](bvid) 嵌入 bilibili 视频 + // youtube: true, // @[youtube](id) 嵌入 youtube 视频 + // codepen: true, // @[codepen](user/slash) 嵌入 codepen + // replit: true, // @[replit](user/repl-name) 嵌入 Replit + // codeSandbox: true, // @[codesandbox](id) 嵌入 CodeSandbox + // jsfiddle: true, // @[jsfiddle](id) 嵌入 jsfiddle + // caniuse: true, // @[caniuse](feature) 嵌入 caniuse + } + } + }), +}) +``` + +## 配置 + +查看 [文档](/plugins/plugin-md-power/) diff --git a/docs/notes/theme/config/plugins/markdown增强.md b/docs/notes/theme/config/plugins/markdown增强.md index a3ade416..b74ba696 100644 --- a/docs/notes/theme/config/plugins/markdown增强.md +++ b/docs/notes/theme/config/plugins/markdown增强.md @@ -1,5 +1,5 @@ --- -title: markdown增强 +title: Markdown Enhance author: pengzhanbo createTime: 2024/03/06 20:25:36 permalink: /config/plugins/markdown-enhance/ diff --git a/docs/notes/theme/guide/markdown/扩展.md b/docs/notes/theme/guide/markdown/扩展.md index 59bc9ccc..b731ae9e 100644 --- a/docs/notes/theme/guide/markdown/扩展.md +++ b/docs/notes/theme/guide/markdown/扩展.md @@ -222,383 +222,6 @@ console.log('Hello, VitePress!') > [!CAUTION] > 行为可能带来的负面影响。 -## 代码块中的语法高亮 - -主题 使用 [Shiki](https://github.com/shikijs/shiki) 在 Markdown 代码块中使用彩色文本实现语法高亮。 -Shiki 支持多种编程语言。需要做的就是将有效的语言别名附加到代码块的开头: - -**输入:** - -```` -```js -export default { - name: 'MyComponent', - // ... -} -``` -```` - -```` -```html - -``` -```` - -**输出:** - -```js -export default { - name: 'MyComponent', - // ... -} -``` - -```html - -``` - -在 Shiki 的代码仓库中,可以找到 [合法的编程语言列表](https://shiki.style/languages)。 - -## 在代码块中实现行高亮 - -**输入:** - -```` -```js{4} -export default { - data () { - return { - msg: 'Highlighted!' - } - } -} -``` -```` - -**输出:** - -```js{4} -export default { - data () { - return { - msg: 'Highlighted!' - } - } -} -``` - -除了单行之外,还可以指定多个单行、多行,或两者均指定: - -- 多行:例如 `{5-8}`、`{3-10}`、`{10-17}` -- 多个单行:例如 `{4,7,9}` -- 多行与单行:例如 `{4,7-13,16,23-27,40}` - -**输入:** - -```` -```js{1,4,6-8} -export default { // Highlighted - data () { - return { - msg: `Highlighted! - This line isn't highlighted, - but this and the next 2 are.`, - motd: 'VitePress is awesome', - lorem: 'ipsum' - } - } -} -``` -```` - -**输出:** - -```js{1,4,6-8} -export default { // Highlighted - data () { - return { - msg: `Highlighted! - This line isn't highlighted, - but this and the next 2 are.`, - motd: 'VitePress is awesome', - lorem: 'ipsum' - } - } -} -``` - -也可以使用 `// [!code highlight]` 注释实现行高亮。 - -**输入:** - -```` -```js -export default { - data () { - return { - msg: 'Highlighted!' // [\!code highlight] - } - } -} -``` -```` - -**输出:** - -```js -export default { - data() { - return { - msg: 'Highlighted!' // [!code highlight] - } - } -} -``` - -## 代码块中聚焦 - -在某一行上添加 `// [!code focus]` 注释将聚焦它并模糊代码的其他部分。 - -此外,可以使用 `// [!code focus:]` 定义要聚焦的行数。 - -**输入:** - -```` -```js -export default { - data () { - return { - msg: 'Focused!' // [\!code focus] - } - } -} -``` -```` - -**输出:** - -```js -export default { - data() { - return { - msg: 'Focused!' // [!code focus] - } - } -} -``` - -## 代码块中的颜色差异 - -在某一行添加 `// [!code --]` 或 `// [!code ++]` 注释将会为该行创建 diff,同时保留代码块的颜色。 - -**输入:** - -```` -```js -export default { - data () { - return { - msg: 'Removed', // [\!code --] - msg: 'Added' // [\!code ++] - } - } -} -``` -```` - -**输出:** - -```js -export default { - data() { - return { - msg: 'Removed', // [!code --] - msg: 'Added' // [!code ++] - } - } -} -``` - -## 高亮“错误”和“警告” - -在某一行添加 `// [!code warning]` 或 `// [!code error]` 注释将会为该行相应的着色。 - -**输入:** - -```` -```js -export default { - data () { - return { - msg: 'Error', // [\!code error] - msg: 'Warning' // [\!code warning] - } - } -} -``` -```` - -**输出:** - -```js -export default { - data() { - return { - msg: 'Error', // [!code error] - msg: 'Warning' // [!code warning] - } - } -} -``` - -## 代码块中 词高亮 - -**输入:** - -```` -```ts -export function foo() { // [\!code word:Hello] - const msg = 'Hello World' - console.log(msg) // prints Hello World -} -``` -```` - -**输出:** - -```ts -export function foo() { // [!code word:Hello] - const msg = 'Hello World' - console.log(msg) // prints Hello World -} -``` - -你还可以指定高亮显示的次数,例如 `[!code word:options:2]` 会高亮显示近两个 `options`。 - -**输入:** - -```` -```ts -// [\!code word:options:2] -const options = { foo: 'bar' } -options.foo = 'baz' -console.log(options.foo) // 这个不会被高亮显示 -``` -```` - -**输出:** - -```ts -// [!code word:options:2] -const options = { foo: 'bar' } -options.foo = 'baz' -console.log(options.foo) // 这个不会被高亮显示 -``` - -## 代码组 - -可以像这样对多个代码块进行分组: - -**输入:** - -````md -::: code-tabs -@tab config.js -```js -/** - * @type {import('vuepress').UserConfig} - */ -const config = { - // .. -} - -export default config -``` - -@tab config.ts -```ts -import type { UserConfig } from 'vuepress' - -const config: UserConfig = { - // .. -} - -export default config -``` -::: -```` - -**输出:** - -::: code-tabs -@tab config.js - -```js -/** - * @type {import('vuepress').UserConfig} - */ -const config = { - // .. -} - -export default config -``` - -@tab config.ts - -```ts -import type { UserConfig } from 'vuepress' - -const config: UserConfig = { - // .. -} - -export default config -``` - -::: - -你还可以通过 `@tab:active` - -## 导入代码块 - -**输入:** - -你可以使用下面的语法,从文件中导入代码块: - -```md -@[code](../snippet/snippet-1.js) -``` - -**输出:** - -@[code](../../snippet/snippet-1.js) - -如果你只想导入这个文件的一部分: - -```md - -@[code{1-10}](../snippet/snippet-1.js) -``` - -代码语言会根据文件扩展名进行推断,但我们建议你显式指定: - -```md - -@[code js](../snippet/snippet-1.js) - - -@[code js{2,4-5}](../foo.js) -``` - ## 数学方程 **输入:** diff --git a/docs/notes/theme/guide/markdown/进阶.md b/docs/notes/theme/guide/markdown/进阶.md index 29c2f016..5ef2a619 100644 --- a/docs/notes/theme/guide/markdown/进阶.md +++ b/docs/notes/theme/guide/markdown/进阶.md @@ -1,5 +1,5 @@ --- -title: 高阶 +title: 更多 author: pengzhanbo icon: ic:outline-auto-fix-high createTime: 2024/03/05 16:27:59 @@ -392,147 +392,6 @@ export default defineUserConfig({ @[caniuse{-2,-1,1,2,3}](css-matches-pseudo) -## CodePen - -主题支持在 Markdown 文件中嵌入 [CodePen](https://codepen.io/)。 - -### 配置 - -此功能默认不启用,你可以在配置文件中启用它。 - -::: code-tabs -@tab .vuepress/config.ts - -```ts -export default defineUserConfig({ - theme: plumeTheme({ - plugins: { - markdownPower: { - codepen: true, // [!code highlight] - }, - } - }) -}) -``` - -::: - -### 语法 - -简单语法: - -```md -@[codepen](user/slash) -``` - -更多选项支持: - -```md -@[codepen preview editable tab="css,result" theme="dark" height="500px" width="100%"](user/slash) -``` - -- `preview`: 是否渲染为预览模式 -- `editable`: 是否可编辑 -- `tab`: 默认显示的标签, 默认为 `result`,多个使用 `,` 分隔 -- `theme`: 主题, 可选值 `dark` 和 `light` -- `height`: 容器高度, 默认为 `400px` -- `width`: 容器宽度, 默认为 `100%` -- `user`: CodePen 用户名 -- `slash`: CodePen 代码文件名 - -### 示例 - -输入: - -```md -@[codepen](leimapapa/RwOZQOW) -``` - -输出: - -@[codepen](leimapapa/RwOZQOW) - -**预览模式:** - -输入: - -```md -@[codepen preview](leimapapa/RwOZQOW) -``` - -输出: - -@[codepen preview](leimapapa/RwOZQOW) - -**编辑模式:** - -输入: - -```md -@[codepen editable tab="html,result"](leimapapa/RwOZQOW) -``` - -输出: - -@[codepen editable tab="html,result"](leimapapa/RwOZQOW) - -## Replit - -主题支持在 Markdown 文件中嵌入 [Replit](https://replit.com/)。 - -### 配置 - -此功能默认不启用,你可以在配置文件中启用它。 - -::: code-tabs -@tab .vuepress/config.ts - -```ts -export default defineUserConfig({ - theme: plumeTheme({ - plugins: { - markdownPower: { - replit: true, // [!code highlight] - }, - } - }) -}) -``` - -::: - -### 语法 - -简单的语法 - -```md -@[replit](user/repl-name) -``` - -更多选项 - -```md -@[replit title="" width="100%" height="450px" theme="dark"](user/repl-name#filepath) -``` - -- `title`: 标题 -- `width`: 容器宽度 -- `height`: 容器高度 -- `theme`: 主题, 可选值 `dark` 和 `light` -- `user`: Replit 用户名 -- `repl-name`: Replit repl 名称 -- `filepath`: Replit 默认打开的文件路径 - -输入: - -```md -@[replit](@TechPandaPro/Cursor-Hangout#package.json) -```` - -输出: - -@[replit](@TechPandaPro/Cursor-Hangout#package.json) - ## 导入文件 主题支持在 Markdown 文件中导入文件切片。 @@ -705,458 +564,3 @@ export default defineUserConfig({ :::: demo-wrapper title="Include by file region" :::: - -## 代码演示 - -代码演示 默认不启用,你可以通过配置来启用它。 - -::: code-tabs -@tab .vuepress/config.ts - -```ts -export default defineUserConfig({ - theme: plumeTheme({ - plugins: { - markdownEnhance: { - demo: true, - }, - } - }) -}) -``` - -::: - -### 语法 - -```` md -::: [类型]-demo 可选的标题文字 - -```html - - - -``` - -```json -// json block 作为插件配置存放处 -{ - // 放置你的配置 (可选的) -} -``` - -::: -```` - -::: tip 提示 -JSON 块是可选的,可用的配置详见[配置](https://vuepress-theme-hope.github.io/v2/md-enhance/zh/config.html) -::: - -插件支持三种类型 - -- normal(默认) -- vue -- react - -### 可用的语言 - -你可以在演示块中使用不同语言。 - -当你设置一些不能在浏览器上直接运行的语言时,由于插件无法解析它们,因此网页演示将被禁用。插件只显示代码。同时提供一个 "在 CodePen 中打开" 按钮允许用户直接在 CodePen 打开并浏览代码。 - -可用的 HTML 语言: - -- `"html"` (默认) -- `"slim"` -- `"haml"` -- `"markdown"` - -可用的 JS 语言: - -- `"javascript"` (default) -- `"coffeescript"` -- `"babel"` -- `"livescript"` -- `"typescript"` - -> 你也可以在代码块中使用 `js`, `ts`, `coffee` 和 `ls。` - -可用的 CSS 语言: - -- `"css"` (default) -- `"less"` -- `"scss"` -- `"sass"` -- `"stylus"` - -### 不支持的语言 - -::: normal-demo 一个使用浏览器不支持解析语言 Demo - -```md -# 标题 - -十分强大 -``` - -```ts -const message: string = 'VuePress Theme Hope' - -document.querySelector('h1').innerHTML = message -``` - -```scss -h1 { - font-style: italic; - - + p { - color: red; - } -} -``` - -::: - -:::: details 代码 - -```` md -::: normal-demo 一个使用浏览器不支持解析语言 Demo - -```md -# 标题 - -十分强大 -``` - -```ts -const message: string = 'VuePress Theme Hope' - -document.querySelector('h1').innerHTML = message -``` - -```scss -h1 { - font-style: italic; - - + p { - color: red; - } -} -``` - -::: -```` - -:::: - -### 普通代码演示 - -格式: - -```` md -::: normal-demo 可选的标题文字 - -```html - -``` - -```js -// js code -``` - -```css -/* css code */ -``` - -```json -// 配置 (可选) -{ - "jsLib": [ - // ... - ], - "cssLib": [ - // ... - ] -} -``` - -::: -```` - -::: warning 注意事项 -我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document,请访问` `window.document`。 -::: - -#### 例子 - -::: normal-demo Demo 演示 - -```html -

Hello Word!

-

非常强大!

-``` - -```js -document.querySelector('#very').addEventListener('click', () => { - alert('非常强大') -}) -``` - -```css -span { - color: red; -} -``` - -::: - -:::: details 代码 - -```` md -::: normal-demo Demo 演示 - -```html -

Hello Word!

-

非常强大!

-``` - -```js -document.querySelector('#very').addEventListener('click', () => { - alert('非常强大') -}) -``` - -```css -span { - color: red; -} -``` - -::: -```` - -:::: - -### Vue 代码演示 - -#### 格式 - -```` md -::: vue-demo 可选的标题文字 - -```vue - - - - - - -``` - -```json -// 配置 (可选) -{} -``` - -::: -```` - -::: warning 注意事项 - -- 你只能使用 `Vue3`。 -- 必须将组件通过 `export default` 默认导出 -- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。 -::: - -#### 演示 - -::: vue-demo 一个 Vue Composition 演示 - -```vue - - - - - -``` - -::: - -:::: details 代码 - -```` md -::: vue-demo 一个 Vue Composition 演示 - -```vue - - - - - -``` - -::: -```` - -:::: - -### React 代码演示 - -#### 格式 - -```` md -::: react-demo 可选的标题文字 - -```js -// 放置脚本,并通过 `export default` 导出你的 react 组件 -``` - -```css -/* 你的 css 内容 */ -``` - -```json -// 配置 (可选) -{} -``` - -::: -```` - -::: warning 注意事项 - -- 使用 React 的时候,为了解析 JSX 必须引入 Babel,此过程由插件自动完成。 -- 必须将组件通过 `export default` 默认导出 -- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。 -::: - -#### 演示 - -::: react-demo 一个函数式 React Demo - -```js -const { useState } = React - -export default () => { - const [message, setMessage] = useState(' 强大') - - const handler = () => { - setMessage(`十分${message}`) - } - - return ( -
- Hello Word ! - - {message} - -
- ) -} -``` - -```css -.box #powerful { - color: blue; -} -``` - -::: - -:::: details 代码 - -```` md -::: react-demo 一个函数式 React Demo - -```js -const { useState } = React - -export default () => { - const [message, setMessage] = useState(' 强大') - - const handler = () => { - setMessage(`十分${message}`) - } - - return ( -
- Hello Word ! - - {message} - -
- ) -} -``` - -```css -.box #powerful { - color: blue; -} -``` - -::: -```` - -:::: diff --git a/docs/notes/theme/guide/介绍.md b/docs/notes/theme/guide/介绍.md index d1b89e2f..249a7778 100644 --- a/docs/notes/theme/guide/介绍.md +++ b/docs/notes/theme/guide/介绍.md @@ -42,6 +42,6 @@ VuePress 是一个 [静态站点生成器](https://en.wikipedia.org/wiki/Static_ - 👀 支持 搜索、文章评论 - 👨‍💻‍ 支持 浅色/深色 主题 (包括代码高亮) - 📠 markdown 增强,支持 代码块分组、提示容器、任务列表、数学公式、代码演示 等 -- 📚 代码演示,支持 CodePen, Replit -- 📊 嵌入图标,支持 chart.js,Echarts,Mermaid,flowchart +- 📚 代码演示,支持 CodePen, Replit, JSFiddle, CodeSandbox +- 📊 嵌入图标,支持 chart.js,Echarts,Mermaid,flowchart 等 - 🎛 资源嵌入,支持 PDF, bilibili视频,youtube视频等 diff --git a/docs/notes/theme/guide/代码/codeSandbox.md b/docs/notes/theme/guide/代码/codeSandbox.md new file mode 100644 index 00000000..76364d6d --- /dev/null +++ b/docs/notes/theme/guide/代码/codeSandbox.md @@ -0,0 +1,82 @@ +--- +title: Code Sandbox +author: pengzhanbo +icon: lucide:codesandbox +createTime: 2024/04/04 03:42:13 +permalink: /guide/code/code-sandbox/ +--- + +主题支持在 Markdown 文件中嵌入 [Code Sandbox](https://codesandbox.io)。 + +## 配置 + +此功能默认不启用,你可以在配置文件中启用它。 + +::: code-tabs +@tab .vuepress/config.ts + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownPower: { + codesandbox: true, // [!code highlight] + }, + } + }) +}) +``` + +::: + +## 语法 + +### 简单语法 + +将 Code Sandbox 嵌入到页面中 + +```md +@[codesandbox](id) +``` + +使用 Code Sandbox 跳转按钮 + +```md +@[codesandbox button](workspace/id) +``` + +### 更多选项 + +```md +@[codesanbox title="xxx" layout="Editor+Preview" height="500px" navbar="false" console](id#filepath) +``` + +- `id`: Code Sandbox ID +- `title`: Code Sandbox 标题 +- `layout`: 代码预览布局 可选值: `Preview`, `Editor`, `Editor+Preview` +- `height`: 代码预览高度 +- `navbar`: 是否显示导航栏,默认为 true +- `console`: 是否显示控制台,默认为 false +- `filepath`: 文件路径 + +## 示例 + +codeSandbox 跳转按钮: + +```md +@[codesandbox button](reaction/5wyzu) +``` + +输出: + +@[codesandbox button](reaction/5wyzu) + +codeSandbox 内嵌到页面中: + +```md +@[codesandbox](5wyzu) +``` + +输出: + +@[codesandbox](5wyzu) diff --git a/docs/notes/theme/guide/代码/codepen.md b/docs/notes/theme/guide/代码/codepen.md new file mode 100644 index 00000000..508a7a13 --- /dev/null +++ b/docs/notes/theme/guide/代码/codepen.md @@ -0,0 +1,89 @@ +--- +title: Code Pen +author: pengzhanbo +icon: mingcute:codepen-line +createTime: 2024/04/04 10:41:58 +permalink: /guide/code/code-pen/ +--- + +主题支持在 Markdown 文件中嵌入 [CodePen](https://codepen.io/)。 + +## 配置 + +此功能默认不启用,你可以在配置文件中启用它。 + +::: code-tabs +@tab .vuepress/config.ts + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownPower: { + codepen: true, // [!code highlight] + }, + } + }) +}) +``` + +::: + +## 语法 + +简单语法: + +```md +@[codepen](user/slash) +``` + +更多选项支持: + +```md +@[codepen preview editable tab="css,result" theme="dark" height="500px" width="100%"](user/slash) +``` + +- `preview`: 是否渲染为预览模式 +- `editable`: 是否可编辑 +- `tab`: 默认显示的标签, 默认为 `result`,多个使用 `,` 分隔 +- `theme`: 主题, 可选值 `dark` 和 `light` +- `height`: 容器高度, 默认为 `400px` +- `width`: 容器宽度, 默认为 `100%` +- `user`: CodePen 用户名 +- `slash`: CodePen 代码文件名 + +## 示例 + +输入: + +```md +@[codepen](leimapapa/RwOZQOW) +``` + +输出: + +@[codepen](leimapapa/RwOZQOW) + +**预览模式:** + +输入: + +```md +@[codepen preview](leimapapa/RwOZQOW) +``` + +输出: + +@[codepen preview](leimapapa/RwOZQOW) + +**编辑模式:** + +输入: + +```md +@[codepen editable tab="html,result"](leimapapa/RwOZQOW) +``` + +输出: + +@[codepen editable tab="html,result"](leimapapa/RwOZQOW) diff --git a/docs/notes/theme/guide/代码/jsFiddle.md b/docs/notes/theme/guide/代码/jsFiddle.md new file mode 100644 index 00000000..0fc0e63f --- /dev/null +++ b/docs/notes/theme/guide/代码/jsFiddle.md @@ -0,0 +1,73 @@ +--- +title: Js Fiddle +author: pengzhanbo +icon: bxl:jsfiddle +createTime: 2024/04/04 10:42:21 +permalink: /guide/code/jsfiddle/ +--- + +主题支持在 Markdown 文件中嵌入 [JS Fiddle](https://jsfiddle.net/)。 + +## 配置 + +此功能默认不启用,你可以在配置文件中启用它。 + +::: code-tabs +@tab .vuepress/config.ts + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownPower: { + jsfiddle: true, // [!code highlight] + }, + } + }) +}) +``` + +::: + +## 语法 + +### 简单语法 + +```md +@[jsfiddle](user/id) +``` + +### 更多选项 + +```md +@[jsfiddle theme="dark" tab="js,css,html,result" height="500px"](user/id) +``` + +- `user`: 用户 +- `id`: jsfiddle id +- `theme`: 主题模式, 可选值: `"light" | "dark"` +- `tab`: 选项卡, 可选值:`"js" | "css" | "html" | "result"`, 多个用 `","` 分割, + 顺序将决定选项卡的排序,默认为 `js,css,html,result` +- `height`: 高度 + +## 示例 + +输入: + +```md +@[jsfiddle](pengzhanbo/1xbwz2p9) +``` + +输出: + +@[jsfiddle](pengzhanbo/1xbwz2p9) + +输入: + +```md +@[jsfiddle tab="result,js,css,html"](pengzhanbo/1xbwz2p9) +``` + +输出: + +@[jsfiddle tab="result,js,css,html"](pengzhanbo/1xbwz2p9) diff --git a/docs/notes/theme/guide/代码/replit.md b/docs/notes/theme/guide/代码/replit.md new file mode 100644 index 00000000..eee3a3f9 --- /dev/null +++ b/docs/notes/theme/guide/代码/replit.md @@ -0,0 +1,64 @@ +--- +title: Replit +author: pengzhanbo +icon: simple-icons:replit +createTime: 2024/04/04 10:42:05 +permalink: /guide/code/replit/ +--- + +主题支持在 Markdown 文件中嵌入 [Replit](https://replit.com/)。 + +## 配置 + +此功能默认不启用,你可以在配置文件中启用它。 + +::: code-tabs +@tab .vuepress/config.ts + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownPower: { + replit: true, // [!code highlight] + }, + } + }) +}) +``` + +::: + +## 语法 + +简单的语法 + +```md +@[replit](user/repl-name) +``` + +更多选项 + +```md +@[replit title="" width="100%" height="450px" theme="dark"](user/repl-name#filepath) +``` + +- `title`: 标题 +- `width`: 容器宽度 +- `height`: 容器高度 +- `theme`: 主题, 可选值 `dark` 和 `light` +- `user`: Replit 用户名 +- `repl-name`: Replit repl 名称 +- `filepath`: Replit 默认打开的文件路径 + +## 示例 + +输入: + +```md +@[replit](@TechPandaPro/Cursor-Hangout#package.json) +```` + +输出: + +@[replit](@TechPandaPro/Cursor-Hangout#package.json) diff --git a/docs/notes/theme/guide/markdown/试验性.md b/docs/notes/theme/guide/代码/twoslash.md similarity index 99% rename from docs/notes/theme/guide/markdown/试验性.md rename to docs/notes/theme/guide/代码/twoslash.md index f6a308c0..970cee10 100644 --- a/docs/notes/theme/guide/markdown/试验性.md +++ b/docs/notes/theme/guide/代码/twoslash.md @@ -1,5 +1,5 @@ --- -title: 试验性 +title: Two Slash author: pengzhanbo icon: material-symbols:experiment-outline createTime: 2024/03/06 11:46:49 @@ -21,6 +21,7 @@ permalink: /guide/markdown/experiment/ > - [x] `vuepress@2.0.0-rc.2` > - [x] `vuepress@2.0.0-rc.7` > - [x] `vuepress@2.0.0-rc.8` +> - [x] `vuepress@2.0.0-rc.9` ### 概述 diff --git a/docs/notes/theme/guide/代码/介绍.md b/docs/notes/theme/guide/代码/介绍.md new file mode 100644 index 00000000..614cfd4c --- /dev/null +++ b/docs/notes/theme/guide/代码/介绍.md @@ -0,0 +1,75 @@ +--- +title: 介绍 +author: pengzhanbo +icon: ic:outline-code +createTime: 2024/04/04 10:35:45 +permalink: /guide/code/intro/ +--- + +## 概述 + +主题 使用 [Shiki](https://github.com/shikijs/shiki) 在 Markdown 代码块实现语法高亮。 + +## 语言 + +[Shiki](https://github.com/shikijs/shiki) 支持 超过 190+ 种语言, +你可以在 [languages](https://shiki.style/languages) 查看所有支持的语言列表。 + +你可以通过以下语法为你使用的 语言所编写的代码 实现高亮效果: + +````md +```[lang] +``` +```` + +其中,`[lang]` 为你使用的语言。 + +示例: + +````md +```js +const a = 1 +console.log(a) +``` +```` + +```js +const a = 1 +console.log(a) +``` + +## 高亮主题 + +[Shiki](https://github.com/shikijs/shiki) 支持 超过 40+ 种高亮主题。 + +你可以在 [Themes](https://shiki.style/themes) 找到所有支持的主题列表,根据个人的喜欢自定义 +高亮主题。 + +Theme Plume 默认为 代码块使用的主题配置: + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + shiki: { + theme: { light: 'vitesse-light', dark: 'vitesse-dark' }, // [!code highlight] + } + } + }) +}) +``` + +默认配置支持在 亮色/暗色 模式分别使用 `vitesse-light`/`vitesse-dark` 主题。 + +## 更多支持 + +得益于 [Shiki](https://github.com/shikijs/shiki) 的强大能力,Theme Plume 还为 代码块 +提供了 更多的 [特性支持](/guide/code/features/),它们让 代码块具备更强的表达能力。 + +同时,为了方便 更好的 完成 代码演示,Theme Plume 还提供了嵌入 [CodePen](/guide/code/code-pen/), +[Js Fiddle](/guide/code/jsfiddle/),[Code Sandbox](/guide/code/code-sandbox/), +[Replit](/guide/code/replit/) 的语法支持,你可以很方便的嵌入代码演示。 + +## 示例 + + diff --git a/docs/notes/theme/guide/代码/代码演示.md b/docs/notes/theme/guide/代码/代码演示.md new file mode 100644 index 00000000..d4991a04 --- /dev/null +++ b/docs/notes/theme/guide/代码/代码演示.md @@ -0,0 +1,462 @@ +--- +title: 代码演示 +author: pengzhanbo +icon: carbon:demo +createTime: 2024/04/04 11:39:05 +permalink: /guide/code/demo/ +--- + +## 概述 + +代码演示 默认不启用,你可以通过配置来启用它。 + +::: code-tabs +@tab .vuepress/config.ts + +```ts +export default defineUserConfig({ + theme: plumeTheme({ + plugins: { + markdownEnhance: { + demo: true, + }, + } + }) +}) +``` + +::: + +## 语法 + +```` md +::: [类型]-demo 可选的标题文字 + +```html + + + +``` + +```json +// json block 作为插件配置存放处 +{ + // 放置你的配置 (可选的) +} +``` + +::: +```` + +::: tip 提示 +JSON 块是可选的,可用的配置详见[配置](https://vuepress-theme-hope.github.io/v2/md-enhance/zh/config.html) +::: + +插件支持三种类型 + +- normal(默认) +- vue +- react + +## 可用的语言 + +你可以在演示块中使用不同语言。 + +当你设置一些不能在浏览器上直接运行的语言时,由于插件无法解析它们,因此网页演示将被禁用。插件只显示代码。同时提供一个 "在 CodePen 中打开" 按钮允许用户直接在 CodePen 打开并浏览代码。 + +可用的 HTML 语言: + +- `"html"` (默认) +- `"slim"` +- `"haml"` +- `"markdown"` + +可用的 JS 语言: + +- `"javascript"` (default) +- `"coffeescript"` +- `"babel"` +- `"livescript"` +- `"typescript"` + +> 你也可以在代码块中使用 `js`, `ts`, `coffee` 和 `ls。` + +可用的 CSS 语言: + +- `"css"` (default) +- `"less"` +- `"scss"` +- `"sass"` +- `"stylus"` + +## 不支持的语言 + +::: normal-demo 一个使用浏览器不支持解析语言 Demo + +```md +# 标题 + +十分强大 +``` + +```ts +const message: string = 'VuePress Theme Hope' + +document.querySelector('h1').innerHTML = message +``` + +```scss +h1 { + font-style: italic; + + + p { + color: red; + } +} +``` + +::: + +:::: details 代码 + +```` md +::: normal-demo 一个使用浏览器不支持解析语言 Demo + +```md +# 标题 + +十分强大 +``` + +```ts +const message: string = 'VuePress Theme Hope' + +document.querySelector('h1').innerHTML = message +``` + +```scss +h1 { + font-style: italic; + + + p { + color: red; + } +} +``` + +::: +```` + +:::: + +## 普通代码演示 + +格式: + +```` md +::: normal-demo 可选的标题文字 + +```html + +``` + +```js +// js code +``` + +```css +/* css code */ +``` + +```json +// 配置 (可选) +{ + "jsLib": [ + // ... + ], + "cssLib": [ + // ... + ] +} +``` + +::: +```` + +::: warning 注意事项 +我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document,请访问` `window.document`。 +::: + +## 例子 + +::: normal-demo Demo 演示 + +```html +

Hello Word!

+

非常强大!

+``` + +```js +document.querySelector('#very').addEventListener('click', () => { + alert('非常强大') +}) +``` + +```css +span { + color: red; +} +``` + +::: + +:::: details 代码 + +```` md +::: normal-demo Demo 演示 + +```html +

Hello Word!

+

非常强大!

+``` + +```js +document.querySelector('#very').addEventListener('click', () => { + alert('非常强大') +}) +``` + +```css +span { + color: red; +} +``` + +::: +```` + +:::: + +### Vue 代码演示 + +#### 格式 + +```` md +::: vue-demo 可选的标题文字 + +```vue + + + + + + +``` + +```json +// 配置 (可选) +{} +``` + +::: +```` + +::: warning 注意事项 + +- 你只能使用 `Vue3`。 +- 必须将组件通过 `export default` 默认导出 +- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。 +::: + +#### 演示 + +::: vue-demo 一个 Vue Composition 演示 + +```vue + + + + + +``` + +::: + +:::: details 代码 + +```` md +::: vue-demo 一个 Vue Composition 演示 + +```vue + + + + + +``` + +::: +```` + +:::: + +### React 代码演示 + +#### 格式 + +```` md +::: react-demo 可选的标题文字 + +```js +// 放置脚本,并通过 `export default` 导出你的 react 组件 +``` + +```css +/* 你的 css 内容 */ +``` + +```json +// 配置 (可选) +{} +``` + +::: +```` + +::: warning 注意事项 + +- 使用 React 的时候,为了解析 JSX 必须引入 Babel,此过程由插件自动完成。 +- 必须将组件通过 `export default` 默认导出 +- 我们使用 `"ShadowDOM"` 进行样式隔离,并已经将 `document` 替换为了 `shadowRoot` 对象。如果需要访问页面的 `document`,请访问 `window.document`。 +::: + +#### 演示 + +::: react-demo 一个函数式 React Demo + +```js +const { useState } = React + +export default () => { + const [message, setMessage] = useState(' 强大') + + const handler = () => { + setMessage(`十分${message}`) + } + + return ( +
+ Hello Word ! + + {message} + +
+ ) +} +``` + +```css +.box #powerful { + color: blue; +} +``` + +::: + +:::: details 代码 + +```` md +::: react-demo 一个函数式 React Demo + +```js +const { useState } = React + +export default () => { + const [message, setMessage] = useState(' 强大') + + const handler = () => { + setMessage(`十分${message}`) + } + + return ( +
+ Hello Word ! + + {message} + +
+ ) +} +``` + +```css +.box #powerful { + color: blue; +} +``` + +::: +```` + +:::: diff --git a/docs/notes/theme/guide/代码/代码组.md b/docs/notes/theme/guide/代码/代码组.md new file mode 100644 index 00000000..c189e04f --- /dev/null +++ b/docs/notes/theme/guide/代码/代码组.md @@ -0,0 +1,72 @@ +--- +title: 代码组 +author: pengzhanbo +icon: fluent:group-list-20-filled +createTime: 2024/04/04 10:36:59 +permalink: /guide/code/group/ +--- + +## 语法 + +可以像这样对多个代码块进行分组: + +**输入:** + +````md +::: code-tabs +@tab config.js +```js +/** + * @type {import('vuepress').UserConfig} + */ +const config = { + // .. +} + +export default config +``` + +@tab config.ts +```ts +import type { UserConfig } from 'vuepress' + +const config: UserConfig = { + // .. +} + +export default config +``` +::: +```` + +**输出:** + +::: code-tabs +@tab config.js + +```js +/** + * @type {import('vuepress').UserConfig} + */ +const config = { + // .. +} + +export default config +``` + +@tab config.ts + +```ts +import type { UserConfig } from 'vuepress' + +const config: UserConfig = { + // .. +} + +export default config +``` + +::: + +你还可以通过 `@tab:active` 选择其中一个代码块作为默认显示的代码块。 diff --git a/docs/notes/theme/guide/代码/导入代码.md b/docs/notes/theme/guide/代码/导入代码.md new file mode 100644 index 00000000..7fb470a9 --- /dev/null +++ b/docs/notes/theme/guide/代码/导入代码.md @@ -0,0 +1,44 @@ +--- +title: 导入代码 +author: pengzhanbo +icon: mdi:import +createTime: 2024/04/04 10:39:22 +permalink: /guide/code/import/ +--- + +## 概述 + +导入代码 可以让你在 md 文件中 导入另一个文件的 代码,并为其高亮显示。 + +它可以帮助你在文章中引用其他文件的代码,避免编写重复的代码。 + +## 语法 + +你可以使用下面的语法,从文件中导入代码块: + +**输入:** + +```md +@[code](../snippet/snippet-1.js) +``` + +**输出:** + +@[code](../../snippet/snippet-1.js) + +如果你只想导入这个文件的一部分: + +```md + +@[code{1-10}](../snippet/snippet-1.js) +``` + +代码语言会根据文件扩展名进行推断,但我们建议你显式指定: + +```md + +@[code js](../snippet/snippet-1.js) + + +@[code js{2,4-5}](../foo.js) +``` diff --git a/docs/notes/theme/guide/代码/特性支持.md b/docs/notes/theme/guide/代码/特性支持.md new file mode 100644 index 00000000..1b10ecdf --- /dev/null +++ b/docs/notes/theme/guide/代码/特性支持.md @@ -0,0 +1,247 @@ +--- +title: 特性支持 +author: pengzhanbo +icon: majesticons:code-block-line +createTime: 2024/04/04 10:41:28 +permalink: /guide/code/features/ +--- + +主题在代码高亮功能上,进一步支持了更多的特性,它们能够帮助你的代码块更加具备表达力。 + +## 在代码块中实现行高亮 + +在 `[lang]` 之后紧跟随 `{xxxx}` ,可以实现行高亮,其中 `xxx` 表示要高亮的行号。 + +**输入:** + +```` +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` +```` + +**输出:** + +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` + +除了单行之外,还可以指定多个单行、多行,或两者均指定: + +- 多行:例如 `{5-8}`、`{3-10}`、`{10-17}` +- 多个单行:例如 `{4,7,9}` +- 多行与单行:例如 `{4,7-13,16,23-27,40}` + +**输入:** + +```` +```js{1,4,6-8} +export default { // Highlighted + data () { + return { + msg: `Highlighted! + This line isn't highlighted, + but this and the next 2 are.`, + motd: 'VitePress is awesome', + lorem: 'ipsum' + } + } +} +``` +```` + +**输出:** + +```js{1,4,6-8} +export default { // Highlighted + data () { + return { + msg: `Highlighted! + This line isn't highlighted, + but this and the next 2 are.`, + motd: 'VitePress is awesome', + lorem: 'ipsum' + } + } +} +``` + +也可以使用 `// [!code highlight]` 注释实现行高亮。 + +**输入:** + +```` +```js +export default { + data () { + return { + msg: 'Highlighted!' // [\!code highlight] + } + } +} +``` +```` + +**输出:** + +```js +export default { + data() { + return { + msg: 'Highlighted!' // [!code highlight] + } + } +} +``` + +## 代码块中聚焦 + +在某一行上添加 `// [!code focus]` 注释将聚焦它并模糊代码的其他部分。 + +此外,可以使用 `// [!code focus:]` 定义要聚焦的行数。 + +**输入:** + +```` +```js +export default { + data () { + return { + msg: 'Focused!' // [\!code focus] + } + } +} +``` +```` + +**输出:** + +```js +export default { + data() { + return { + msg: 'Focused!' // [!code focus] + } + } +} +``` + +## 代码块中的颜色差异 + +在某一行添加 `// [!code --]` 或 `// [!code ++]` 注释将会为该行创建 diff,同时保留代码块的颜色。 + +**输入:** + +```` +```js +export default { + data () { + return { + msg: 'Removed', // [\!code --] + msg: 'Added' // [\!code ++] + } + } +} +``` +```` + +**输出:** + +```js +export default { + data() { + return { + msg: 'Removed', // [!code --] + msg: 'Added' // [!code ++] + } + } +} +``` + +## 高亮“错误”和“警告” + +在某一行添加 `// [!code warning]` 或 `// [!code error]` 注释将会为该行相应的着色。 + +**输入:** + +```` +```js +export default { + data () { + return { + msg: 'Error', // [\!code error] + msg: 'Warning' // [\!code warning] + } + } +} +``` +```` + +**输出:** + +```js +export default { + data() { + return { + msg: 'Error', // [!code error] + msg: 'Warning' // [!code warning] + } + } +} +``` + +## 代码块中 词高亮 + +**输入:** + +```` +```ts +export function foo() { // [\!code word:Hello] + const msg = 'Hello World' + console.log(msg) // prints Hello World +} +``` +```` + +**输出:** + +```ts +export function foo() { // [!code word:Hello] + const msg = 'Hello World' + console.log(msg) // prints Hello World +} +``` + +你还可以指定高亮显示的次数,例如 `[!code word:options:2]` 会高亮显示近两个 `options`。 + +**输入:** + +```` +```ts +// [\!code word:options:2] +const options = { foo: 'bar' } +options.foo = 'baz' +console.log(options.foo) // 这个不会被高亮显示 +``` +```` + +**输出:** + +```ts +// [!code word:options:2] +const options = { foo: 'bar' } +options.foo = 'baz' +console.log(options.foo) // 这个不会被高亮显示 +``` diff --git a/docs/notes/theme/guide/安装与使用.md b/docs/notes/theme/guide/安装与使用.md index 69cd9293..7c412da4 100644 --- a/docs/notes/theme/guide/安装与使用.md +++ b/docs/notes/theme/guide/安装与使用.md @@ -95,7 +95,7 @@ npm i -D vuepress-theme-plume @vuepress/bundler-vite@next ::: :::warning -主题当前版本 已适配至 `vuepress@2.0.0-rc.8`,你应该安装这个版本的 VuePress。 +主题当前版本 已适配至 `vuepress@2.0.0-rc.9`,你应该安装这个版本的 VuePress。 高于或低于这个版本,可能会存在潜在的兼容性问题。 ::: diff --git a/docs/notes/theme/guide/编写文章.md b/docs/notes/theme/guide/编写文章.md index f573fc5e..4d9678fe 100644 --- a/docs/notes/theme/guide/编写文章.md +++ b/docs/notes/theme/guide/编写文章.md @@ -50,4 +50,4 @@ __example:__ ## 文章写作 你可以使用 `markdown` 语法开始在 `sourceDir` 下新建 `Markdown` 文件,编写你自己的文章了, -关于 markdown 扩展的功能支持,请查看 [这个文档](/guide/markdown/)。 +关于 markdown 扩展的功能支持,请查看 [这个文档](/guide/markdown/extensions/)。 diff --git a/docs/notes/theme/snippet/code-block.snippet.md b/docs/notes/theme/snippet/code-block.snippet.md new file mode 100644 index 00000000..3f13ba24 --- /dev/null +++ b/docs/notes/theme/snippet/code-block.snippet.md @@ -0,0 +1,1176 @@ +::: code-tabs +@tab C + +``` c +#include + +#define ARR_LEN 7 + +void qsort(int v[], int left, int right); +void printArr(int v[], int len); + +int main() +{ + int i; + int v[ARR_LEN] = { 4, 3, 1, 7, 9, 6, 2 }; + printArr(v, ARR_LEN); + qsort(v, 0, ARR_LEN-1); + printArr(v, ARR_LEN); + return 0; +} + +void qsort(int v[], int left, int right) +{ + int i, last; + void swap(int v[], int i, int j); + + if (left >= right) + return; + swap(v, left, (left + right) / 2); + last = left; + for (i = left+1; i <= right; i++) + if (v[i] < v[left]) + swap(v, ++last, i); + swap(v, left, last); + qsort(v, left, last-1); + qsort(v, last+1, right); +} + +void swap(int v[], int i, int j) +{ + int temp; + + temp = v[i]; + v[i] = v[j]; + v[j] = temp; +} + +void printArr(int v[], int len) +{ + int i; + for (i = 0; i < len; i++) + printf("%d ", v[i]); + printf("\n"); +} +``` + +@tab C++ + +```c++ +// Working of implicit type-conversion + +#include +using namespace std; + +int main() { + + int num_int; + double num_double = 9.99; + + // implicit conversion + // assigning a double value to an int variable + num_int = num_double; + + cout << "num_int = " << num_int << endl; + cout << "num_double = " << num_double << endl; + + return 0; +} +``` + +@tab Java + +```java +import java.awt.Rectangle; + +public class ObjectVarsAsParameters +{ public static void main(String[] args) + { go(); + } + + public static void go() + { Rectangle r1 = new Rectangle(0,0,5,5); + System.out.println("In method go. r1 " + r1 + "\n"); + // could have been + //System.out.prinltn("r1" + r1.toString()); + r1.setSize(10, 15); + System.out.println("In method go. r1 " + r1 + "\n"); + alterPointee(r1); + System.out.println("In method go. r1 " + r1 + "\n"); + + alterPointer(r1); + System.out.println("In method go. r1 " + r1 + "\n"); + } + + public static void alterPointee(Rectangle r) + { System.out.println("In method alterPointee. r " + r + "\n"); + r.setSize(20, 30); + System.out.println("In method alterPointee. r " + r + "\n"); + } + + public static void alterPointer(Rectangle r) + { System.out.println("In method alterPointer. r " + r + "\n"); + r = new Rectangle(5, 10, 30, 35); + System.out.println("In method alterPointer. r " + r + "\n"); + } + +} +``` + +@tab Kotlin + +```kotlin +package com.example.kotlin + +import java.util.Random as Rand +import android.support.v7.app.AppCompatActivity +import org.amshove.kluent.`should equal` as Type + +fun main(@NonNull args: Array) { + println("Hello Kotlin! ${/*test*/}") + + val map = mutableMapOf("A" to "B") + + thing.apply("random string here \n\t\r") + thing.let { test: -> } + + val string = "${getThing()}" +} + +val items = listOf("apple", "banana", "kiwifruit") +var x = 9 +const val CONSTANT = 99 + +@get:Rule +val activityRule = ActivityTestRule(SplashActivity::class.java) + +val oneMillion = 1_000_000 +val creditCardNumber = 1234_5678_9012_3456L +val socialSecurityNumber = 999_99_9999L +val hexBytes = 0xFF_EC_DE_5E +val float = 0.043_331F +val bytes = 0b11010010_01101001_10010100_10010010 + +if(test == "") { + 1 and 2 not 3 +} else { + +} + +fun foo() { + val x = Bar::class + val y = hello?.test +} + +suspend fun SequenceBuilder.yieldIfOdd(x: Int) { + if (x % 2 != 0) yield(x) +} + +val function = fun(@Inject x: Int, y: Int, lamda: (A, B) -> Unit): Int { + test.test() + return x + y; +} + +abstract fun onCreate(savedInstanceState: Bundle?) + +fun isOdd(x: Int) = x % 2 != 0 +fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove" + +val numbers = listOf(1, 2, 3) +println(numbers.filter(::isOdd)) + +fun foo(node: Node?): String? { + val parent = node.getParent() ?: return null +} + +interface Greetable { + fun greet() +} + +open class Greeter: Greetable { + companion object { + private const val GREETING = "Hello, World!" + } + + override fun greet() { + println(GREETING) + } +} + +expect class Foo(bar: String) { + fun frob() +} + +actual class Foo actual constructor(val bar: String) { + actual fun frob() { + println("Frobbing the $bar") + } +} + +expect fun formatString(source: String, vararg args: Any): String +expect annotation class Test + +actual fun formatString(source: String, vararg args: Any) = String.format(source, args) +actual typealias Test = org.junit.Test + +sealed class Expr +data class Const(val number: Double) : Expr() +data class Sum(val e1: Expr, val e2: Expr) : Expr() +object NotANumber : Expr() + +@file:JvmName("Foo") +private sealed class InjectedClass @Inject constructor( + val test: Int = 50, + var anotherVar: String = "hello world" +) : SomeSuperClass(test, anotherVar) { + + init { + // + } + + constructor(param1: String, param2: Int): this(param1, param2) { + // + } + + companion object { + // + } +} +annotation class Suspendable +val f = @Suspendable { Fiber.sleep(10) } + +private data class Foo( + /** + * ``` + * ($) + * ``` + */ + val variables: Map +) + +data class Response(@SerializedName("param1") val param1: String, + @SerializedName("param2") val param2: String, + @SerializedName("param3") val param3: String) { +} + +object DefaultListener : MouseAdapter() { + override fun mouseClicked(e: MouseEvent) { } + + override fun mouseEntered(e: MouseEvent) { } +} + +class Feature : Node("Title", "Content", "Description") { + +} + +class Outer { + inner class Inner {} +} +``` + +@tab Python + +```py +def fib(n): # write Fibonacci series up to n + """Print a Fibonacci series up to n.""" + a, b = 0, 1 + while a < n: + print(a, end=' ') + a, b = b, a+b + print() + +# Now call the function we just defined: +fib(2000) +``` + +@tab Go + +```go +package main + +import ( + "fmt" + "log" + "net/http" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) +} + +func main() { + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":8080", nil)) +} +``` + +@tab Ruby + +```ruby +class LotteryTicket + + NUMERIC_RANGE = 1..25 + + attr_reader :picks, :purchased + + def initialize( *picks ) + if picks.length != 3 + raise ArgumentError, "three numbers must be picked" + elsif picks.uniq.length != 3 + raise ArgumentError, "the three picks must be different numbers" + elsif picks.detect { |p| not NUMERIC_RANGE === p } + raise ArgumentError, "the three picks must be numbers between 1 and 25" + end + @picks = picks + @purchased = Time.now + end + +end +``` + +@tab Makefile + +```make +edit : main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o + cc -o edit main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o + +main.o : main.c defs.h + cc -c main.c +kbd.o : kbd.c defs.h command.h + cc -c kbd.c +command.o : command.c defs.h command.h + cc -c command.c +display.o : display.c defs.h buffer.h + cc -c display.c +insert.o : insert.c defs.h buffer.h + cc -c insert.c +search.o : search.c defs.h buffer.h + cc -c search.c +files.o : files.c defs.h buffer.h command.h + cc -c files.c +utils.o : utils.c defs.h + cc -c utils.c +clean : + rm edit main.o kbd.o command.o display.o \ + insert.o search.o files.o utils.o +``` + +@tab Object-C + +```objc +@interface classname : superclassname { + // instance variables +} ++ classMethod1; ++ (return_type)classMethod2; ++ (return_type)classMethod3:(param1_type)param1_varName; + +- (return_type)instanceMethod1With1Parameter:(param1_type)param1_varName; +- (return_type)instanceMethod2With2Parameters:(param1_type)param1_varName + param2_callName:(param2_type)param2_varName; +@end +``` + +@tab Swift + +```swift +class Residence { + var rooms: [Room] = [] + var numberOfRooms: Int { + return rooms.count + } + subscript(i: Int) -> Room { + get { + return rooms[i] + } + set { + rooms[i] = newValue + } + } + func printNumberOfRooms() { + print("The number of rooms is \(numberOfRooms)") + } + var address: Address? +} +``` + +@tab PHP + +```php +command('inspire')->hourly(); + } + + /** + * Register the commands for the application. + */ + protected function commands(): void + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} +``` + +@tab Rust + +```rs +// Unlike C/C++, there's no restriction on the order of function definitions +fn main() { + // We can use this function here, and define it somewhere later + fizzbuzz_to(100); +} + +// Function that returns a boolean value +fn is_divisible_by(lhs: u32, rhs: u32) -> bool { + // Corner case, early return + if rhs == 0 { + return false; + } + + // This is an expression, the `return` keyword is not necessary here + lhs % rhs == 0 +} + +// Functions that "don't" return a value, actually return the unit type `()` +fn fizzbuzz(n: u32) -> () { + if is_divisible_by(n, 15) { + println!("fizzbuzz"); + } else if is_divisible_by(n, 3) { + println!("fizz"); + } else if is_divisible_by(n, 5) { + println!("buzz"); + } else { + println!("{}", n); + } +} + +// When a function returns `()`, the return type can be omitted from the +// signature +fn fizzbuzz_to(n: u32) { + for n in 1..=n { + fizzbuzz(n); + } +} +``` + +@tab SQL + +```sql +USE AdventureWorks2022; +GO +IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL + DROP TABLE dbo.NewProducts; +GO +ALTER DATABASE AdventureWorks2022 SET RECOVERY BULK_LOGGED; +GO + +SELECT * INTO dbo.NewProducts +FROM Production.Product +WHERE ListPrice > $25 +AND ListPrice < $100; +GO +ALTER DATABASE AdventureWorks2022 SET RECOVERY FULL; +GO +``` + +@tab XML + +```xml + + + + Gambardella, Matthew + XML Developer's Guide + Computer + 44.95 + 2000-10-01 + An in-depth look at creating applications + with XML. + + + Ralls, Kim + Midnight Rain + Fantasy + 5.95 + 2000-12-16 + A former architect battles corporate zombies, + an evil sorceress, and her own childhood to become queen + of the world. + + + Corets, Eva + Maeve Ascendant + Fantasy + 5.95 + 2000-11-17 + After the collapse of a nanotechnology + society in England, the young survivors lay the + foundation for a new society. + + + Corets, Eva + Oberon's Legacy + Fantasy + 5.95 + 2001-03-10 + In post-apocalypse England, the mysterious + agent known only as Oberon helps to create a new life + for the inhabitants of London. Sequel to Maeve + Ascendant. + + + Corets, Eva + The Sundered Grail + Fantasy + 5.95 + 2001-09-10 + The two daughters of Maeve, half-sisters, + battle one another for control of England. Sequel to + Oberon's Legacy. + + + Randall, Cynthia + Lover Birds + Romance + 4.95 + 2000-09-02 + When Carla meets Paul at an ornithology + conference, tempers fly as feathers get ruffled. + + + Thurman, Paula + Splish Splash + Romance + 4.95 + 2000-11-02 + A deep sea diver finds true love twenty + thousand leagues beneath the sea. + + + Knorr, Stefan + Creepy Crawlies + Horror + 4.95 + 2000-12-06 + An anthology of horror stories about roaches, + centipedes, scorpions and other insects. + + + Kress, Peter + Paradox Lost + Science Fiction + 6.95 + 2000-11-02 + After an inadvertant trip through a Heisenberg + Uncertainty Device, James Salway discovers the problems + of being quantum. + + + O'Brien, Tim + Microsoft .NET: The Programming Bible + Computer + 36.95 + 2000-12-09 + Microsoft's .NET initiative is explored in + detail in this deep programmer's reference. + + + O'Brien, Tim + MSXML3: A Comprehensive Guide + Computer + 36.95 + 2000-12-01 + The Microsoft MSXML3 parser is covered in + detail, with attention to XML DOM interfaces, XSLT processing, + SAX and more. + + + Galos, Mike + Visual Studio 7: A Comprehensive Guide + Computer + 49.95 + 2001-04-16 + Microsoft Visual Studio 7 is explored in depth, + looking at how Visual Basic, Visual C++, C#, and ASP+ are + integrated into a comprehensive development + environment. + + +``` + +@tab Zig + +```zig +const std = @import("std"); +const parseInt = std.fmt.parseInt; + +test "parse integers" { + const input = "123 67 89,99"; + const ally = std.testing.allocator; + + var list = std.ArrayList(u32).init(ally); + // Ensure the list is freed at scope exit. + // Try commenting out this line! + defer list.deinit(); + + var it = std.mem.tokenize(u8, input, " ,"); + while (it.next()) |num| { + const n = try parseInt(u32, num, 10); + try list.append(n); + } + + const expected = [_]u32{ 123, 67, 89, 99 }; + + for (expected, list.items) |exp, actual| { + try std.testing.expectEqual(exp, actual); + } +} +``` +::: + +::: code-tabs +@tab HTML + +``` html + + + + + + MDN Web Docs Example: Toggling full-screen mode + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +``` + +@tab Pug + +```pug +doctype html +html(lang="en") + head + title= pageTitle + script(type='text/javascript'). + if (foo) bar(1 + 5); + body + h1 Pug - node template engine + #container.col + if youAreUsingPug + p You are amazing + else + p Get on it! + p. + Pug is a terse and simple templating language with a + strong focus on performance and powerful features. +``` + +@tab HTTP + +```http +// Basic authentication +GET http://example.com +Authorization: Basic username password + +### + +// Digest authentication +GET http://example.com +Authorization: Digest username password + +// The request body is provided in place +POST https://example.com:8080/api/html/post HTTP/1.1 +Content-Type: application/json +Cookie: key=first-value + +{ "key" : "value", "list": [1, 2, 3] } +``` + +@tab CSS + +```css +html { + margin: 0; + background: black; + height: 100%; +} + +body { + margin: 0; + width: 100%; + height: inherit; +} + +/* the three main rows going down the page */ + +body > div { + height: 25%; +} + +.thumb { + float: left; + width: 25%; + height: 100%; + object-fit: cover; +} + +.main { + display: none; +} + +.blowup { + display: block; + position: absolute; + object-fit: contain; + object-position: center; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 2000; +} + +.darken { + opacity: 0.4; +} +``` + +@tab Less + +```less +.button { + &-ok { + background-image: url("ok.png"); + } + &-cancel { + background-image: url("cancel.png"); + } + + &-custom { + background-image: url("custom.png"); + } +} +.link { + & + & { + color: red; + } + + & & { + color: green; + } + + && { + color: blue; + } + + &, &ish { + color: cyan; + } +} +``` + +@tab SCSS + +```scss +nav { + ul { + margin: 0; + padding: 0; + list-style: none; + } + + li { display: inline-block; } + + a { + display: block; + padding: 6px 12px; + text-decoration: none; + } +} +``` + +@tab Stylus + +```styl +vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + +border-radius() + vendor('border-radius', arguments) + +box-shadow() + vendor('box-shadow', arguments) + +button + border-radius 1px 2px / 3px 4px + +border-radius() { + -webkit-border-radius: arguments; + -moz-border-radius: arguments; + border-radius: arguments; +} + +body a { + font: 12px/1.4 "Lucida Grande", Arial, sans-serif; + background: black; + color: #ccc; +} + +form input { + padding: 5px; + border: 1px solid; + border-radius: 5px; +} +``` + +@tab JavaScript + +```js +function resolveAfter2Seconds(x) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(x) + }, 2000) + }) +} + +// async function expression assigned to a variable +const add = async function (x) { + const a = await resolveAfter2Seconds(20) + const b = await resolveAfter2Seconds(30) + return x + a + b +} + +add(10).then((v) => { + console.log(v) // prints 60 after 4 seconds. +}); + +// async function expression used as an IIFE +(async function (x) { + const p1 = resolveAfter2Seconds(20) + const p2 = resolveAfter2Seconds(30) + return x + (await p1) + (await p2) +})(10).then((v) => { + console.log(v) // prints 60 after 2 seconds. +}) +``` + +@tab JSX + +```jsx +function Item({ name, isPacked }) { + if (isPacked) + return null + + return
  • {name}
  • +} + +export default function PackingList() { + return ( +
    +

    Sally Ride's Packing List

    +
      + + + +
    +
    + ) +} +``` + +@tab TypeScript + +```ts +enum LogLevel { + ERROR, + WARN, + INFO, + DEBUG, +} + +/** + * This is equivalent to: + * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'; + */ +type LogLevelStrings = keyof typeof LogLevel + +function printImportant(key: LogLevelStrings, message: string) { + const num = LogLevel[key] + if (num <= LogLevel.WARN) { + console.log('Log level key is:', key) + console.log('Log level value is:', num) + console.log('Log level message is:', message) + } +} +printImportant('ERROR', 'This is a message') +``` + +@tab TSX + +```tsx +// posts will be populated at build time by getStaticProps() +function Blog({ posts }) { + return ( +
      + {posts.map(post => ( +
    • {post.title}
    • + ))} +
    + ) +} + +// This function gets called at build time on server-side. +export async function getStaticProps() { + const res = await fetch('https://.../posts') + const posts = await res.json() + + return { + props: { + posts + } + } +} + +export default Blog +``` + +@tab Astro + +```astro +--- +// Your component script here! +import Banner from '../components/Banner.astro'; +import ReactPokemonComponent from '../components/ReactPokemonComponent.jsx'; +const myFavoritePokemon = [/* ... */]; +const { title } = Astro.props; +--- + +{/* JS comment syntax is also valid! */} + + +

    Hello, world!

    + + +

    {title}

    + + + + + +
      + {myFavoritePokemon.map((data) =>
    • {data.name}
    • )} +
    + + +

    +``` + +@tab Vue + +```vue + + + + + +``` + +@tab Svelte + +```svelte + + + + + + + + +{#if files} +

    Selected files:

    + {#each Array.from(files) as file} +

    {file.name} ({file.size} bytes)

    + {/each} +{/if} +``` + +@tab WebAssembly + +```wasm +(module + ;; add the $even_check function to the top of the module + (func $even_check (param $n i32) (result i32) + local.get $n + i32.const 2 + i32.rem_u ;; if you take the remainder of a division by 2 + i32.const 0 ;; even numbers will have a remainder 0 + i32.eq ;; $n % 2 == 0 + ) + ;; add the $eq_2 function after $even_check + (func $eq_2 (param $n i32) (result i32) + local.get $n + i32.const 2 + i32.eq ;; returns 1 if $n == 2 + ) + + ;; add $multiple_check after $eq_2 + (func $multiple_check (param $n i32) (param $m i32) (result i32) + local.get $n + local.get $m + i32.rem_u ;; get the remainder of $n / $m + i32.const 0 ;; I want to know if the remainder is 0 + i32.eq ;; that will tell us if $n is a multiple of $m + ) + + ;; add the is_prime exported function after $multiple_check + (func (export "is_prime") (param $n i32) (result i32) + (local $i i32) + (if (i32.eq (local.get $n) (i32.const 1)) ;; 1 is not prime + (then + i32.const 0 + return + )) + (if (call $eq_2 (local.get $n)) ;; check to see if $n is 2 + (then + i32.const 1 ;; 2 is prime + return + ) + ) + (block $not_prime + (call $even_check (local.get $n)) + br_if $not_prime ;; even numbers are not prime (except 2) + + (local.set $i (i32.const 1)) + (loop $prime_test_loop + + (local.tee $i (i32.add (local.get $i) (i32.const 2) ) ) ;; $i += 2 + local.get $n ;; stack = [$n, $i] + + i32.ge_u ;; $i >= $n + if ;; if $i >= $n, $n is prime + i32.const 1 + return + end + (call $multiple_check (local.get $n) (local.get $i)) + br_if $not_prime ;; if $n is a multiple of $i this is not prime + br $prime_test_loop ;; branch back to top of loop + ) ;; end of $prime_test_loop loop + ) ;; end of $not_prime block + +i32.const 0 ;; return false + ) +) ;; end of module +``` + +::: diff --git a/plugins/plugin-md-power/README.md b/plugins/plugin-md-power/README.md index 314db88c..2b4b0d35 100644 --- a/plugins/plugin-md-power/README.md +++ b/plugins/plugin-md-power/README.md @@ -199,3 +199,41 @@ pnpm add @iconify/json - `title` 为标题 - `height` 为高度 - `theme` 为主题, 可选值包括 `dark` 和 `light` + +### CodeSandbox + +插件默认不启用该功能,你需要手动设置 `codesandbox` 为 `true` + +#### 语法 + +```md +@[codesandbox](id) +@[codesandbox button](workspace/id) +@[codesanbox title="xxx" layout="Editor+Preview" height="500px" navbar="false" console](id#filepath) +``` + +- `id`: Code Sandbox ID +- `title`: Code Sandbox 标题 +- `layout`: 代码预览布局 可选值: `Preview`, `Editor`, `Editor+Preview` +- `height`: 代码预览高度 +- `navbar`: 是否显示导航栏,默认为 true +- `console`: 是否显示控制台,默认为 false +- `filepath`: 文件路径 + +### JSFiddle + +插件默认不启用该功能,你需要手动设置 `jsfiddle` 为 `true` + +#### 语法 + +```md +@[jsfiddle](user/id) +@[jsfiddle theme="dark" tab="js,css,html,result" height="500px"](user/id) +``` + +- `user`: 用户 +- `id`: jsfiddle id +- `theme`: 主题模式, 可选值: `"light" | "dark"` +- `tab`: 选项卡, 可选值:`"js" | "css" | "html" | "result"`, 多个用 `","` 分割, + 顺序将决定选项卡的排序,默认为 `js,css,html,result` +- `height`: 高度