0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-30 22:03:56 -05:00

Move to shiki and stabilize dual themes support (#10130)

* Update to shiki

* Stabilize shikiConfig.experimentalThemes

* Add changeset

* Fix merge issues
This commit is contained in:
Bjorn Lu 2024-03-08 18:53:19 +08:00 committed by GitHub
parent 959ca5f9f8
commit 5a9528741f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 70 additions and 51 deletions

View file

@ -0,0 +1,5 @@
---
"astro": minor
---
Stabilizes `markdown.shikiConfig.experimentalThemes` as `markdown.shikiConfig.themes`. No behaviour changes are made to this option.

View file

@ -0,0 +1,6 @@
---
"@astrojs/markdown-remark": minor
"astro": minor
---
Migrates `shikiji` to `shiki` 1.0

View file

@ -18,7 +18,7 @@ Published on: {new Intl.DateTimeFormat('en', {dateStyle: 'long'}).format(publish
## Syntax highlighting
We also support syntax highlighting in MDX out-of-the-box! This example uses our default [Shiki theme](https://github.com/shikijs/shiki). See the [MDX integration docs](https://docs.astro.build/en/guides/integrations-guide/mdx/#syntax-highlighting) for configuration options.
We also support syntax highlighting in MDX out-of-the-box! This example uses the default [Shiki](https://shiki.style) theme. See the [MDX integration docs](https://docs.astro.build/en/guides/integrations-guide/mdx/#syntax-highlighting) for configuration options.
```astro
---

View file

@ -6,8 +6,8 @@ import type {
SpecialLanguage,
ThemeRegistration,
ThemeRegistrationRaw,
} from 'shikiji';
import { bundledLanguages } from 'shikiji/langs';
} from 'shiki';
import { bundledLanguages } from 'shiki/langs';
import { getCachedHighlighter } from '../dist/core/shiki.js';
interface Props {
@ -15,25 +15,25 @@ interface Props {
code: string;
/**
* The language of your code.
* Supports all languages listed here: https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
* Instructions for loading a custom language: https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
* Supports all languages listed here: https://shiki.style/languages
* Instructions for loading a custom language: https://shiki.style/guide/load-lang
*
* @default "plaintext"
*/
lang?: BuiltinLanguage | SpecialLanguage | LanguageRegistration;
/**
* The styling theme.
* Supports all themes listed here: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
* Instructions for loading a custom theme: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
* Supports all themes listed here: https://shiki.style/themes
* Instructions for loading a custom theme: https://shiki.style/guide/load-theme
*
* @default "github-dark"
*/
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
/**
* Multiple themes to style with -- alternative to "theme" option.
* Supports all themes found above; see https://github.com/antfu/shikiji#lightdark-dual-themes for more information.
* Supports all themes found above; see https://shiki.style/guide/dual-themes for more information.
*/
experimentalThemes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
/**
* Enable word wrapping.
* - true: enabled.
@ -55,12 +55,12 @@ const {
code,
lang = 'plaintext',
theme = 'github-dark',
experimentalThemes = {},
themes = {},
wrap = false,
inline = false,
} = Astro.props;
// shiki -> shikiji compat
// shiki 1.0 compat
if (typeof lang === 'object') {
// `id` renamed to `name` (always override)
if ((lang as any).id) {
@ -81,7 +81,7 @@ const highlighter = await getCachedHighlighter({
: lang,
],
theme,
experimentalThemes,
themes,
wrap,
});

View file

@ -125,6 +125,7 @@
"@babel/traverse": "^7.23.3",
"@babel/types": "^7.23.3",
"@medv/finder": "^3.1.0",
"@shikijs/core": "^1.1.2",
"@types/babel__core": "^7.20.4",
"acorn": "^8.11.2",
"aria-query": "^5.3.0",
@ -166,8 +167,7 @@
"rehype": "^13.0.1",
"resolve": "^1.22.4",
"semver": "^7.5.4",
"shikiji": "^0.9.19",
"shikiji-core": "^0.9.19",
"shiki": "^1.1.2",
"string-width": "^7.0.0",
"strip-ansi": "^7.1.0",
"tsconfck": "^3.0.0",

View file

@ -1294,7 +1294,7 @@ export interface AstroUserConfig {
* @default `shiki`
* @description
* Which syntax highlighter to use, if any.
* - `shiki` - use the [Shiki](https://github.com/shikijs/shiki) highlighter
* - `shiki` - use the [Shiki](https://shiki.style) highlighter
* - `prism` - use the [Prism](https://prismjs.com/) highlighter
* - `false` - do not apply syntax highlighting.
*

View file

@ -5,7 +5,7 @@ import type {
ShikiConfig,
} from '@astrojs/markdown-remark';
import { markdownConfigDefaults } from '@astrojs/markdown-remark';
import { type BuiltinTheme, bundledThemes } from 'shikiji';
import { type BuiltinTheme, bundledThemes } from 'shiki';
import type { AstroUserConfig, ViteUserConfig } from '../../@types/astro.js';
import type { OutgoingHttpHeaders } from 'node:http';
@ -14,10 +14,10 @@ import { pathToFileURL } from 'node:url';
import { z } from 'zod';
import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from '../path.js';
// This import is required to appease TypeScript!
// These imports are required to appease TypeScript!
// See https://github.com/withastro/astro/pull/8762
import '@shikijs/core';
import 'mdast-util-to-hast';
import 'shikiji-core';
type ShikiLangs = NonNullable<ShikiConfig['langs']>;
type ShikiTheme = NonNullable<ShikiConfig['theme']>;
@ -250,7 +250,7 @@ export const AstroConfigSchema = z.object({
.array()
.transform((langs) => {
for (const lang of langs) {
// shiki -> shikiji compat
// shiki 1.0 compat
if (typeof lang === 'object') {
// `id` renamed to `name` (always override)
if ((lang as any).id) {
@ -269,17 +269,28 @@ export const AstroConfigSchema = z.object({
.enum(Object.keys(bundledThemes) as [BuiltinTheme, ...BuiltinTheme[]])
.or(z.custom<ShikiTheme>())
.default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.theme!),
experimentalThemes: z
themes: z
.record(
z
.enum(Object.keys(bundledThemes) as [BuiltinTheme, ...BuiltinTheme[]])
.or(z.custom<ShikiTheme>())
)
.default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.experimentalThemes!),
.default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.themes!),
wrap: z.boolean().or(z.null()).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.wrap!),
transformers: z
.custom<ShikiTransformers[number]>()
.array()
.transform((transformers) => {
for (const transformer of transformers) {
// When updating shikiji to shiki, the `token` property was renamed to `span`.
// We apply the compat here for now until the next Astro major.
// TODO: Remove this in Astro 5.0
if ((transformer as any).token && !('span' in transformer)) {
transformer.span = (transformer as any).token;
}
}
return transformers;
})
.default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.transformers!),
})
.default({}),

View file

@ -1,6 +1,6 @@
import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { codeToHtml, createCssVariablesTheme } from 'shikiji';
import { codeToHtml, createCssVariablesTheme } from 'shiki';
import type { ErrorPayload } from 'vite';
import type { ModuleLoader } from '../../module-loader/index.js';
import { FailedToLoadModuleSSR, InvalidGlob, MdxIntegrationMissingError } from '../errors-data.js';

View file

@ -44,7 +44,7 @@
"remark-parse": "^11.0.0",
"remark-rehype": "^11.0.0",
"remark-smartypants": "^2.0.0",
"shikiji": "^0.9.19",
"shiki": "^1.1.2",
"unified": "^11.0.4",
"unist-util-visit": "^5.0.0",
"vfile": "^6.0.1"

View file

@ -34,7 +34,7 @@ export const markdownConfigDefaults: Required<AstroMarkdownOptions> = {
shikiConfig: {
langs: [],
theme: 'github-dark',
experimentalThemes: {},
themes: {},
wrap: false,
transformers: [],
},

View file

@ -1,5 +1,5 @@
import type { Properties } from 'hast';
import { bundledLanguages, createCssVariablesTheme, getHighlighter } from 'shikiji';
import { bundledLanguages, createCssVariablesTheme, getHighlighter } from 'shiki';
import { visit } from 'unist-util-visit';
import type { ShikiConfig } from './types.js';
@ -25,12 +25,10 @@ const cssVariablesTheme = () =>
export async function createShikiHighlighter({
langs = [],
theme = 'github-dark',
experimentalThemes = {},
themes = {},
wrap = false,
transformers = [],
}: ShikiConfig = {}): Promise<ShikiHighlighter> {
const themes = experimentalThemes;
theme = theme === 'css-variables' ? cssVariablesTheme() : theme;
const highlighter = await getHighlighter({
@ -106,11 +104,10 @@ export async function createShikiHighlighter({
}
},
root(node) {
if (Object.values(experimentalThemes).length) {
if (Object.values(themes).length) {
return;
}
// theme.id for shiki -> shikiji compat
const themeName = typeof theme === 'string' ? theme : theme.name;
if (themeName === 'css-variables') {
// Replace special color tokens to CSS variables

View file

@ -4,10 +4,10 @@ import type { Options as RemarkRehypeOptions } from 'remark-rehype';
import type {
BuiltinTheme,
LanguageRegistration,
ShikijiTransformer,
ShikiTransformer,
ThemeRegistration,
ThemeRegistrationRaw,
} from 'shikiji';
} from 'shiki';
import type * as unified from 'unified';
import type { VFile } from 'vfile';
@ -38,9 +38,9 @@ export type ThemePresets = BuiltinTheme | 'css-variables';
export interface ShikiConfig {
langs?: LanguageRegistration[];
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
experimentalThemes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
wrap?: boolean | null;
transformers?: ShikijiTransformer[];
transformers?: ShikiTransformer[];
}
export interface AstroMarkdownOptions {

View file

@ -13,7 +13,7 @@ describe('shiki syntax highlighting', () => {
it('supports light/dark themes', async () => {
const processor = await createMarkdownProcessor({
shikiConfig: {
experimentalThemes: {
themes: {
light: 'github-light',
dark: 'github-dark',
},

View file

@ -530,6 +530,9 @@ importers:
'@medv/finder':
specifier: ^3.1.0
version: 3.1.0
'@shikijs/core':
specifier: ^1.1.2
version: 1.1.2
'@types/babel__core':
specifier: ^7.20.4
version: 7.20.5
@ -653,12 +656,9 @@ importers:
semver:
specifier: ^7.5.4
version: 7.5.4
shikiji:
specifier: ^0.9.19
version: 0.9.19
shikiji-core:
specifier: ^0.9.19
version: 0.9.19
shiki:
specifier: ^1.1.2
version: 1.1.2
string-width:
specifier: ^7.0.0
version: 7.0.0
@ -5236,9 +5236,9 @@ importers:
remark-smartypants:
specifier: ^2.0.0
version: 2.0.0
shikiji:
specifier: ^0.9.19
version: 0.9.19
shiki:
specifier: ^1.1.2
version: 1.1.2
unified:
specifier: ^11.0.4
version: 11.0.4
@ -7590,6 +7590,10 @@ packages:
requiresBuild: true
optional: true
/@shikijs/core@1.1.2:
resolution: {integrity: sha512-ERVzNQz88ZkDqUpWeC57Kp+Kmx5RjqeDBR1M8AGWGom4yrkITiTfXCGmjchlDSw12MhDTuPYR4HVFW8uT61RaQ==}
dev: false
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: false
@ -15025,14 +15029,10 @@ packages:
vscode-textmate: 5.2.0
dev: true
/shikiji-core@0.9.19:
resolution: {integrity: sha512-AFJu/vcNT21t0e6YrfadZ+9q86gvPum6iywRyt1OtIPjPFe25RQnYJyxHQPMLKCCWA992TPxmEmbNcOZCAJclw==}
dev: false
/shikiji@0.9.19:
resolution: {integrity: sha512-Kw2NHWktdcdypCj1GkKpXH4o6Vxz8B8TykPlPuLHOGSV8VkhoCLcFOH4k19K4LXAQYRQmxg+0X/eM+m2sLhAkg==}
/shiki@1.1.2:
resolution: {integrity: sha512-qNzFwTv5uhEDNUIwp7wHjsrffVeLbmOgWnM5mZZhoiz7G2qAUvqVfUzuWfieD45/YAKipzCtdV9SndacKtABow==}
dependencies:
shikiji-core: 0.9.19
'@shikijs/core': 1.1.2
dev: false
/side-channel@1.0.4: