Skip to content

Commit 182dc80

Browse files
committed
fix: improve transformers
1 parent 543c2b7 commit 182dc80

11 files changed

+106
-82
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
33
import { createCommentNotationTransformer } from '../utils'
4+
import { transformerNotationMap } from './notation-map'
45

56
export interface TransformerNotationDiffOptions {
67
/**
78
* Class for added lines
89
*/
9-
classAdded?: string
10+
classLineAdd?: string
1011
/**
1112
* Class for removed lines
1213
*/
13-
classRemoved?: string
14+
classLineRemove?: string
1415
/**
15-
* Class added to the root element when the current code has diff
16+
* Class added to the <pre> element when the current code has diff
1617
*/
17-
classRootActive?: string
18+
classActivePre?: string
1819
}
1920

2021
/**
@@ -24,27 +25,19 @@ export function transformerNotationDiff(
2425
options: TransformerNotationDiffOptions = {},
2526
): ShikijiTransformer {
2627
const {
27-
classAdded = 'diff add',
28-
classRemoved = 'diff remove',
29-
classRootActive = 'has-diff',
28+
classLineAdd = 'diff add',
29+
classLineRemove = 'diff remove',
30+
classActivePre = 'has-diff',
3031
} = options
3132

32-
return createCommentNotationTransformer(
33-
'shikiji-transformers:notation-diff',
34-
/\[!code (\-\-|\+\+)(:\d+)?\]/,
35-
function ([_, match, range = ':1'], _line, _comment, lines, index) {
36-
const className = match === '--'
37-
? classRemoved
38-
: classAdded
39-
const lineNum = Number.parseInt(range.slice(1), 10)
40-
lines
41-
.slice(index, index + lineNum)
42-
.forEach((line) => {
43-
addClassToHast(line, className)
44-
})
45-
if (classRootActive)
46-
addClassToHast(this.pre, classRootActive)
47-
return true
33+
return transformerNotationMap(
34+
{
35+
classMap: {
36+
'++': classLineAdd,
37+
'--': classLineRemove,
38+
},
39+
classActivePre,
4840
},
41+
'shikiji-transformers:notation-diff',
4942
)
5043
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
33
import { createCommentNotationTransformer } from '../utils'
4+
import { transformerNotationMap } from './notation-map'
45

56
export interface TransformerNotationErrorLevelOptions {
67
classMap?: Record<string, string | string[]>
8+
/**
9+
* Class added to the <pre> element when the current code has diff
10+
*/
11+
classActivePre?: string
712
}
813

914
/**
@@ -17,19 +22,14 @@ export function transformerNotationErrorLevel(
1722
error: ['highlighted', 'error'],
1823
warning: ['highlighted', 'warning'],
1924
},
25+
classActivePre = 'has-highlighted',
2026
} = options
2127

22-
return createCommentNotationTransformer(
23-
'shikiji-transformers:notation-error-level',
24-
new RegExp(`\\[!code (${Object.keys(classMap).join('|')})(:\\d+)?\\]`),
25-
([_, match, range = ':1'], _line, _comment, lines, index) => {
26-
const lineNum = Number.parseInt(range.slice(1), 10)
27-
lines
28-
.slice(index, index + lineNum)
29-
.forEach((line) => {
30-
addClassToHast(line, classMap[match])
31-
})
32-
return true
28+
return transformerNotationMap(
29+
{
30+
classMap,
31+
classActivePre,
3332
},
33+
'shikiji-transformers:notation-error-level',
3434
)
3535
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
33
import { createCommentNotationTransformer } from '../utils'
4+
import { transformerNotationMap } from './notation-map'
45

56
export interface TransformerNotationFocusOptions {
67
/**
78
* Class for focused lines
89
*/
9-
classFocused?: string
10+
classActiveLine?: string
1011
/**
1112
* Class added to the root element when the code has focused lines
1213
*/
13-
classRootActive?: string
14+
classActivePre?: string
1415
}
1516

1617
/**
@@ -20,23 +21,17 @@ export function transformerNotationFocus(
2021
options: TransformerNotationFocusOptions = {},
2122
): ShikijiTransformer {
2223
const {
23-
classFocused = 'focused',
24-
classRootActive = 'has-focused',
24+
classActiveLine = 'focused',
25+
classActivePre = 'has-focused',
2526
} = options
2627

27-
return createCommentNotationTransformer(
28-
'shikiji-transformers:notation-focus',
29-
/\[!code focus(:\d+)?\]/,
30-
function ([_, range = ':1'], _line, _comment, lines, index) {
31-
const lineNum = Number.parseInt(range.slice(1), 10)
32-
lines
33-
.slice(index, index + lineNum)
34-
.forEach((line) => {
35-
addClassToHast(line, classFocused)
36-
})
37-
if (classRootActive)
38-
addClassToHast(this.pre, classRootActive)
39-
return true
28+
return transformerNotationMap(
29+
{
30+
classMap: {
31+
focus: classActiveLine,
32+
},
33+
classActivePre,
4034
},
35+
'shikiji-transformers:notation-focus',
4136
)
4237
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
33
import { createCommentNotationTransformer } from '../utils'
4+
import { transformerNotationMap } from './notation-map'
45

56
export interface TransformerNotationHighlightOptions {
67
/**
78
* Class for highlighted lines
89
*/
9-
classHighlight?: string
10+
classActiveLine?: string
1011
/**
1112
* Class added to the root element when the code has highlighted lines
1213
*/
13-
classRootActive?: string
14+
classActivePre?: string
1415
}
1516

1617
/**
@@ -20,23 +21,18 @@ export function transformerNotationHighlight(
2021
options: TransformerNotationHighlightOptions = {},
2122
): ShikijiTransformer {
2223
const {
23-
classHighlight = 'highlighted',
24-
classRootActive = 'has-highlighted',
24+
classActiveLine = 'highlighted',
25+
classActivePre = 'has-highlighted',
2526
} = options
2627

27-
return createCommentNotationTransformer(
28-
'shikiji-transformers:notation-highlight',
29-
/\[!code (?:hl|highlight)(:\d+)?\]/,
30-
function ([_, range = ':1'], _line, _comment, lines, index) {
31-
const lineNum = Number.parseInt(range.slice(1), 10)
32-
lines
33-
.slice(index, index + lineNum)
34-
.forEach((line) => {
35-
addClassToHast(line, classHighlight)
36-
})
37-
if (classRootActive)
38-
addClassToHast(this.pre, classRootActive)
39-
return true
28+
return transformerNotationMap(
29+
{
30+
classMap: {
31+
highlight: classActiveLine,
32+
hl: classActiveLine,
33+
},
34+
classActivePre,
4035
},
36+
'shikiji-transformers:notation-highlight',
4137
)
4238
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { ShikijiTransformer } from 'shikiji'
2+
import { addClassToHast } from 'shikiji'
3+
import { createCommentNotationTransformer } from '../utils'
4+
5+
export interface TransformerNotationMapOptions {
6+
classMap?: Record<string, string | string[]>
7+
/**
8+
* Class added to the <pre> element when the current code has diff
9+
*/
10+
classActivePre?: string
11+
}
12+
13+
function escapeRegExp(str: string) {
14+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
15+
}
16+
17+
export function transformerNotationMap(
18+
options: TransformerNotationMapOptions = {},
19+
name = 'shikiji-transformers:notation-map',
20+
): ShikijiTransformer {
21+
const {
22+
classMap = {},
23+
classActivePre = undefined,
24+
} = options
25+
26+
return createCommentNotationTransformer(
27+
name,
28+
new RegExp(`\\s*(?://|/\\*|<!--|#)\\s+\\[!code (${Object.keys(classMap).map(escapeRegExp).join('|')})(:\\d+)?\\]\\s*(?:\\*/|-->)?`),
29+
function ([_, match, range = ':1'], _line, _comment, lines, index) {
30+
const lineNum = Number.parseInt(range.slice(1), 10)
31+
lines
32+
.slice(index, index + lineNum)
33+
.forEach((line) => {
34+
addClassToHast(line, classMap[match])
35+
})
36+
if (classActivePre)
37+
addClassToHast(this.pre, classActivePre)
38+
return true
39+
},
40+
)
41+
}

packages/shikiji-transformers/src/utils.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function createCommentNotationTransformer(
2323
regex: RegExp,
2424
onMatch: (
2525
this: ShikijiTransformerContext,
26-
match: RegExpMatchArray,
26+
match: string[],
2727
line: Element,
2828
commentNode: Element,
2929
lines: Element[],
@@ -39,18 +39,17 @@ export function createCommentNotationTransformer(
3939
for (const child of line.children) {
4040
if (child.type !== 'element')
4141
continue
42-
if (!isCommentLike(child, line))
43-
continue
4442
const text = child.children[0]
4543
if (text.type !== 'text')
4644
continue
47-
const match = text.value.match(regex)
48-
if (!match)
49-
continue
50-
if (onMatch.call(this, match, line, child, lines, idx)) {
45+
46+
text.value = text.value.replace(regex, (...match) => {
47+
if (onMatch.call(this, match, line, child, lines, idx))
48+
return ''
49+
return match[0]
50+
})
51+
if (!text.value.trim())
5152
nodeToRemove = child
52-
break
53-
}
5453
}
5554
if (nodeToRemove)
5655
line.children.splice(line.children.indexOf(nodeToRemove), 1)

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> foo</span><span style="color:#E1E4E8">() {</span></span><span class="line highlighted error"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'error'</span><span style="color:#E1E4E8">) </span></span><span class="line highlighted warning"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'warn'</span><span style="color:#E1E4E8">) </span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
1+
<pre class="shiki github-dark has-highlighted" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> foo</span><span style="color:#E1E4E8">() {</span></span><span class="line highlighted error"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'error'</span><span style="color:#E1E4E8">) </span></span><span class="line highlighted warning"><span style="color:#E1E4E8"> console.</span><span style="color:#B392F0">log</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">'warn'</span><span style="color:#E1E4E8">) </span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
22
<style>
33
body { margin: 0; }
44
.shiki { padding: 1em; }

packages/shikiji-transformers/test/fixtures/focus/mutliple-lines.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ export function transformerNotationFocus(
33
) {
44
const {
55
classFocused = 'focused',
6-
classRootActive = 'has-focused',
6+
classActivePre = 'has-focused',
77
} = options
88
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<pre class="shiki github-dark has-focused" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> transformerNotationFocus</span><span style="color:#E1E4E8">(</span></span><span class="line focused"><span style="color:#FFAB70"> options</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {}, </span></span><span class="line focused"><span style="color:#E1E4E8">) {</span></span><span class="line focused"><span style="color:#F97583"> const</span><span style="color:#E1E4E8"> {</span></span><span class="line focused"><span style="color:#79B8FF"> classFocused</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#79B8FF"> classRootActive</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'has-focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> options</span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
1+
<pre class="shiki github-dark has-focused" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> transformerNotationFocus</span><span style="color:#E1E4E8">(</span></span><span class="line focused"><span style="color:#FFAB70"> options</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {}, </span></span><span class="line focused"><span style="color:#E1E4E8">) {</span></span><span class="line focused"><span style="color:#F97583"> const</span><span style="color:#E1E4E8"> {</span></span><span class="line focused"><span style="color:#79B8FF"> classFocused</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#79B8FF"> classActivePre</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'has-focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> options</span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
22
<style>
33
body { margin: 0; }
44
.shiki { padding: 1em; }

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ export function transformerNotationFocus(
33
) {
44
const {
55
classFocused = 'focused',
6-
classRootActive = 'has-focused',
6+
classActivePre = 'has-focused',
77
} = options
88
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<pre class="shiki github-dark has-highlighted" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> transformerNotationFocus</span><span style="color:#E1E4E8">(</span></span><span class="line highlighted"><span style="color:#FFAB70"> options</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {}, </span></span><span class="line highlighted"><span style="color:#E1E4E8">) {</span></span><span class="line highlighted"><span style="color:#F97583"> const</span><span style="color:#E1E4E8"> {</span></span><span class="line highlighted"><span style="color:#79B8FF"> classFocused</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#79B8FF"> classRootActive</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'has-focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> options</span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
1+
<pre class="shiki github-dark has-highlighted" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> function</span><span style="color:#B392F0"> transformerNotationFocus</span><span style="color:#E1E4E8">(</span></span><span class="line highlighted"><span style="color:#FFAB70"> options</span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> {}, </span></span><span class="line highlighted"><span style="color:#E1E4E8">) {</span></span><span class="line highlighted"><span style="color:#F97583"> const</span><span style="color:#E1E4E8"> {</span></span><span class="line highlighted"><span style="color:#79B8FF"> classFocused</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#79B8FF"> classActivePre</span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> 'has-focused'</span><span style="color:#E1E4E8">,</span></span><span class="line"><span style="color:#E1E4E8"> } </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> options</span></span><span class="line"><span style="color:#E1E4E8">}</span></span><span class="line"></span></code></pre>
22
<style>
33
body { margin: 0; }
44
.shiki { padding: 1em; }

0 commit comments

Comments
 (0)