Skip to content

Commit

Permalink
feat: support mergeWhitespaces: never for themes are not handling p…
Browse files Browse the repository at this point in the history
…erfectly
  • Loading branch information
antfu committed Jan 1, 2024
1 parent 425344b commit 744598a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 8 deletions.
29 changes: 28 additions & 1 deletion packages/shikiji-core/src/renderer-hast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ export function tokensToHast(
console.warn('[shikiji] `transforms` option is deprecated, use `transformers` instead')
}

if (mergeWhitespaces)
if (mergeWhitespaces === true)
tokens = mergeWhitespaceTokens(tokens)
else if (mergeWhitespaces === 'never')
tokens = splitWhitespaceTokens(tokens)

const lines: (Element | Text)[] = []
const tree: Root = {
Expand Down Expand Up @@ -325,3 +327,28 @@ function mergeWhitespaceTokens(tokens: ThemedToken[][]) {
return newLine
})
}

function splitWhitespaceTokens(tokens: ThemedToken[][]) {
return tokens.map((line) => {
return line.flatMap((token) => {
if (token.content.match(/^\s+$/))
return token
const match = token.content.match(/^(\s*)(.*?)(\s*)$/)
if (!match)
return token
const [, leading, content, trailing] = match
if (!leading && !trailing)
return token

const expanded = [{
...token,
content,
}]
if (leading)
expanded.unshift({ content: leading })
if (trailing)
expanded.push({ content: trailing })
return expanded
})
})
}
9 changes: 6 additions & 3 deletions packages/shikiji-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,15 @@ export interface CodeToHastOptionsCommon<Languages extends string = string> exte
lang: StringLiteralUnion<Languages | SpecialLanguage>

/**
* Merge token with only whitespace to the next token,
* Saving a few extra `<span>`
* Merge whitespace tokens to saving extra `<span>`.
*
* When set to true, it will merge whitespace tokens with the next token.
* When set to false, it keep the output as-is.
* When set to `never`, it will force to separate leading and trailing spaces from tokens.
*
* @default true
*/
mergeWhitespaces?: boolean
mergeWhitespaces?: boolean | 'never'
}

export interface CodeToTokensWithThemesOptions<Languages = string, Themes = string> {
Expand Down
2 changes: 1 addition & 1 deletion packages/shikiji-transformers/src/transformers/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function isSpace(part: string) {
return part === ' ' || part === '\t'
}

export function mergeSpaces(
export function splitSpaces(
parts: string[],
type: 'all' | 'boundary' | 'trailing',
renderContinuousSpaces = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ShikijiTransformer } from 'shikiji'
import { addClassToHast } from 'shikiji'
import type { Element } from 'hast'
import { mergeSpaces } from './_utils'
import { splitSpaces } from './_utils'

export interface TransformerRenderWhitespaceOptions {
/**
Expand Down Expand Up @@ -64,7 +64,7 @@ export function transformerRenderWhitespace(
return token

// Split by whitespaces
const parts = mergeSpaces(
const parts = splitSpaces(
node.value.split(/([ \t])/).filter(i => i.length),
(position === 'boundary' && index === last && last !== 0)
? 'trailing'
Expand Down
2 changes: 1 addition & 1 deletion packages/shikiji-twoslash/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function createTransformerFactory(defaultTwoslasher: typeof twoslasher) {
lang = langAlias[shikijiOptions.lang]

if (filter(lang, code, shikijiOptions)) {
shikijiOptions.mergeWhitespaces = false
shikijiOptions.mergeWhitespaces = 'never'
const twoslash = twoslasher(code, lang, twoslashOptions)
this.meta.twoslash = twoslash
return twoslash.code
Expand Down

0 comments on commit 744598a

Please sign in to comment.