-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
84 lines (78 loc) · 2.46 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { Plugin } from 'unified';
import { Root, Element, Comment, Properties, Literal } from 'hast';
import { visit } from 'unist-util-visit';
import { propertiesHandle, nextChild, prevChild, getCommentObject } from './utils';
export type RehypeAttrsOptions = {
/**
* ## `data`
*
* ```markdown
* text
* <!--rehype:title=Rehype Attrs&abc=2-->
* ```
*
* ⇣⇣⇣⇣⇣⇣
*
* ```html
* <p data-config="data-config='[object Object]'">text</p>
* ```
*
* ## `string`
*
* ```markdown
* text
* <!--rehype:title=Rehype Attrs-->
* ```
*
* ⇣⇣⇣⇣⇣⇣
*
* ```html
* <p data-config="{"title":"Rehype Attrs","rehyp":true}">text</p>
* ```
*
* ## attr
*
* ```markdown
* text
* <!--rehype:title=Rehype Attrs-->
* ```
* ⇣⇣⇣⇣⇣⇣
* ```html
* <p title="Rehype Attrs">text</p>
* ```
*/
properties: 'data' | 'string' | 'attr';
}
const defaultOptions: RehypeAttrsOptions = {
properties: 'data',
}
const rehypeAttrs: Plugin<[RehypeAttrsOptions?], Root> = (options) => {
const opts = { ...defaultOptions, ...options }
return (tree) => {
visit(tree, 'element', (node, index, parent) => {
if (node.tagName === 'pre' && node && Array.isArray(node.children) && parent && Array.isArray(parent.children) && parent.children.length > 1) {
const firstChild = node.children[0] as Element;
if (firstChild && firstChild.tagName === 'code' && typeof index === 'number') {
const child = prevChild(parent.children as Literal[], index);
if (child) {
const attr = getCommentObject(child);
if (Object.keys(attr).length > 0) {
node.properties = { ...node.properties, ...{ 'data-type': 'rehyp' } }
firstChild.properties = propertiesHandle(firstChild.properties, attr, opts.properties) as Properties
}
}
}
}
if (/^(em|strong|b|a|i|p|pre|kbd|blockquote|h(1|2|3|4|5|6)|code|table|img|del|ul|ol)$/.test(node.tagName) && parent && Array.isArray(parent.children) && typeof index === 'number') {
const child = nextChild(parent.children, index)
if (child) {
const attr = getCommentObject(child as Comment)
if (Object.keys(attr).length > 0) {
node.properties = propertiesHandle(node.properties, attr, opts.properties) as Properties
}
}
}
});
}
}
export default rehypeAttrs