Skip to content

Commit 7b9c0f4

Browse files
committed
fix(transformers): make transformers works well together
1 parent c76fe98 commit 7b9c0f4

File tree

7 files changed

+98
-34
lines changed

7 files changed

+98
-34
lines changed

packages/shikiji-transformers/src/transformers/render-whitespace.ts

+37-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
3+
import type { Element } from 'hast'
34

45
export interface TransformerRenderWhitespaceOptions {
56
/**
@@ -44,38 +45,45 @@ export function transformerRenderWhitespace(
4445

4546
return {
4647
name: 'shikiji-transformers:render-whitespace',
47-
line(node) {
48-
const first = node.children[0]
49-
if (!first || first.type !== 'element')
50-
return
51-
const textNode = first.children[0]
52-
if (!textNode || textNode.type !== 'text')
53-
return
54-
node.children = node.children.flatMap((token) => {
55-
if (token.type !== 'element')
56-
return token
57-
const node = token.children[0]
58-
if (node.type !== 'text' || !node.value)
59-
return token
48+
root(root) {
49+
const pre = root.children[0] as Element
50+
const code = pre.children[0] as Element
51+
code.children.forEach((line) => {
52+
if (line.type !== 'element')
53+
return
54+
const first = line.children[0]
55+
if (!first || first.type !== 'element')
56+
return
57+
const textNode = first.children[0]
58+
if (!textNode || textNode.type !== 'text')
59+
return
60+
line.children = line.children.flatMap((token) => {
61+
if (token.type !== 'element')
62+
return token
63+
const node = token.children[0]
64+
if (node.type !== 'text' || !node.value)
65+
return token
6066

61-
// Split by whitespaces
62-
const parts = node.value.split(/([ \t])/).filter(i => i.length)
63-
if (parts.length <= 1)
64-
return token
67+
// Split by whitespaces
68+
const parts = node.value.split(/([ \t])/).filter(i => i.length)
69+
if (parts.length <= 1)
70+
return token
6571

66-
return parts.map((part) => {
67-
const clone = {
68-
...token,
69-
properties: { ...token.properties },
70-
}
71-
clone.children = [{ type: 'text', value: part }]
72-
if (keys.includes(part)) {
73-
addClassToHast(clone, classMap[part])
74-
delete clone.properties.style
75-
}
76-
return clone
72+
return parts.map((part) => {
73+
const clone = {
74+
...token,
75+
properties: { ...token.properties },
76+
}
77+
clone.children = [{ type: 'text', value: part }]
78+
if (keys.includes(part)) {
79+
addClassToHast(clone, classMap[part])
80+
delete clone.properties.style
81+
}
82+
return clone
83+
})
7784
})
78-
})
85+
},
86+
)
7987
},
8088
}
8189
}

packages/shikiji-transformers/src/utils.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ export function createCommentNotationTransformer(
4343
if (text.type !== 'text')
4444
continue
4545

46+
let replaced = false
4647
text.value = text.value.replace(regex, (...match) => {
47-
if (onMatch.call(this, match, line, child, lines, idx))
48+
if (onMatch.call(this, match, line, child, lines, idx)) {
49+
replaced = true
4850
return ''
51+
}
4952
return match[0]
5053
})
51-
if (!text.value.trim())
54+
if (replaced && !text.value.trim())
5255
nodeToRemove = child
5356
}
5457
if (nodeToRemove)

packages/shikiji-transformers/test/fixtures.test.ts

+35-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest'
44
import type { ShikijiTransformer } from 'shikiji'
55
import { codeToHtml } from 'shikiji'
66
import {
7+
transformerCompactLineOptions,
78
transformerNotationDiff,
89
transformerNotationErrorLevel,
910
transformerNotationFocus,
@@ -82,7 +83,7 @@ suite(
8283
body { margin: 0; }
8384
.shiki { padding: 1em; }
8485
.line { display: block; width: 100%; height: 1.2em; }
85-
.highlighted { background-color: #888; }
86+
.highlighted { background-color: #8885; }
8687
</style>`,
8788
)
8889

@@ -114,3 +115,36 @@ body { margin: 0; }
114115
.space::before { content: "\\B7"; position: absolute; opacity: 0.3; }
115116
</style>`,
116117
)
118+
119+
suite(
120+
'all',
121+
import.meta.glob('./fixtures/all/*.*', { as: 'raw', eager: true }),
122+
[
123+
transformerNotationDiff(),
124+
transformerNotationFocus(),
125+
transformerNotationHighlight(),
126+
transformerNotationErrorLevel(),
127+
transformerCompactLineOptions([
128+
{
129+
line: 2,
130+
classes: ['highlighted'],
131+
},
132+
]),
133+
transformerRenderWhitespace(),
134+
transformerRemoveLineBreak(),
135+
],
136+
code => `${code}
137+
<style>
138+
* { tab-size: 4; }
139+
body { margin: 0; }
140+
.shiki { padding: 1em; }
141+
.line { display: block; width: 100%; height: 1.2em; }
142+
.has-focused .focused { background-color: #8805; }
143+
.highlighted { background-color: #8885; }
144+
.highlighted.warning { background-color: #9905; }
145+
.highlighted.error { background-color: #8005; }
146+
.tab, .space { position: relative; }
147+
.tab::before { content: "\\21E5"; position: absolute; opacity: 0.3; }
148+
.space::before { content: "\\B7"; position: absolute; opacity: 0.3; }
149+
</style>`,
150+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function hello(indentSize, type) {
2+
if (indentSize === 4 && type !== 'tab') {
3+
console.log('Each next indentation will increase on 4 spaces'); // [!code error] // [!code focus]
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<pre class="shiki github-dark has-focused has-highlighted" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">function</span><span class="space"> </span><span style="color:#B392F0">hello</span><span style="color:#E1E4E8">(</span><span style="color:#FFAB70">indentSize</span><span style="color:#E1E4E8">,</span><span class="space"> </span><span style="color:#FFAB70">type</span><span style="color:#E1E4E8">)</span><span class="space"> </span><span style="color:#E1E4E8">{</span></span><span class="line highlighted"><span class="space"> </span><span class="space"> </span><span style="color:#F97583">if</span><span class="space"> </span><span style="color:#E1E4E8">(indentSize</span><span class="space"> </span><span style="color:#F97583">===</span><span class="space"> </span><span style="color:#79B8FF">4</span><span class="space"> </span><span style="color:#F97583">&#x26;&#x26;</span><span class="space"> </span><span style="color:#E1E4E8">type</span><span class="space"> </span><span style="color:#F97583">!==</span><span class="space"> </span><span style="color:#9ECBFF">'tab'</span><span style="color:#E1E4E8">)</span><span class="space"> </span><span style="color:#E1E4E8">{</span></span><span class="line focused highlighted error"><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="space"> </span><span class="tab"> </span><span style="color:#E1E4E8">console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'Each</span><span class="space"> </span><span style="color:#9ECBFF">next</span><span class="space"> </span><span style="color:#9ECBFF">indentation</span><span class="space"> </span><span style="color:#9ECBFF">will</span><span class="space"> </span><span style="color:#9ECBFF">increase</span><span class="space"> </span><span style="color:#9ECBFF">on</span><span class="space"> </span><span style="color:#9ECBFF">4</span><span class="space"> </span><span style="color:#9ECBFF">spaces'</span><span style="color:#E1E4E8">);</span><span class="space"> </span></span><span class="line"><span class="space"> </span><span class="space"> </span><span style="color:#E1E4E8">}</span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
2+
<style>
3+
* { tab-size: 4; }
4+
body { margin: 0; }
5+
.shiki { padding: 1em; }
6+
.line { display: block; width: 100%; height: 1.2em; }
7+
.has-focused .focused { background-color: #8805; }
8+
.highlighted { background-color: #8885; }
9+
.highlighted.warning { background-color: #9905; }
10+
.highlighted.error { background-color: #8005; }
11+
.tab, .space { position: relative; }
12+
.tab::before { content: "\21E5"; position: absolute; opacity: 0.3; }
13+
.space::before { content: "\B7"; position: absolute; opacity: 0.3; }
14+
</style>

packages/shikiji-transformers/test/fixtures/highlight/a.js.output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
body { margin: 0; }
44
.shiki { padding: 1em; }
55
.line { display: block; width: 100%; height: 1.2em; }
6-
.highlighted { background-color: #888; }
6+
.highlighted { background-color: #8885; }
77
</style>

packages/shikiji-transformers/test/fixtures/highlight/mutliple-lines.js.output.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
body { margin: 0; }
44
.shiki { padding: 1em; }
55
.line { display: block; width: 100%; height: 1.2em; }
6-
.highlighted { background-color: #888; }
6+
.highlighted { background-color: #8885; }
77
</style>

0 commit comments

Comments
 (0)