Plumbiu
banner
avatar
Plumbiu
这人很勤奋,啥都没留

Markdown Extensions.

2025-04-27
Note

本博客 Markdown 拓展基于 remarkrehype 生态构建。

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;
}
```

输出:

Code Playground
App.jsx
App.css
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; }
```

输出:

Code Playground
index.html
color.css
<div class="test" onclick="console.log(111)">hello</div>

用户配置

例如之前的 ExtensionTest 组件,可以通过 meta 信息控制:

输入:

```tsx Playground path="ExtensionTest" component="ExtensionTest"

```

输出:

Code Playground
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')
```

输出:

Code Runner
const start = Date.now()
console.log('start')
while (Date.now() - start < 3000) {}
console.log('end')
Loading...

代码行数显示

通过配置 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
yarn
pnpm
npm install @plumbiu/react-store

自定义标题

输入:

```jsx title="src/custom-title.ts"
console.log('custom-title')
```

输出:

src/custom-title.ts
console.log('custom-title')

文字转换

全局配置

输入:

:smile:

{{bar['test'].a}}

[Next.js][]

输出:

😄

Test

Next.js

front-matter

输入:

---
emoji: { num: 🔢 }
variable: { var_text: 'var_text' }
definitions: { plumbiu: 'https://github.com/Plumbiu' }
---

:num:

{{var_text}}

[plumbiu][]

输出:

🔢

var_text

plumbiu

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

  1. Big note.

评论区
CC BY-NC-SA 4.0 2024 © Plumbiu