Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support remark/rehype plugins and other markdown options #185

Open
Yuhanawa opened this issue Dec 12, 2024 · 3 comments
Open

Support remark/rehype plugins and other markdown options #185

Yuhanawa opened this issue Dec 12, 2024 · 3 comments

Comments

@Yuhanawa
Copy link
Contributor

There is the type of markdown option in astro config

markdown:{
  syntaxHighlight: false | "shiki" | "prism";
  shikiConfig: {
      langs: ShikiLang[];
      theme: import("shiki").BundledTheme | ShikiTheme;
      themes: Record<string, import("shiki").BundledTheme | ShikiTheme>;
      langAlias: Record<string, string>;
      wrap: boolean | null;
      transformers: ShikiTransformer[];
      defaultColor?: string | false | undefined;
  };
  remarkPlugins: (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
  rehypePlugins: (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
  remarkRehype: RemarkRehype;
  gfm: boolean;
  smartypants: boolean;
}

The author often use remarkPlugins, rehypePlugins and transformers in shikiConfig,
So at least support for these three options should be provided

  • Allow user to disable all or only disable a plugin
  • Allow authors to choose to use user config or override
@BryceRussell
Copy link
Member

BryceRussell commented Dec 12, 2024

Currently, there is a way to do this using an integration:

// package/index.ts
import defineTheme from 'astro-theme-provider';
import { z } from 'astro/zod'

export default defineTheme({
  schema: z.object({
    title: z.string(),
  }),
  integrations: [
    {
      name: 'theme-markdown-plugins',
      'astro:config:setup': ({ updateConfig }) => updateConfig({
        markdown : { ... }
      })
    }
  ]
})

And user's can opt out of this by disabling the integration:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import Blog from 'blog-theme';

export default defineConfig({
  integrations: [
    Blog({
      config: {
        title: "My Blog"
      },
      integrations: {
       'theme-markdown-plugins': false
      }
    }),
  ],
});

This pattern is a bit more verbose, but it:

  • Makes the backend code for ATP much simpler
  • Gives authors more flexibility than a rigid option
  • Keeps the user option simpler so it is not bloated it with too many disables/overrides

What do you think of this pattern? Is this too verbose for authors? What advantages does your suggestion have over this pattern?

side note: We should document the integration pattern outlined above so that more people know about it

@Yuhanawa
Copy link
Contributor Author

that's nice, I never thought it could be done this way,
but if author wants to provide multiple plugins that can be turned on and off individually, the code will be very verbose

import defineTheme from 'astro-theme-provider';
import { z } from 'astro/zod'

export default defineTheme({
  schema: z.object({
    title: z.string(),
  }),
  integrations: [
    {
      name: 'theme-markdown-plugin1',
      'astro:config:setup': ({ updateConfig }) => updateConfig({
        markdown : {
             remarkPlugins:[ remarkPlugins1 ]
          }
      }),
    },
    {
      name: 'theme-markdown-plugin2',
      'astro:config:setup': ({ updateConfig }) => updateConfig({
        markdown : {
             remarkPlugins:[ [remarkPlugins2, { /* config */ } ] ]
            // maybe the author will adjust the config of the plugin according to the user's config
          }
      }),
    },
    // ...
  ]
})

maybe it would be easier if a wrapper function could be provided:

export default defineTheme({
  integrations: [
    createRemarkPluginsIntegration('theme-markdown-plugin1',[remarkPlugins1]),
    createRemarkPluginsIntegration('theme-markdown-plugin2',(config) => [[remarkPlugins2, { /* config */ }]),
    // ...
  ]
})

@BryceRussell
Copy link
Member

Ahh ya good point! A wrapper would make this much easier without having to repeat too much boilerplate. Although this is more verbose, I think I like this API for now because it is simpler for the end user to understand at the cost of being more verbose for authors. Instead of changing the shape of both the author and user APIs, I think we should document this integration pattern as a suggestion for theme authors who may not know about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants