1
- import { toString } from "hast-util-to-string" ;
1
+ import { Node , toString } from "hast-util-to-string" ;
2
2
import { refractor } from "refractor/lib/all.js" ;
3
3
import { visit } from "unist-util-visit" ;
4
- import { Node , Parent } from "unist" ;
5
- import { Element } from "hast" ;
6
-
7
- const languagePrefix = "language-" ;
8
-
9
- function isElement ( node : Node ) : node is Element {
10
- return node . type === "element" ;
11
- }
4
+ import { Parent } from "unist" ;
12
5
13
6
export const rehypeSyntaxHighlighting = ( options : {
14
7
ignoreMissing ?: boolean ;
@@ -19,59 +12,70 @@ export const rehypeSyntaxHighlighting = (options: {
19
12
}
20
13
21
14
return ( tree : Parent ) => {
22
- visit ( tree , isElement , ( node , _ , parent ) => {
23
- if (
24
- ! parent ||
25
- ! isElement ( parent ) ||
26
- parent . tagName !== "pre" ||
27
- node . tagName !== "code"
28
- ) {
29
- return ;
30
- }
31
-
32
- const lang = getLanguage ( node ) ;
15
+ visit (
16
+ tree ,
17
+ "element" ,
18
+ (
19
+ node : Node & {
20
+ tagName : string ;
21
+ children : Node [ ] ;
22
+ properties : {
23
+ className ?: string [ ] ;
24
+ } ;
25
+ } ,
26
+ _index ,
27
+ parent ?: {
28
+ tagName : string ;
29
+ properties : {
30
+ className ?: string [ ] ;
31
+ } ;
32
+ }
33
+ ) => {
34
+ if ( ! parent || parent . tagName !== "pre" || node . tagName !== "code" ) {
35
+ return ;
36
+ }
33
37
34
- if ( lang === null ) {
35
- return ;
36
- }
38
+ const lang = getLanguage ( node ) ;
37
39
38
- try {
39
- const existingClassName = parent . properties . className ?? [ ] ;
40
- if ( Array . isArray ( existingClassName ) ) {
41
- parent . properties . className = [
42
- ...existingClassName ,
43
- languagePrefix + lang ,
44
- ] ;
40
+ if ( lang === null ) {
41
+ return ;
45
42
}
46
- const result = refractor . highlight ( toString ( node ) , lang ) ;
47
43
48
- // @ts -expect-error refractor uses outdated version of @types/hast
49
- node . children = result . children ;
50
- } catch ( err ) {
51
- if (
52
- options . ignoreMissing &&
53
- / U n k n o w n l a n g u a g e / . test ( ( err as Error ) . message )
54
- ) {
55
- return ;
44
+ let result ;
45
+ try {
46
+ parent . properties . className = (
47
+ parent . properties . className || [ ]
48
+ ) . concat ( "language-" + lang ) ;
49
+ result = refractor . highlight ( toString ( node ) , lang ) ;
50
+ node . children = result . children ;
51
+ } catch ( err ) {
52
+ if (
53
+ options . ignoreMissing &&
54
+ / U n k n o w n l a n g u a g e / . test ( ( err as Error ) . message )
55
+ ) {
56
+ return ;
57
+ }
58
+ throw err ;
56
59
}
57
- throw err ;
58
60
}
59
- } ) ;
61
+ ) ;
60
62
} ;
61
63
} ;
62
64
63
- function getLanguage ( node : Element ) {
64
- const className = node . properties . className || [ ] ;
65
- if ( ! Array . isArray ( className ) ) {
66
- return null ;
65
+ function getLanguage (
66
+ node : Node & {
67
+ tagName : string ;
68
+ children : Node [ ] ;
69
+ properties : {
70
+ className ?: string [ ] ;
71
+ } ;
67
72
}
73
+ ) {
74
+ const className = node . properties . className || [ ] ;
68
75
69
76
for ( const classListItem of className ) {
70
- if (
71
- typeof classListItem === "string" &&
72
- classListItem . startsWith ( languagePrefix )
73
- ) {
74
- return classListItem . slice ( languagePrefix . length ) . toLowerCase ( ) ;
77
+ if ( classListItem . slice ( 0 , 9 ) === "language-" ) {
78
+ return classListItem . slice ( 9 ) . toLowerCase ( ) ;
75
79
}
76
80
}
77
81
0 commit comments