Markdown Extensions.
本博客 Markdown 拓展基于 remark 和 rehype 生态构建。
Markdown 中使用 React 组件
组件需要放置在 markdown/components 中,例如 markdown/components/ExtensionTest.tsx 内容为:
function ExtensionText() {
return <del>ExtensionText</del>
}
export default ExtensionText
再通过配置 markdown/custom-components.tsx 导入该组件:
import { lazy } from 'react'
const ExtensionTest = lazy(() => import('./ExtensionTest'))
export const customComponentMap: Record<string, any> = {
// ...
ExtensionTest,
}
输入:
<ExtensionTest />
输出:
Playground
用于展示代码和组件,包括打印栏等。不同 Tab 通过 ///
表达式分隔,后续可以加上 meta 信息(例如 line
显示行数)。其中样式基于 ShadowRoot,不会影响到全局。
NOTE
Playground
为动态运行,有风险,请谨慎使用
React 组件
支持 tsx
。
输入:
```tsx Playground
/// App.jsx
import Random from './Random'
function App() {
console.log('App')
return <div className="app">{Math.random()}</div>
}
export default App
/// App.css line
.app {
font-size: 24px;
color: blue;
}
```
输出:
import Random from './Random'
function App() {
return <div className="app">{Math.random()}</div>
}
export default App
HTML
HTML 暂不支持打印
输入:
```html Playground
/// index.html
<div class="test" onclick="console.log(111)">hello</div>
/// color.css .test { color: red; font-weight: 600; }
```
输出:
<div class="test" onclick="console.log(111)">hello</div>
用户配置
例如之前的 ExtensionTest
组件,可以通过 meta 信息控制:
输入:
```tsx Playground path="ExtensionTest" component="ExtensionTest"
```
输出:
function ExtensionText() {
return <del>ExtensionText</del>
}
export default ExtensionText
打印
在 Web Worker
中运行,主线程不会卡死。
输入:
```js Run
const start = Date.now()
console.log('start')
while (Date.now() - start < 3000) {}
console.log('end')
```
输出:
const start = Date.now()
console.log('start')
while (Date.now() - start < 3000) {}
console.log('end')
代码行数显示
通过配置 meta 信息,展示代码行数。
输入:
```tsx line
console.log('1')
console.log('2')
console.log('3')
```
输出:
console.log('1')
console.log('2')
console.log('3')
代码高亮
代码高亮分为行高亮和单词高亮,通过 shiki 实现。
这里 !code
之后只有一个空格,加了两个防止渲染。
行高亮
输入:
```ts line {1,3-4}
console.log('1')
console.log('2')
console.log('3')
console.log('4')
console.log('5') // [!code highlight]
```
输出:
console.log('1')
console.log('2')
console.log('3')
console.log('4')
console.log('5')
单词高亮
输入:
```ts /log/
// [!code word:console]
console.log('1')
console.log('2')
console.log('3')
console.log('4')
console.log('5')
```
输出:
console.log('1')
console.log('2')
console.log('3')
console.log('4')
console.log('5')
代码块增删高亮
这里 !code
之后也是只有一个空格,加了两个防止渲染。
输入:
```diff-js
-console.log('----')
+console.log('+++')
```
```js
console.log('----') // [!code --]
console.log('+++') // [!code ++]
```
输出:
console.log('----')
console.log('+++')
console.log('----')
console.log('+++')
本地远程代码
用户本地文件和远程文件代码通过配置 meta 中的 path
属性
输入:
```jsx path="ExtensionTest"
```
```js path="https://gist.githubusercontent.com/Plumbiu/7fc950397d9913b6f9558f7fc2c541ed/raw/4a3c95548679087f4ccd6ac032ed7aa1b1ca7e87/blog-remote-test.js"
```
输出:
function ExtensionText() {
return <del>ExtensionText</del>
}
export default ExtensionText
const s = 'Wow, this is from remote'
console.log(s)
代码分组
meta 添加 Switcher 字符,并通过 ///
语法划分。
输入:
```bash Switcher
/// npm
npm install @plumbiu/react-store
/// yarn
yarn add @plumbiu/react-store
/// pnpm
pnpm add @plumbiu/react-store
```
输出:
npm install @plumbiu/react-store
自定义标题
输入:
```jsx title="src/custom-title.ts"
console.log('custom-title')
```
输出:
console.log('custom-title')
文字转换
全局配置
- emoji:转换 emoji,全局配置文件 markdown/config/emoji.ts。
- 变量:通过定义变量显示文字,全局配置文件 markdown/config/variables.ts。
- definitions:类似
<!-- Definitions -->
,可将空链接或者对应语法转换为合法链接,全局配置文件 markdown/config/links.ts
输入:
:smile:
{{bar['test'].a}}
[Next.js][]
输出:
😄
Test
front-matter
输入:
---
emoji: { num: 🔢 }
variable: { var_text: 'var_text' }
definitions: { plumbiu: 'https://github.com/Plumbiu' }
---
:num:
{{var_text}}
[plumbiu][]
输出:
🔢
var_text
Blockquote
输入:
> [!NOTE] MY CUSTOM TITLE
> `Useful information` that users should know, even when skimming content.
> [!TIP] MY CUSTOM TITLE
> `Helpful advice` for doing things better or more easily.
> [!IMPORTANT] MY CUSTOM TITLE
> `Key information` users need to know to achieve their goal.
> [!WARNING] MY CUSTOM TITLE
> `Urgent info` that needs immediate user attention to avoid problems.
> [!CAUTION] MY CUSTOM TITLE
> `Advises` about risks or negative outcomes of certain actions.
输出:
MY CUSTOM TITLE
Useful information
that users should know, even when skimming content.
MY CUSTOM TITLE
Helpful advice
for doing things better or more easily.
MY CUSTOM TITLE
Key information
users need to know to achieve their goal.
MY CUSTOM TITLE
Urgent info
that needs immediate user attention to avoid problems.
MY CUSTOM TITLE
Advises
about risks or negative outcomes of certain actions.
Details
输入:
:::Details[Detail 测试]
Hello World
`console.log('details')`
:::
输出:
Detail 测试
Hello World
console.log('details')
画廊
首行通过 max-数字
,配置最大显示个数,也可以不写。
输入:
:::Gallery
max-10
2023-1.webp
threejs/flower-2.jpg
2023-2.webp
2023-3.png
threejs/flower-6.jpg
shiki-className.webp
threejs/flower-1.jpg
shiki-inline-styles.webp
toc-optimize.gif
toc.gif
threejs/flower-3.jpg
view-frustum.png
threejs/flower-4.jpg
2022-1.png
threejs/flower-5.jpg
threejs/wall.jpg
:::
输出
Literal autolink
输入:
www.example.com, https://example.com, and contact@example.com.
输出:
www.example.com, https://example.com, and contact@example.com.
footnote
输入:
A note[^1]
[^1]: Big note.
输出:
A note1
任务列表
输入:
- [ ] to do
- [x] done
输出:
- to do
- done
视频
B 站
输入:
::bilibili[【官方 MV】Never Gonna Give You Up - Rick Astley]{#BV1GJ411x7h7}
输出:
Youtube
输入:
::youtube[Rick Astley - Never Gonna Give You Up (Official Music Video)]{#dQw4w9WgXcQ}
输出:
Footnotes
-
Big note. ↩