|
1 | | -import { URL } from 'url' |
2 | | - |
3 | | -import type { Element, Root } from 'hast' |
4 | 1 | import rehypeFormat from 'rehype-format' |
5 | 2 | import rehypeParse from 'rehype-parse' |
6 | 3 | import rehypePresetMinify from 'rehype-preset-minify' |
7 | 4 | import rehypeStringify from 'rehype-stringify' |
8 | 5 | import { unified } from 'unified' |
9 | 6 | import type { MinimalDuplex } from 'unified-stream' |
10 | 7 | import { stream } from 'unified-stream' |
11 | | -import { remove } from 'unist-util-remove' |
12 | | -import { visit } from 'unist-util-visit' |
13 | | - |
14 | | -const CLASSNAME_MAPPER = { |
15 | | - 'toc-macro': 'toc', |
16 | | - 'hide-toolbar': 'expandable', |
17 | | - 'confluence-information-macro': 'alert', |
18 | | - code: 'code', |
19 | | - panel: 'panel', |
20 | | - panelHeader: 'panel-header', |
21 | | - panelContent: 'panel-content', |
22 | | - confluenceTd: 'border-td', |
23 | | - confluenceTh: 'border-th', |
24 | | -} |
25 | | - |
26 | | -// eslint-disable-next-line sonarjs/cognitive-complexity |
27 | | -export const rehypeConfluence = () => (root: Root) => { |
28 | | - remove( |
29 | | - root, |
30 | | - node => |
31 | | - node.type === 'element' && |
32 | | - (['style', 'script'].includes(node.tagName) || |
33 | | - (node.properties?.className as string[] | undefined)?.some(className => |
34 | | - ['aui-icon', 'hide-border-bottom', 'hidden'].includes(className), |
35 | | - )), |
36 | | - ) |
37 | 8 |
|
38 | | - remove(root, node => { |
39 | | - if (node.type === 'element' && node.tagName === 'p') { |
40 | | - return node.children.every(item => { |
41 | | - if (item.type === 'text') { |
42 | | - return !item.value.trim() |
43 | | - } |
44 | | - |
45 | | - return false |
46 | | - }) |
47 | | - } |
48 | | - }) |
49 | | - |
50 | | - visit( |
51 | | - root, |
52 | | - node => node.type === 'element' && !!(node as Element).properties, |
53 | | - _el => { |
54 | | - const properties = (_el as Element).properties! |
55 | | - for (const key of Object.keys(properties)) { |
56 | | - switch (key) { |
57 | | - case 'className': { |
58 | | - const className = properties.className as string[] |
59 | | - properties.className = className |
60 | | - // eslint-disable-next-line array-callback-return |
61 | | - .map(name => { |
62 | | - if (name in CLASSNAME_MAPPER) { |
63 | | - return CLASSNAME_MAPPER[name as keyof typeof CLASSNAME_MAPPER] |
64 | | - } |
65 | | - |
66 | | - if (name.startsWith('confluence-information-macro-')) { |
67 | | - return name.replace('confluence-information-macro-', 'alert-') |
68 | | - } |
69 | | - }) |
70 | | - .filter(Boolean) as string[] |
71 | | - if (properties.className.length === 0) { |
72 | | - delete properties.className |
73 | | - } |
74 | | - if (properties.style) { |
75 | | - delete properties.style |
76 | | - } |
77 | | - break |
78 | | - } |
79 | | - case 'dataSyntaxhighlighterParams': { |
80 | | - const params = properties[key] as string |
81 | | - const matched = /brush:\s*([^;]+);/.exec(params) |
82 | | - const lang = matched?.[1] |
83 | | - if (lang) { |
84 | | - properties.className = ['language-' + lang] |
85 | | - } |
86 | | - delete properties[key] |
87 | | - break |
88 | | - } |
89 | | - case 'href': { |
90 | | - const href = properties.href as string |
91 | | - const url = new URL(href) |
92 | | - const matched = /\?pageId=(\d+)/.exec(url.search) |
93 | | - if (matched) { |
94 | | - properties.href = '/knowledge/' + matched[1] + url.hash |
95 | | - } |
96 | | - break |
97 | | - } |
98 | | - default: { |
99 | | - if (key.startsWith('data')) { |
100 | | - delete properties[key] |
101 | | - } |
102 | | - } |
103 | | - } |
104 | | - } |
105 | | - }, |
106 | | - ) |
107 | | -} |
| 9 | +import { rehypeConfluence } from './rehype-confluence' |
108 | 10 |
|
109 | 11 | const getProcessor = (minify?: boolean | undefined) => { |
110 | 12 | let processor = unified() |
|
0 commit comments