Skip to content

Commit 6319e26

Browse files
fix(transformers): also convert single-theme inline token styles to classes (#1344)
1 parent f8f6335 commit 6319e26

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

‎packages/transformers/src/transformers/style-to-class.ts‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ export interface ShikiTransformerStyleToClass extends ShikiTransformer {
2525
}
2626

2727
/**
28-
* Remove line breaks between lines.
29-
* Useful when you override `display: block` to `.line` in CSS.
28+
* Convert inline styles to class names, and collect the styles it creates a CSS stylesheet for
29+
* via `getCSS()`.
30+
*
31+
* Works on the `<pre>` element, on the token spans, and on tokens with custom `htmlStyle`.
3032
*/
3133
export function transformerStyleToClass(options: TransformerStyleToClassOptions = {}): ShikiTransformerStyleToClass {
3234
const {
@@ -69,6 +71,15 @@ export function transformerStyleToClass(options: TransformerStyleToClassOptions
6971
delete t.properties.style
7072
this.addClassToHast(t, className)
7173
},
74+
span(hast) {
75+
// Token colors are applied to the `<span>` elements after the `tokens` hook runs, so spans
76+
// with a plain single-theme style are caught here.
77+
if (!hast.properties.style)
78+
return
79+
const className = registerStyle(hast.properties.style as string)
80+
delete hast.properties.style
81+
this.addClassToHast(hast, className)
82+
},
7283
tokens(lines) {
7384
for (const line of lines) {
7485
for (const token of line) {

‎packages/transformers/test/style-to-class.test.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,23 @@ it('transformerStyleToClass', async () => {
5050

5151
expect(transformer.getCSS()).toMatchInlineSnapshot(`".__shiki_223nhr{--shiki-dark:#CB7676;--shiki-light:#AB5959;--shiki-nord:#81A1C1}.__shiki_u5wfov{--shiki-dark:#BD976A;--shiki-light:#B07D48;--shiki-nord:#D8DEE9}.__shiki_26darv{--shiki-dark:#666666;--shiki-light:#999999;--shiki-nord:#81A1C1}.__shiki_17lqoe{--shiki-dark:#666666;--shiki-light:#999999;--shiki-nord:#ECEFF4}.__shiki_6u0ar0{--shiki-dark:#80A665;--shiki-light:#59873A;--shiki-nord:#88C0D0}.__shiki_k92bfk{--shiki-dark:#666666;--shiki-light:#999999;--shiki-nord:#D8DEE9FF}.__shiki_1328cg{--shiki-dark:#4C9A91;--shiki-light:#2F798A;--shiki-nord:#B48EAD}.__shiki_ga6n9x{--shiki-dark:#C98A7D77;--shiki-light:#B5695977;--shiki-nord:#ECEFF4}.__shiki_23isjw{--shiki-dark:#C98A7D;--shiki-light:#B56959;--shiki-nord:#A3BE8C}.__shiki_uywmyh{--shiki-dark:#dbd7caee;--shiki-light:#393a34;--shiki-nord:#d8dee9ff;--shiki-dark-bg:#121212;--shiki-light-bg:#ffffff;--shiki-nord-bg:#2e3440ff}"`)
5252
})
53+
54+
it('transformerStyleToClass with a single theme', async () => {
55+
using shiki = await createHighlighter({
56+
themes: ['nord'],
57+
langs: ['typescript'],
58+
})
59+
60+
const transformer = transformerStyleToClass({ classPrefix: '__shiki_' })
61+
62+
const result = shiki.codeToHtml(`console.log('hello')`, {
63+
lang: 'typescript',
64+
theme: 'nord',
65+
defaultColor: false,
66+
transformers: [transformer],
67+
})
68+
69+
// Token spans should be converted to classes just like the <pre> element is.
70+
expect(result).not.toContain('<span style=')
71+
expect(transformer.getCSS()).toContain('color:#')
72+
})

0 commit comments

Comments
 (0)