在 Markdown 中使用组件
Nuxt Content 使用 Markdown 语法和约定来提供丰富的文本编辑体验。它使用自定的 MDC 语法,可以让你在 Markdown 中使用 Vue 组件,并支持多种 remark 扩展。
我编写了一些可以在 Markdown 文件中调用的组件,以下是一些示例。
通过 CSS 类名控制样式
Markdown 语法组件
可以通过 Markdown 原生语法、HTML 语法和 MDC 语法使用的组件。
链接 ProseA
这是内部链接。站外链接 默认在新标签页打开,并在鼠标悬浮时展示域名。
还会根据域名展示图标,例如 微软文档、GitHub、Bilibili、QQ 官网、微信公众号 等。
::
为更多站点匹配图标
你可以在 app/utils/icon.ts 分别为主域名或专门域名(优先级高)添加匹配规则来为更多站点匹配图标。
代码 ProseCode
行内代码 和 在超链接中的 行内代码。
还可以通过在反引号后加 {lang="js"} 等语言实现高亮,例如 const a = 1 。
代码块 ProsePre
纯文本代码块
带文件夹名、未指定语言的代码块
语言: yaml # 指定语言但无文件名
羽化边缘: 如果一行特别特别特别特别特别特别特别特别特别特别特别特别特别特别特别特别长,溢出滚动时有羽化边缘。
# 更新日志 - 特殊文件名自动匹配图标 - 若行数超出 `appConfig.component.codeblock.triggerRows` (默认32) - 则自动折叠到 `appConfig.component.codeblock.collapsedRows` (默认16) - 如果设置了 expand,则不会自动折叠 - 如果设置了 wrap,则会自动换行 - 如果设置了文件名,则会在代码块标题前展示图标 - 图标只在有文件名时展示 - 默认图标是语言图标 - 特殊文件名也会自动识别出图标 - 文件名可以是任意字符串,例如 `CHANGELOG.md`、`README.md` 等 - 文件名也可以是路径,例如 `src/components/ProsePre.vue` 等 - 还可以通过 `icon=图标` 自定义图标 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
- 在 Markdown 文件中,可以通过代码块语法的 meta 标记 - `wrap` 直接启用自动换行功能,以展示特别特别特别特别特别特别特别特别特别特别特别特别特别特别特别特别长的文本而不换行 - `icon=tabler:files` 自定义代码块图标 - `expand` 禁用自动折叠功能 # 代码块语法 ```语言简写 [文件名] icon=图标 wrap expand - 上面这几项都是可选的。 - 如果有语言简写,必须位于反引号后的第一项,且需要是小写字母。 - https://shiki.style/languages - 方括号包裹的是文件名。 - icon=图标、wrap、expand 都是 meta 标记。 - 如果要在代码块中嵌套代码块语法,外层可以用四个反引号包裹。 ```
高亮和转换
代码块通过 Shiki 进行高亮,可在 blog.config.ts 中配置语言(Markdown 中出现的所有语言)和代码高亮主题。
转换器(如 diff)可通过 https://shiki.style/packages/transformers#transformers 配置,启用的转换器可在 app/stores/shiki.ts 查看。
为更多语言匹配图标
你可以根据 app/utils/icon.ts 语言图标匹配流程为文件后缀、语言简写或别名添加匹配规则来为更多语言匹配图标:
- 查找
file2icon映射表,将文件名后缀替换为图标名。 - 若无匹配,查找
ext2lang映射表,将语言简写或别名转换为 Catppuccin 图标库中的语言名。 - 将 Catppuccin 图标库中的语言名转换为 Iconify 图标名。
表格 ProseTable
支持表格横向滚动或自动换行的切换。
| 表头滚动吸附 | 滚动时边缘羽化 | 如果标题或内容很 loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog | 这里还有一列,但是是空内容 |
|---|---|---|---|
| 已实现 | 已实现 | 可以切换滚动方式 |
脚注
由remark-gfm的micromark-extension-gfm-footnote驱动的脚注1。
数学公式
由 remark- 驱动,支持 和部分 语法。如果 Markdown 正文需要直接使用 $ 符号,需要使用
\$转义。
许可协议和侧栏插槽
由自编写的rehype-meta-slots插件实现,插槽必须是文章的直接子元素,内容已插入到文章末尾 2 和目录侧栏。
---
aside: [toc, meta-aside-foo, meta-aside-bar]
---
::meta-aside-foo{title="从文章插入的组件" card}
展示remark插件能力,为用户自己编写插件提供实现思路。
虽然一般情况下, :blur[文章侧栏不需要组件]
::
:::meta-aside-bar
::link-card
---
title: MDC 基本语法(必读)
icon: https://v2.content.nuxt.com/favicon.ico
link: https://content.nuxt.com/docs/files/markdown#mdc-syntax
---
::
:::
::meta-copyright{title="本文章不保留版权"}
通过 [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/deed.zh-hans){icon="ri:creative-commons-zero-line"} 贡献至公共领域。
::
乐谱渲染播放
由自编写的remark-music插件实现,必要时可用豆包等 AI 将乐谱识别为 ABC 记法。只在网络状态良好时加载播放能力。
编辑器、Cheat Sheet 和语法检查:https://editor.drawthedots.com/
自定义组件
可以通过 Vue 模板语法、MDC 语法使用的组件。
Alert
Badge
BlogHeader
鼠标悬浮时的动画 Emoji 📄🦌🙌🐟🏖️ 对应“纸鹿摸鱼处”的汉字,在 app.config.ts 中配置,字体由 阿里妈妈方圆体 分割而来。
# iconfont 网页版生成的字体子集在 Chrome 124 的版本无法解析,需要借助 fonttools 工具手动生成子集 pip install fonttools brotli pyftsubset ./AlimamaFangYuanTi.ttf --text=Header文本 --flavor=woff2
Blur
CardList
给列表刷上了自定义样式,待完善。
Chat
Copy
自动推断语言
语言从 app/utils/str.ts 的 getPromptLanguage 里根据命令提示符前缀推断,使用 plain-shiki 高亮。和之前的 Markdown 代码块使用相同的高亮语言和高亮主题配置。
EmojiClock
现在几点了?
FeedCard 和 FeedGroup
用于在友链页面展示链接,由于友链页面的 Markdown 部分要可能会显示这个组件,就放在这个目录下大家都能调用了。去友链页面看看吧。
Folding
折叠组件,支持折叠和展开,可以嵌套使用。
Key
按下键时会亮,可以通过
@press配置触发事件,鼠标点击也会触发事件,博客全站搜索框的按键提示使用了这个组件。
LinkBanner
LinkCard
Pic
用于展示图片,支持说明文字、点击后打开灯箱缩放。
Poetry
在文章的 type 为
tech或story时,它有不同的样式。
Quote
在文章的 type 为
tech或story时,它有不同的样式。
Tab
Timeline
Tip
VideoEmbed
放点视频给你看。
组件使用方法
一是看开头提到的 MDC 文档,至关重要。二是看使用组件对应的源代码 (example.md),也很重要。三是看我文章的调用方式,没有就慎用。
组件的不完美性
博客开发精力有限,常用的组件会仔细打磨,不常用的组件仅仅满足需求。
所以,少年,选择你的英雄吧!
Footnotes
- README of micromark-extension-gfm-footnote ↩
- 文章末尾有特殊许可协议,还可从此处返回正文对插槽的讲解。 ↩
评论区
评论加载中...