Update to new system (#68)

This commit is contained in:
Adam Matthiesen 2024-03-28 12:30:33 -07:00 committed by GitHub
parent 010ef457ac
commit 4993642d93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 151 additions and 33 deletions

View File

@ -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'`

View File

@ -47,10 +47,13 @@
"@octokit/types": "^12.6.0" "@octokit/types": "^12.6.0"
}, },
"dependencies": { "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", "@expressive-code/plugin-line-numbers": "^0.33.5",
"astro-integration-kit": "~0.7.1", "astro-integration-kit": "~0.7.1",
"chalk": "5.3.0", "chalk": "5.3.0",
"expressive-code": "^0.33.5",
"hast-util-to-html": "8.0.4", "hast-util-to-html": "8.0.4",
"p-retry": "6.2.0", "p-retry": "6.2.0",
"octokit": "^3.1.2", "octokit": "^3.1.2",

View File

@ -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 })
}
}

View File

@ -1,17 +1,31 @@
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'
import { ExpressiveCode, loadShikiTheme, type BundledShikiTheme } from 'expressive-code' import { ExpressiveCode, type BundledShikiTheme, type ExpressiveCodeTheme, loadShikiTheme } from './engine'
import config from "virtual:astro-gists/config"; import Config from 'virtual:astro-gists/config'
// Export defined components // Export defined components
export { default as Code } from './components/Code.astro' export { default as Code } from './components/Code.astro'
// Create a custom instance of ExpressiveCode
export const engine = new ExpressiveCode({ export async function getTheme(themeName: BundledShikiTheme): Promise<ExpressiveCodeTheme> {
themes: [ return await loadShikiTheme(themeName)
config.theme ? }
await loadShikiTheme(config.theme as BundledShikiTheme) :
await loadShikiTheme('catppuccin-macchiato'), await loadShikiTheme('catppuccin-latte') // Get the themes from the configuration
], const { themes: userThemes } = Config
plugins: [pluginLineNumbers()],
}) 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: userThemes?.length ? themes : undefined })

View File

@ -1,15 +1,17 @@
// Export the user config schema // Export the user config schema
import { z } from "astro/zod"; import { z } from "astro/zod";
import type { BundledShikiTheme } from "expressive-code"; import type { BundledShikiTheme } from "./ExpressiveCode/engine";
export const optionsSchema = z.object({ export const optionsSchema = z.object({
/** /**
* Optional: Allows the user to change the default theme for the code blocks. * 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. * Optional: Allows the user to enable verbose logging.
*/ */

View File

@ -1,4 +1,4 @@
declare module "virtual:astro-gists/config" { declare module "virtual:astro-gists/config" {
const Config: import("./src/index").astroGistsUserConfig; const Config: import("./src/UserConfigSchema").astroGistsUserConfig;
export default Config; export default Config;
} }

View File

@ -11,8 +11,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@matthiesenxyz/astro-gists": "*", "astro": "^4.5.9",
"astro": "^4.5.9" "@matthiesenxyz/astro-gists": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/mdx": "^2.2.1", "@astrojs/mdx": "^2.2.1",

View File

@ -17,9 +17,21 @@ importers:
package: package:
dependencies: 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': '@expressive-code/plugin-line-numbers':
specifier: ^0.33.5 specifier: ^0.33.5
version: 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: astro:
specifier: ^4.4.1 specifier: ^4.4.1
version: 4.4.11 version: 4.4.11
@ -29,9 +41,6 @@ importers:
chalk: chalk:
specifier: 5.3.0 specifier: 5.3.0
version: 5.3.0 version: 5.3.0
expressive-code:
specifier: ^0.33.5
version: 0.33.5
hast-util-to-html: hast-util-to-html:
specifier: 8.0.4 specifier: 8.0.4
version: 8.0.4 version: 8.0.4
@ -52,7 +61,7 @@ importers:
playground: playground:
dependencies: dependencies:
'@matthiesenxyz/astro-gists': '@matthiesenxyz/astro-gists':
specifier: '*' specifier: workspace:*
version: link:../package version: link:../package
astro: astro:
specifier: ^4.5.9 specifier: ^4.5.9
@ -3048,15 +3057,6 @@ packages:
requiresBuild: true requiresBuild: true
optional: 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: /extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}