From d5ed66c6d21ec3b5e17469771057132c53220bea Mon Sep 17 00:00:00 2001 From: Azat S Date: Fri, 15 Jul 2022 17:40:27 +0300 Subject: [PATCH] feat: allow using custom syntax highlighting themes (#992) Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> --- docs/config/app-configs.md | 17 ++++++++++------- src/node/markdown/markdown.ts | 6 ++++-- src/node/markdown/plugins/highlight.ts | 19 ++++++++++++------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/config/app-configs.md b/docs/config/app-configs.md index 54657e3f..b9e3be6d 100644 --- a/docs/config/app-configs.md +++ b/docs/config/app-configs.md @@ -109,13 +109,18 @@ export default { } ``` -Below shows the the full option you may define within this object. +Below are all the options that you can have in this object: ```ts interface MarkdownOptions extends MarkdownIt.Options { - // Syntax highlight theme for Shiki. + // Custom theme for syntax highlighting. + // You can use an existing theme. // See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes - theme?: Shiki.Theme | { light: Shiki.Theme, dark: Shiki.Theme } + // Or add your own theme. + // See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme + theme?: + | Shiki.IThemeRegistration + | { light: Shiki.IThemeRegistration; dark: Shiki.IThemeRegistration } // Enable line numbers in code block. lineNumbers?: boolean @@ -136,11 +141,10 @@ interface MarkdownOptions extends MarkdownIt.Options { } // markdown-it-toc-done-right plugin options - // https://github.com/nagaozen/markdown-it-toc-done-right + // See: https://github.com/nagaozen/markdown-it-toc-done-right toc?: any - // Configure the Markdown-it instance to fully customize - // how it works. + // Configure the Markdown-it instance. config?: (md: MarkdownIt) => void } ``` @@ -172,4 +176,3 @@ export default { titleTemplate: 'Vite & Vue powered static site generator' } ``` - diff --git a/src/node/markdown/markdown.ts b/src/node/markdown/markdown.ts index 7582f47f..4b43918d 100644 --- a/src/node/markdown/markdown.ts +++ b/src/node/markdown/markdown.ts @@ -1,5 +1,5 @@ import MarkdownIt from 'markdown-it' -import { Theme } from 'shiki' +import { IThemeRegistration } from 'shiki' import { parseHeader } from '../utils/parseHeader' import { highlight } from './plugins/highlight' import { slugify } from './plugins/slugify' @@ -19,7 +19,9 @@ import attrs from 'markdown-it-attrs' import emoji from 'markdown-it-emoji' import toc from 'markdown-it-toc-done-right' -export type ThemeOptions = Theme | { light: Theme; dark: Theme } +export type ThemeOptions = + | IThemeRegistration + | { light: IThemeRegistration; dark: IThemeRegistration } export interface MarkdownOptions extends MarkdownIt.Options { lineNumbers?: boolean diff --git a/src/node/markdown/plugins/highlight.ts b/src/node/markdown/plugins/highlight.ts index eb27b559..5b1d0e14 100644 --- a/src/node/markdown/plugins/highlight.ts +++ b/src/node/markdown/plugins/highlight.ts @@ -1,26 +1,31 @@ -import { getHighlighter } from 'shiki' +import { IThemeRegistration, getHighlighter } from 'shiki' import type { ThemeOptions } from '../markdown' export async function highlight(theme: ThemeOptions = 'material-palenight') { - const themes = typeof theme === 'string' ? [theme] : [theme.dark, theme.light] - const highlighter = await getHighlighter({ themes }) + const hasSingleTheme = typeof theme === 'string' || 'name' in theme + const getThemeName = (themeValue: IThemeRegistration) => + typeof themeValue === 'string' ? themeValue : themeValue.name + + const highlighter = await getHighlighter({ + themes: hasSingleTheme ? [theme] : [theme.dark, theme.light] + }) const preRE = /^/ return (str: string, lang: string) => { lang = lang || 'text' - if (typeof theme === 'string') { + if (hasSingleTheme) { return highlighter - .codeToHtml(str, { lang, theme }) + .codeToHtml(str, { lang, theme: getThemeName(theme) }) .replace(preRE, '
')
     }
 
     const dark = highlighter
-      .codeToHtml(str, { lang, theme: theme.dark })
+      .codeToHtml(str, { lang, theme: getThemeName(theme.dark) })
       .replace(preRE, '
')
 
     const light = highlighter
-      .codeToHtml(str, { lang, theme: theme.light })
+      .codeToHtml(str, { lang, theme: getThemeName(theme.light) })
       .replace(preRE, '
')
 
     return dark + light