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
85
86
87
88
89
90
91
92
93
94
95
96
|
import type Hast from 'hast';
import { classnames } from 'hast-util-classnames';
import rehypeParse from 'rehype-parse';
import rehypeSlug from 'rehype-slug';
import rehypeStringify from 'rehype-stringify';
import { unified, type Plugin as UnifiedPlugin } from 'unified';
import { visit } from 'unist-util-visit';
/**
* Update a stringified HTML tree using unified plugins.
*
* It will parse the provided content to add id to each headings.
*
* @param {string} content - The page contents.
* @returns {string} The updated page contents.
*/
export const updateContentTree = (content: string): string =>
unified()
.use(rehypeParse, { fragment: true })
.use(rehypeSlug)
.use(rehypeStringify)
.processSync(content)
.toString();
const isSubStrIn = (substr: string | RegExp, str: string) => {
if (typeof substr === 'string') return str.includes(substr);
return substr.test(str);
};
const isNodeContainsClass = (
node: Hast.Element,
className: string | RegExp
) => {
if (Array.isArray(node.properties.className)) {
return node.properties.className.some(
(singleClass) =>
typeof singleClass === 'string' && isSubStrIn(className, singleClass)
);
}
if (typeof node.properties.className === 'string')
return isSubStrIn(className, node.properties.className);
return false;
};
const rehypePrismClass: UnifiedPlugin<
Record<'className', string>[],
Hast.Root
> =
({ className }) =>
(tree) => {
const wpBlockClassName = 'wp-block-code';
const lineNumbersClassName = className
.replace('command-line', '')
.replace(/\s\s+/g, ' ');
const commandLineClassName = className
.replace('line-numbers', '')
.replace(/\s\s+/g, ' ');
visit(tree, 'element', (node) => {
if (
node.tagName === 'pre' &&
isNodeContainsClass(node, wpBlockClassName)
) {
if (isNodeContainsClass(node, 'language-bash')) {
classnames(node, commandLineClassName);
node.properties['data-filter-output'] = '#output#';
} else if (isNodeContainsClass(node, /language-/)) {
classnames(node, lineNumbersClassName);
}
}
});
};
/**
* Update a stringified HTML tree using unified plugins.
*
* It will parse the provided content to update the classnames of WordPress
* code blocks.
*
* @param {string} content - The page contents.
* @param {string} className - The prism classNames.
* @returns {string} The updated page contents.
*/
export const updateWordPressCodeBlocks = (
content: string,
className: string
): string =>
unified()
.use(rehypeParse, { fragment: true })
.use(rehypePrismClass, { className })
.use(rehypeStringify)
.processSync(content)
.toString();
|