Refactor Expressive Code plugins and themes
This commit is contained in:
parent
0d438752ee
commit
835987239b
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
"@matthiesenxyz/astro-gists": minor
|
||||
---
|
||||
|
||||
Full Shiki theme support with options to have light/dark mode! Now creating our own expressive code engine from the core module instead of the expressive-code package
|
||||
|
||||
## Breaking Changes:
|
||||
|
||||
- User Config `theme` changed to `themes` will accept an array `['github-light','github-dark']` or a string `'github-dark'`
|
|
@ -47,10 +47,13 @@
|
|||
"@octokit/types": "^12.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expressive-code/core": "^0.33.5",
|
||||
"@expressive-code/plugin-frames": "0.33.5",
|
||||
"@expressive-code/plugin-shiki": "0.33.5",
|
||||
"@expressive-code/plugin-text-markers": "0.33.5",
|
||||
"@expressive-code/plugin-line-numbers": "^0.33.5",
|
||||
"astro-integration-kit": "~0.7.1",
|
||||
"chalk": "5.3.0",
|
||||
"expressive-code": "^0.33.5",
|
||||
"hast-util-to-html": "8.0.4",
|
||||
"p-retry": "6.2.0",
|
||||
"octokit": "^3.1.2",
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import { ExpressiveCodeEngine, type ExpressiveCodeTheme, type ExpressiveCodeEngineConfig, type ExpressiveCodePlugin } from '@expressive-code/core'
|
||||
import { type PluginFramesOptions, pluginFrames } from '@expressive-code/plugin-frames'
|
||||
import type { PluginShikiOptions } from '@expressive-code/plugin-shiki'
|
||||
import { loadShikiTheme, pluginShiki, type BundledShikiTheme } from '@expressive-code/plugin-shiki'
|
||||
import { pluginTextMarkers } from '@expressive-code/plugin-text-markers'
|
||||
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'
|
||||
|
||||
export * from '@expressive-code/core'
|
||||
export * from '@expressive-code/plugin-frames'
|
||||
export * from '@expressive-code/plugin-shiki'
|
||||
export * from '@expressive-code/plugin-text-markers'
|
||||
|
||||
export interface ExpressiveCodeConfig extends ExpressiveCodeEngineConfig {
|
||||
/**
|
||||
* The Shiki plugin adds syntax highlighting to code blocks.
|
||||
*
|
||||
* This plugin is enabled by default. Set this to `false` to disable it.
|
||||
* You can also configure the plugin by setting this to an options object.
|
||||
*/
|
||||
shiki?: PluginShikiOptions | boolean | undefined
|
||||
/**
|
||||
* The Text Markers plugin allows to highlight lines and inline ranges
|
||||
* in code blocks in various styles (e.g. marked, inserted, deleted).
|
||||
*
|
||||
* This plugin is enabled by default. Set this to `false` to disable it.
|
||||
*/
|
||||
textMarkers?: boolean | undefined
|
||||
/**
|
||||
* The Frames plugin adds an editor or terminal frame around code blocks,
|
||||
* including an optional title displayed as a tab or window caption.
|
||||
*
|
||||
* This plugin is enabled by default. Set this to `false` to disable it.
|
||||
* You can also configure the plugin by setting this to an options object.
|
||||
*/
|
||||
frames?: PluginFramesOptions | boolean | undefined
|
||||
themes?: ExpressiveCodeTheme[] | undefined;
|
||||
}
|
||||
|
||||
|
||||
export async function getTheme(themeName: BundledShikiTheme): Promise<ExpressiveCodeTheme> {
|
||||
return await loadShikiTheme(themeName)
|
||||
}
|
||||
|
||||
const darkTheme = await getTheme('catppuccin-macchiato')
|
||||
const lightTheme = await getTheme('catppuccin-latte')
|
||||
|
||||
export class ExpressiveCode extends ExpressiveCodeEngine {
|
||||
constructor({ shiki, textMarkers, frames, themes, ...baseConfig }: ExpressiveCodeConfig = {}) {
|
||||
// Collect all default plugins with their configuration,
|
||||
// but skip those that were disabled or already added to plugins
|
||||
const pluginsToPrepend: ExpressiveCodePlugin[] = []
|
||||
const baseConfigPlugins = baseConfig.plugins?.flat() || []
|
||||
const notPresentInPlugins = (name: string) => baseConfigPlugins.every((plugin) => plugin.name !== name)
|
||||
if (shiki !== false && notPresentInPlugins('Shiki')) {
|
||||
pluginsToPrepend.push(pluginShiki(shiki !== true ? shiki : undefined))
|
||||
}
|
||||
if (textMarkers !== false && notPresentInPlugins('TextMarkers')) {
|
||||
if (typeof textMarkers === 'object' && (textMarkers as { styleOverrides: unknown }).styleOverrides) {
|
||||
throw new Error(
|
||||
`The Expressive Code config option "textMarkers" can no longer be an object,
|
||||
but only undefined or a boolean. Please move any style settings into the
|
||||
top-level "styleOverrides" object below the new "textMarkers" key.`.replace(/\s+/g, ' ')
|
||||
)
|
||||
}
|
||||
pluginsToPrepend.push(pluginTextMarkers())
|
||||
}
|
||||
if (frames !== false && notPresentInPlugins('Frames')) {
|
||||
if (typeof frames === 'object' && (frames as { styleOverrides: unknown }).styleOverrides) {
|
||||
throw new Error(
|
||||
`The config option "frames" no longer has its own "styleOverrides" object.
|
||||
Please move any style settings into the top-level "styleOverrides" object
|
||||
below the new "frames" key.`.replace(/\s+/g, ' ')
|
||||
)
|
||||
}
|
||||
pluginsToPrepend.push(pluginFrames(frames !== true ? frames : undefined))
|
||||
}
|
||||
|
||||
pluginsToPrepend.push(pluginLineNumbers())
|
||||
|
||||
// Create a new plugins array with the default plugins prepended
|
||||
const pluginsWithDefaults = [...pluginsToPrepend, ...(baseConfig.plugins || [])]
|
||||
|
||||
if (!themes) {
|
||||
themes = [darkTheme, lightTheme]
|
||||
}
|
||||
|
||||
// Call the base constructor with the new plugins array
|
||||
super({ ...baseConfig, themes, plugins: pluginsWithDefaults })
|
||||
}
|
||||
}
|
|
@ -1,17 +1,31 @@
|
|||
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'
|
||||
import { ExpressiveCode, loadShikiTheme, type BundledShikiTheme } from 'expressive-code'
|
||||
import config from "virtual:astro-gists/config";
|
||||
|
||||
import { ExpressiveCode, type BundledShikiTheme, type ExpressiveCodeTheme, loadShikiTheme } from './engine'
|
||||
import Config from 'virtual:astro-gists/config'
|
||||
|
||||
// Export defined components
|
||||
export { default as Code } from './components/Code.astro'
|
||||
|
||||
// Create a custom instance of ExpressiveCode
|
||||
export const engine = new ExpressiveCode({
|
||||
themes: [
|
||||
config.theme ?
|
||||
await loadShikiTheme(config.theme as BundledShikiTheme) :
|
||||
await loadShikiTheme('catppuccin-macchiato'), await loadShikiTheme('catppuccin-latte')
|
||||
],
|
||||
plugins: [pluginLineNumbers()],
|
||||
})
|
||||
|
||||
export async function getTheme(themeName: BundledShikiTheme): Promise<ExpressiveCodeTheme> {
|
||||
return await loadShikiTheme(themeName)
|
||||
}
|
||||
|
||||
// Get the themes from the configuration
|
||||
const { themes: userThemes } = Config
|
||||
|
||||
const themes: ExpressiveCodeTheme[] = []
|
||||
|
||||
// Load the themes from the configuration
|
||||
if (userThemes) {
|
||||
if (Array.isArray(userThemes)) {
|
||||
for (const themeName of userThemes) {
|
||||
themes.push(await getTheme(themeName))
|
||||
}
|
||||
} else {
|
||||
themes.push(await getTheme(userThemes))
|
||||
}
|
||||
}
|
||||
|
||||
// Create a custom instance of ExpressiveCode
|
||||
export const engine = new ExpressiveCode({ themes })
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
// Export the user config schema
|
||||
import { z } from "astro/zod";
|
||||
import type { BundledShikiTheme } from "expressive-code";
|
||||
import type { BundledShikiTheme } from "./ExpressiveCode/engine";
|
||||
|
||||
export const optionsSchema = z.object({
|
||||
/**
|
||||
* Optional: Allows the user to change the default theme for the code blocks.
|
||||
* @example ['github-dark']
|
||||
* @example ['github-light','github-dark']
|
||||
* @example 'github-light'
|
||||
*
|
||||
* @see All available themes are listed in the [Shiki documentation](https://shiki.matsu.io/docs/themes)
|
||||
*
|
||||
* All available themes are listed in the [Shiki documentation](https://shiki.matsu.io/docs/themes).
|
||||
*/
|
||||
theme: z.custom<BundledShikiTheme>().optional(),
|
||||
themes: z.custom<BundledShikiTheme[]|BundledShikiTheme>().optional(),
|
||||
/**
|
||||
* Optional: Allows the user to enable verbose logging.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
declare module "virtual:astro-gists/config" {
|
||||
const Config: import("./src/index").astroGistsUserConfig;
|
||||
const Config: import("./src/UserConfigSchema").astroGistsUserConfig;
|
||||
export default Config;
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matthiesenxyz/astro-gists": "*",
|
||||
"@matthiesenxyz/astro-gists": "workspace:*",
|
||||
"astro": "^4.5.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -17,9 +17,21 @@ importers:
|
|||
|
||||
package:
|
||||
dependencies:
|
||||
'@expressive-code/core':
|
||||
specifier: ^0.33.5
|
||||
version: 0.33.5
|
||||
'@expressive-code/plugin-frames':
|
||||
specifier: 0.33.5
|
||||
version: 0.33.5
|
||||
'@expressive-code/plugin-line-numbers':
|
||||
specifier: ^0.33.5
|
||||
version: 0.33.5
|
||||
'@expressive-code/plugin-shiki':
|
||||
specifier: 0.33.5
|
||||
version: 0.33.5
|
||||
'@expressive-code/plugin-text-markers':
|
||||
specifier: 0.33.5
|
||||
version: 0.33.5
|
||||
astro:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.11
|
||||
|
@ -29,9 +41,6 @@ importers:
|
|||
chalk:
|
||||
specifier: 5.3.0
|
||||
version: 5.3.0
|
||||
expressive-code:
|
||||
specifier: ^0.33.5
|
||||
version: 0.33.5
|
||||
hast-util-to-html:
|
||||
specifier: 8.0.4
|
||||
version: 8.0.4
|
||||
|
@ -52,7 +61,7 @@ importers:
|
|||
playground:
|
||||
dependencies:
|
||||
'@matthiesenxyz/astro-gists':
|
||||
specifier: '*'
|
||||
specifier: workspace:*
|
||||
version: link:../package
|
||||
astro:
|
||||
specifier: ^4.5.6
|
||||
|
@ -2671,15 +2680,6 @@ packages:
|
|||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/expressive-code@0.33.5:
|
||||
resolution: {integrity: sha512-UPg2jSvZEfXPiCa4MKtMoMQ5Hwiv7In5/LSCa/ukhjzZqPO48iVsCcEBgXWEUmEAQ02P0z00/xFfBmVnUKH+Zw==}
|
||||
dependencies:
|
||||
'@expressive-code/core': 0.33.5
|
||||
'@expressive-code/plugin-frames': 0.33.5
|
||||
'@expressive-code/plugin-shiki': 0.33.5
|
||||
'@expressive-code/plugin-text-markers': 0.33.5
|
||||
dev: false
|
||||
|
||||
/extend-shallow@2.0.1:
|
||||
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
Loading…
Reference in New Issue