From 194557fae213054c20343c2ff786869c0f47b52a Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 26 Jan 2024 22:17:03 +0100 Subject: [PATCH] feat: support ansi background color, fix #432 --- packages/core/src/code-to-hast.ts | 2 ++ packages/core/src/code-to-tokens-ansi.ts | 10 ++++-- packages/core/src/types.ts | 4 +++ packages/shiki/test/ansi.test.ts | 32 ++++++++++++-------- packages/shiki/test/out/ansi-background.html | 6 ++++ packages/shiki/test/out/ansi.html | 7 +++++ 6 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 packages/shiki/test/out/ansi-background.html create mode 100644 packages/shiki/test/out/ansi.html diff --git a/packages/core/src/code-to-hast.ts b/packages/core/src/code-to-hast.ts index dee2e9f62..f57648a30 100644 --- a/packages/core/src/code-to-hast.ts +++ b/packages/core/src/code-to-hast.ts @@ -274,6 +274,8 @@ function getTokenStyleObject(token: TokenStyles) { const styles: Record = {} if (token.color) styles.color = token.color + if (token.bgColor) + styles['background-color'] = token.bgColor if (token.fontStyle) { if (token.fontStyle & FontStyle.Italic) styles['font-style'] = 'italic' diff --git a/packages/core/src/code-to-tokens-ansi.ts b/packages/core/src/code-to-tokens-ansi.ts index a0c143db4..b6e2b75aa 100644 --- a/packages/core/src/code-to-tokens-ansi.ts +++ b/packages/core/src/code-to-tokens-ansi.ts @@ -28,10 +28,15 @@ export function tokenizeAnsiWithTheme( return lines.map(line => parser.parse(line[0]).map((token): ThemedToken => { let color: string - if (token.decorations.has('reverse')) + let bgColor: string | undefined + if (token.decorations.has('reverse')) { color = token.background ? colorPalette.value(token.background) : theme.bg - else + bgColor = token.foreground ? colorPalette.value(token.foreground) : theme.fg + } + else { color = token.foreground ? colorPalette.value(token.foreground) : theme.fg + bgColor = token.background ? colorPalette.value(token.background) : undefined + } color = applyColorReplacements(color, colorReplacements) @@ -52,6 +57,7 @@ export function tokenizeAnsiWithTheme( content: token.value, offset: line[1], // TODO: more accurate offset? might need to fork ansi-sequence-parser color, + bgColor, fontStyle, } }), diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index ec4a4f610..53fe5d5ef 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -626,6 +626,10 @@ export interface TokenStyles { * 6 or 8 digit hex code representation of the token's color */ color?: string + /** + * 6 or 8 digit hex code representation of the token's background color + */ + bgColor?: string /** * Font style of token. Can be None/Italic/Bold/Underline */ diff --git a/packages/shiki/test/ansi.test.ts b/packages/shiki/test/ansi.test.ts index cc6f07946..dafaf3a7f 100644 --- a/packages/shiki/test/ansi.test.ts +++ b/packages/shiki/test/ansi.test.ts @@ -1,13 +1,11 @@ /* eslint-disable no-irregular-whitespace */ import { expect, it } from 'vitest' import { - getHighlighter, + codeToHtml, } from '../src' it('renders ansi to html', async () => { - const highlighter = await getHighlighter({ themes: ['monokai'] }) - - const out = highlighter.codeToHtml(` WARN  using --force I sure hope you know what you are doing + const out = await codeToHtml(` WARN  using --force I sure hope you know what you are doing Scope: all 6 workspace projects Lockfile is up to date, resolution step is skipped Packages: +952 @@ -15,13 +13,21 @@ Packages: +952 Progress: resolved 952, reused 910, downloaded 42, added 952, done Done in 15.7s`, { theme: 'monokai', lang: 'ansi' }) - expect(out).toMatchInlineSnapshot(` - "
 WARN  using --force I sure hope you know what you are doing
-    Scope: all 6 workspace projects
-    Lockfile is up to date, resolution step is skipped
-    Packages: +952
-    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    Progress: resolved 952, reused 910, downloaded 42, added 952, done
-    Done in 15.7s
" - `) + expect(out).toMatchFileSnapshot('./out/ansi.html') +}) + +// https://github.com/shikijs/shiki/issues/432 +it('renders ansi with background', async () => { + const code = ` +❯ pnpm install --force + WARN  using --force I sure hope you know what you are doing +Scope: all 6 workspace projects +Lockfile is up to date, resolution step is skipped +Packages: +1038 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +`.trim() + + const out = await codeToHtml(code, { theme: 'monokai', lang: 'ansi' }) + + expect(out).toMatchFileSnapshot('./out/ansi-background.html') }) diff --git a/packages/shiki/test/out/ansi-background.html b/packages/shiki/test/out/ansi-background.html new file mode 100644 index 000000000..77342f0be --- /dev/null +++ b/packages/shiki/test/out/ansi-background.html @@ -0,0 +1,6 @@ +
 pnpm install --force
+ WARN  using --force I sure hope you know what you are doing
+Scope: all 6 workspace projects
+Lockfile is up to date, resolution step is skipped
+Packages: +1038
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
\ No newline at end of file diff --git a/packages/shiki/test/out/ansi.html b/packages/shiki/test/out/ansi.html new file mode 100644 index 000000000..c7f117e8f --- /dev/null +++ b/packages/shiki/test/out/ansi.html @@ -0,0 +1,7 @@ +
 WARN  using --force I sure hope you know what you are doing
+Scope: all 6 workspace projects
+Lockfile is up to date, resolution step is skipped
+Packages: +952
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Progress: resolved 952, reused 910, downloaded 42, added 952, done
+Done in 15.7s
\ No newline at end of file