Skip to content

Commit 2bde863

Browse files
committed
docs(element-transform): added documentations
Signed-off-by: Neko Ayaka <neko@ayaka.moe>
1 parent fadf8b8 commit 2bde863

9 files changed

Lines changed: 371 additions & 6 deletions

File tree

docs/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
"@rive-app/canvas": "^2.11.1",
2727
"@rollup/plugin-yaml": "^4.1.2",
2828
"@shikijs/vitepress-twoslash": "^1.2.4",
29+
"@types/markdown-it": "^13.0.7",
2930
"@types/markdown-it-footnote": "^3.0.4",
31+
"markdown-it": "^13.0.2",
3032
"markdown-it-footnote": "^4.0.0",
3133
"thumbhash": "^0.1.1",
3234
"unlazy": "^0.11.2"

docs/pages/en/integrations/markdown-it-bi-directional-links/index.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ Install `@nolebase/markdown-it-bi-directional-links` to your project dependencie
5555

5656
::: code-group
5757

58+
```shell [@antfu/ni]
59+
ni @nolebase/markdown-it-bi-directional-links -D
60+
```
61+
5862
```shell [pnpm]
5963
pnpm add @nolebase/markdown-it-bi-directional-links -D
6064
```
@@ -113,8 +117,8 @@ Then you need to use the `use()` member methods from the `markdown-it` instance
113117
With a options object that contains a `dir` field which is the root directory of your project supplied, the value for `dir` field can be obtained through `cwd()` function call that imported from either `process` or `node:process`:
114118
115119
```typescript twoslash
116-
import type { MarkdownIt } from 'markdown-it'
117-
let markdownIt = null as MarkdownIt
120+
import MarkdownIt from 'markdown-it'
121+
let markdownIt: MarkdownIt = null as unknown as MarkdownIt
118122
// ---cut---
119123
import { BiDirectionalLinks } from '@nolebase/markdown-it-bi-directional-links' // [!code ++]
120124
import { cwd } from 'node:process' // [!code ++]
1.44 MB
Loading
1.46 MB
Loading
Lines changed: 179 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,182 @@
11
# Elements Transformation <Badge type="tip" text="v1.28.0" />
22

3-
::: warning 🚧 Constructing
4-
Nice to meet you! But sorry, this page is still under construction. If you don’t find the information you are interested in, you can first find the content you are interested in in the navigation in the sidebar to start reading.
3+
This is a low-level plugin that is intended to be used by advanced users who want to transform the `markdown-it` [tokens](https://markdown-it.github.io/markdown-it/#Token) to perform tasks like replacing elements, adding attributes, etc.
4+
5+
::: warning Before you start
6+
7+
This plugin primarily is a helper utility markdown-it plugin for [Inline Links Previewing](/pages/en/integrations/vitepress-plugin-inline-link-preview/) to help to transform all the `<a>` elements to `<NolebaseInlineLinkPreview>` components.
8+
9+
When using this plugin directly, you may encounter errors like `Invalid tag`, or `Element missing end tag` errors when integrating with VitePress or Vue markdown plugins after transforming [tokens](https://markdown-it.github.io/markdown-it/#Token) and elements,
10+
or other markdown-it plugins that are not compatible with the transformed elements. Please use it when you understand how the [Token API](https://markdown-it.github.io/markdown-it/#Token) of `markdown-it` works.
11+
12+
:::
13+
14+
## Installation
15+
16+
Install `@nolebase/markdown-it-bi-element-transform` to your project dependencies by running the following command:
17+
18+
::: code-group
19+
20+
```shell [@antfu/ni]
21+
ni @nolebase/markdown-it-bi-element-transform -D
22+
```
23+
24+
```shell [pnpm]
25+
pnpm add @nolebase/markdown-it-bi-element-transform -D
26+
```
27+
28+
```shell [npm]
29+
npm install @nolebase/markdown-it-bi-element-transform -D
30+
```
31+
32+
```shell [yarn]
33+
yarn add @nolebase/markdown-it-bi-element-transform -D
34+
```
35+
536
:::
37+
38+
39+
## Usage
40+
41+
::: tip Suggestions to developers
42+
43+
When learning, debugging, we suggest including [`vite-plugin-inspect`](https://github.com/antfu/vite-plugin-inspect) in your project. It allows you to inspect the intermediate state of Vite plugins, Markdown transformations. After installing, you can visit [](http://localhost:5173/__inspect/) to inspect the modules and transformation stack of your project.
44+
45+
Check out install instructions in the [`vite-plugin-inspect` docs](https://github.com/antfu/vite-plugin-inspect).
46+
47+
<picture>
48+
<source srcset="./assets/vite-plugin-inspect-screenshot-day-theme.png" media="(prefers-color-scheme: light)">
49+
<source srcset="./assets/vite-plugin-inspect-screenshot-night-theme.png" media="(prefers-color-scheme: dark)">
50+
<img src="./assets//vite-plugin-inspect-screenshot-day-theme.png" alt="Screenshot of vite-plugin-inspect" />
51+
</picture>
52+
53+
:::
54+
55+
### Use with [Inline Links Previewing](/pages/en/integrations/vitepress-plugin-inline-link-preview/)
56+
57+
Use this plugin with [Inline Links Previewing](/pages/en/integrations/vitepress-plugin-inline-link-preview/) to replace all the `<a>` elements to `<NolebaseInlineLinkPreview>` components to enable the abilities to preview the links.
58+
59+
::: danger Implementation may change in the future for [Inline Links Previewing](/pages/en/integrations/vitepress-plugin-inline-link-preview/)
60+
61+
Such usage is a temporary workaround due to the fact that we haven't had time to refactor [Inline Links Previewing](/pages/en/integrations/vitepress-plugin-inline-link-preview/) plugin to listen the mouse hovering event of all the `<a>` elements as singleton instance across all pages for both better accessibility and compatibilities (since it replaces all the `<a>` elements and may break the markdown processing pipelines for advanced users).
62+
63+
:::
64+
65+
This is the living example code where we use it as references:
66+
67+
```ts twoslash
68+
import MarkdownIt from 'markdown-it'
69+
let markdownIt: MarkdownIt = null as unknown as MarkdownIt
70+
// ---cut---
71+
import { ElementTransform } from '@nolebase/markdown-it-element-transform'
72+
73+
markdownIt.use(ElementTransform, (() => {
74+
// Define variables inside the closure function to share the state between multiple tokens
75+
// Here we need a variable to track whether the next token needs to be transformed or not because we need to modify two tokens (link_open, link_close)
76+
let transformNextLinkCloseToken = false
77+
78+
return {
79+
transform(token) {
80+
switch (token.type) {
81+
case 'link_open':
82+
// Skip the transformation if the token is a header anchor
83+
// because the header anchor doesn't need to be previewed
84+
if (token.attrGet('class') !== 'header-anchor') {
85+
// Modify the tag of the token
86+
token.tag = 'NolebaseInlineLinkPreview'
87+
// Set the flag to transform the next link_close token
88+
transformNextLinkCloseToken = true
89+
}
90+
break
91+
case 'link_close':
92+
// Transform the token if the flag is set
93+
if (transformNextLinkCloseToken) {
94+
// Modify the tag of the token
95+
token.tag = 'NolebaseInlineLinkPreview'
96+
// Reset the flag
97+
transformNextLinkCloseToken = false
98+
}
99+
100+
break
101+
}
102+
},
103+
}
104+
})())
105+
```
106+
107+
### Use it to add more attributes to the elements
108+
109+
There are many use cases where you want to add more attributes to the elements.
110+
111+
For example:
112+
113+
1. Add `target="_blank"` and `rel="noopener noreferrer"` to all the `<a>` elements.
114+
2. Add inline styles to all the `<span>` elements.
115+
3. Add more classes to the elements.
116+
117+
#### Add `target="_blank"` and `rel="noopener noreferrer"` to links
118+
119+
```ts twoslash
120+
import MarkdownIt from 'markdown-it'
121+
let markdownIt: MarkdownIt = null as unknown as MarkdownIt
122+
// ---cut---
123+
import { ElementTransform } from '@nolebase/markdown-it-element-transform'
124+
125+
markdownIt.use(ElementTransform, (() => {
126+
return {
127+
transform(token) {
128+
if (token.type === 'link_open') {
129+
token.attrSet('target', '_blank')
130+
token.attrSet('rel', 'noopener noreferrer')
131+
}
132+
},
133+
}
134+
})())
135+
```
136+
137+
#### Add inline styles to the elements
138+
139+
```ts twoslash
140+
import MarkdownIt from 'markdown-it'
141+
let markdownIt: MarkdownIt = null as unknown as MarkdownIt
142+
// ---cut---
143+
import { ElementTransform } from '@nolebase/markdown-it-element-transform'
144+
145+
markdownIt.use(ElementTransform, (() => {
146+
return {
147+
transform(token) {
148+
if (token.type === 'span') {
149+
token.attrSet('style', 'color: red;')
150+
}
151+
},
152+
}
153+
})())
154+
```
155+
156+
#### Add more classes to the elements
157+
158+
```ts twoslash
159+
import MarkdownIt from 'markdown-it'
160+
let markdownIt: MarkdownIt = null as unknown as MarkdownIt
161+
// ---cut---
162+
import { ElementTransform } from '@nolebase/markdown-it-element-transform'
163+
164+
markdownIt.use(ElementTransform, (() => {
165+
return {
166+
transform(token) {
167+
if (token.type === 'span') {
168+
const existingClasses = token.attrGet('class') || ''
169+
token.attrSet('class', existingClasses + ' my-custom-class')
170+
}
171+
},
172+
}
173+
})())
174+
```
175+
176+
## Alternatives?
177+
178+
### [jeffbski/markdown-it-modify-token](https://github.com/jeffbski/markdown-it-modify-token)
179+
180+
Yes, this plugin does everything literally the same as [jeffbski/markdown-it-modify-token](https://github.com/jeffbski/markdown-it-modify-token). The reason why we have our own implementation is because we didn't know the existence of the plugin until we have implemented it.
181+
182+
Feel free to use the alternative if you want to. 😋
1.44 MB
Loading
1.46 MB
Loading

0 commit comments

Comments
 (0)