Skip to content

Commit 744598a

Browse files
committed
feat: support mergeWhitespaces: never for themes are not handling perfectly
1 parent 425344b commit 744598a

File tree

5 files changed

+38
-8
lines changed

5 files changed

+38
-8
lines changed

packages/shikiji-core/src/renderer-hast.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ export function tokensToHast(
157157
console.warn('[shikiji] `transforms` option is deprecated, use `transformers` instead')
158158
}
159159

160-
if (mergeWhitespaces)
160+
if (mergeWhitespaces === true)
161161
tokens = mergeWhitespaceTokens(tokens)
162+
else if (mergeWhitespaces === 'never')
163+
tokens = splitWhitespaceTokens(tokens)
162164

163165
const lines: (Element | Text)[] = []
164166
const tree: Root = {
@@ -325,3 +327,28 @@ function mergeWhitespaceTokens(tokens: ThemedToken[][]) {
325327
return newLine
326328
})
327329
}
330+
331+
function splitWhitespaceTokens(tokens: ThemedToken[][]) {
332+
return tokens.map((line) => {
333+
return line.flatMap((token) => {
334+
if (token.content.match(/^\s+$/))
335+
return token
336+
const match = token.content.match(/^(\s*)(.*?)(\s*)$/)
337+
if (!match)
338+
return token
339+
const [, leading, content, trailing] = match
340+
if (!leading && !trailing)
341+
return token
342+
343+
const expanded = [{
344+
...token,
345+
content,
346+
}]
347+
if (leading)
348+
expanded.unshift({ content: leading })
349+
if (trailing)
350+
expanded.push({ content: trailing })
351+
return expanded
352+
})
353+
})
354+
}

packages/shikiji-core/src/types.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,15 @@ export interface CodeToHastOptionsCommon<Languages extends string = string> exte
227227
lang: StringLiteralUnion<Languages | SpecialLanguage>
228228

229229
/**
230-
* Merge token with only whitespace to the next token,
231-
* Saving a few extra `<span>`
230+
* Merge whitespace tokens to saving extra `<span>`.
231+
*
232+
* When set to true, it will merge whitespace tokens with the next token.
233+
* When set to false, it keep the output as-is.
234+
* When set to `never`, it will force to separate leading and trailing spaces from tokens.
232235
*
233236
* @default true
234237
*/
235-
mergeWhitespaces?: boolean
238+
mergeWhitespaces?: boolean | 'never'
236239
}
237240

238241
export interface CodeToTokensWithThemesOptions<Languages = string, Themes = string> {

packages/shikiji-transformers/src/transformers/_utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function isSpace(part: string) {
3535
return part === ' ' || part === '\t'
3636
}
3737

38-
export function mergeSpaces(
38+
export function splitSpaces(
3939
parts: string[],
4040
type: 'all' | 'boundary' | 'trailing',
4141
renderContinuousSpaces = true,

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ShikijiTransformer } from 'shikiji'
22
import { addClassToHast } from 'shikiji'
33
import type { Element } from 'hast'
4-
import { mergeSpaces } from './_utils'
4+
import { splitSpaces } from './_utils'
55

66
export interface TransformerRenderWhitespaceOptions {
77
/**
@@ -64,7 +64,7 @@ export function transformerRenderWhitespace(
6464
return token
6565

6666
// Split by whitespaces
67-
const parts = mergeSpaces(
67+
const parts = splitSpaces(
6868
node.value.split(/([ \t])/).filter(i => i.length),
6969
(position === 'boundary' && index === last && last !== 0)
7070
? 'trailing'

packages/shikiji-twoslash/src/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function createTransformerFactory(defaultTwoslasher: typeof twoslasher) {
4949
lang = langAlias[shikijiOptions.lang]
5050

5151
if (filter(lang, code, shikijiOptions)) {
52-
shikijiOptions.mergeWhitespaces = false
52+
shikijiOptions.mergeWhitespaces = 'never'
5353
const twoslash = twoslasher(code, lang, twoslashOptions)
5454
this.meta.twoslash = twoslash
5555
return twoslash.code

0 commit comments

Comments
 (0)