From f1fecff84ebbf57924938e673220a0affc937074 Mon Sep 17 00:00:00 2001
From: Isaac Mann <isaacplmann@gmail.com>
Date: Fri, 11 Apr 2025 15:09:49 -0400
Subject: [PATCH] feat(astro): custom expressive code plugins

---
 packages/astro/src/index.ts        | 15 ++++++++++++++-
 packages/astro/src/integrations.ts | 12 +++++++++---
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts
index 706d256f8..2ea81475f 100644
--- a/packages/astro/src/index.ts
+++ b/packages/astro/src/index.ts
@@ -1,5 +1,6 @@
 import { fileURLToPath } from 'node:url';
 import type { AstroConfig, AstroIntegration } from 'astro';
+import type { ExpressiveCodePlugin } from 'astro-expressive-code';
 import { extraIntegrations } from './integrations.js';
 import { updateMarkdownConfig } from './remark/index.js';
 import { tutorialkitCore } from './vite-plugins/core.js';
@@ -59,6 +60,13 @@ export interface Options {
      */
     scope: string;
   };
+
+  /**
+   * Expressive code plugins.
+   *
+   * @default []
+   */
+  expressiveCodePlugins?: ExpressiveCodePlugin[];
 }
 
 export default function createPlugin({
@@ -66,6 +74,7 @@ export default function createPlugin({
   components,
   isolation,
   enterprise,
+  expressiveCodePlugins = [],
 }: Options = {}): AstroIntegration {
   const webcontainerFiles = new WebContainerFiles();
 
@@ -137,7 +146,11 @@ export default function createPlugin({
 
         // inject the additional integrations right after ours
         const selfIndex = config.integrations.findIndex((integration) => integration.name === '@tutorialkit/astro');
-        config.integrations.splice(selfIndex + 1, 0, ...extraIntegrations({ root: fileURLToPath(config.root) }));
+        config.integrations.splice(
+          selfIndex + 1,
+          0,
+          ...extraIntegrations({ root: fileURLToPath(config.root), expressiveCodePlugins }),
+        );
       },
       'astro:config:done'({ config }) {
         _config = config;
diff --git a/packages/astro/src/integrations.ts b/packages/astro/src/integrations.ts
index d99424a24..74348a2b7 100644
--- a/packages/astro/src/integrations.ts
+++ b/packages/astro/src/integrations.ts
@@ -4,14 +4,20 @@ import react from '@astrojs/react';
 import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections';
 import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers';
 import { getInlineContentForPackage } from '@tutorialkit/theme';
-import expressiveCode from 'astro-expressive-code';
+import expressiveCode, { type ExpressiveCodePlugin } from 'astro-expressive-code';
 import UnoCSS from 'unocss/astro';
 
-export function extraIntegrations({ root }: { root: string }) {
+export function extraIntegrations({
+  root,
+  expressiveCodePlugins = [],
+}: {
+  root: string;
+  expressiveCodePlugins?: ExpressiveCodePlugin[];
+}) {
   return [
     react(),
     expressiveCode({
-      plugins: [pluginCollapsibleSections(), pluginLineNumbers()],
+      plugins: [pluginCollapsibleSections(), pluginLineNumbers(), ...expressiveCodePlugins],
       themes: ['dark-plus', 'light-plus'],
       customizeTheme: (theme) => {
         const isDark = theme.type === 'dark';