feat(theme): support light shiki themes (#2319)

BREAKING CHANGE: Styling for code blocks might break, especially if you were earlier overriding it for light theme. Those workarounds are no longer required. VitePress will now show code blocks and groups in light mode too if a light shiki theme is specified.
pull/2323/head
Divyansh Singh 2 years ago committed by GitHub
parent 3b3bfea94c
commit d0f0012aea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -491,7 +491,7 @@
z-index: 2; z-index: 2;
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
color: var(--vp-c-text-dark-3); color: var(--vp-c-code-dimm);
transition: color 0.4s, opacity 0.4s; transition: color 0.4s, opacity 0.4s;
} }

@ -208,6 +208,7 @@
:root { :root {
--vp-code-line-height: 1.7; --vp-code-line-height: 1.7;
--vp-code-font-size: 0.875em; --vp-code-font-size: 0.875em;
--vp-c-code-dimm: var(--vp-c-text-dark-3);
--vp-code-block-color: var(--vp-c-text-dark-1); --vp-code-block-color: var(--vp-c-text-dark-1);
--vp-code-block-bg: #292b30; --vp-code-block-bg: #292b30;
@ -215,7 +216,7 @@
--vp-code-block-divider-color: #000000; --vp-code-block-divider-color: #000000;
--vp-code-line-highlight-color: rgba(0, 0, 0, 0.5); --vp-code-line-highlight-color: rgba(0, 0, 0, 0.5);
--vp-code-line-number-color: var(--vp-c-text-dark-3); --vp-code-line-number-color: var(--vp-c-code-dimm);
--vp-code-line-diff-add-color: var(--vp-c-green-dimm-2); --vp-code-line-diff-add-color: var(--vp-c-green-dimm-2);
--vp-code-line-diff-add-symbol-color: var(--vp-c-green); --vp-code-line-diff-add-symbol-color: var(--vp-c-green);
@ -244,6 +245,27 @@
--vp-code-block-bg: #161618; --vp-code-block-bg: #161618;
} }
:root:not(.dark) .vp-adaptive-theme {
--vp-c-code-dimm: var(--vp-c-text-2);
--vp-code-block-color: var(--vp-c-text-1);
--vp-code-block-bg: #f8f8f8;
--vp-code-block-divider-color: var(--vp-c-divider);
--vp-code-line-highlight-color: #ececec;
--vp-code-line-number-color: var(--vp-c-code-dimm);
--vp-code-copy-code-bg: #e2e2e2;
--vp-code-copy-code-hover-bg: #dcdcdc;
--vp-code-copy-code-active-text: var(--vp-c-text-2);
--vp-code-tab-divider: var(--vp-c-divider);
--vp-code-tab-text-color: var(--vp-c-text-2);
--vp-code-tab-bg: var(--vp-code-block-bg);
--vp-code-tab-hover-text-color: var(--vp-c-text-1);
--vp-code-tab-active-text-color: var(--vp-c-text-1);
}
/** /**
* Component: Button * Component: Button
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */

@ -60,13 +60,16 @@ export const createMarkdownRenderer = async (
base = '/', base = '/',
logger: Pick<Logger, 'warn'> = console logger: Pick<Logger, 'warn'> = console
): Promise<MarkdownRenderer> => { ): Promise<MarkdownRenderer> => {
const theme = options.theme ?? 'material-theme-palenight'
const hasSingleTheme = typeof theme === 'string' || 'name' in theme
const md = MarkdownIt({ const md = MarkdownIt({
html: true, html: true,
linkify: true, linkify: true,
highlight: highlight:
options.highlight || options.highlight ||
(await highlight( (await highlight(
options.theme, theme,
options.languages, options.languages,
options.defaultHighlightLang, options.defaultHighlightLang,
logger logger
@ -79,9 +82,9 @@ export const createMarkdownRenderer = async (
// custom plugins // custom plugins
md.use(componentPlugin) md.use(componentPlugin)
.use(highlightLinePlugin) .use(highlightLinePlugin)
.use(preWrapperPlugin) .use(preWrapperPlugin, { hasSingleTheme })
.use(snippetPlugin, srcDir) .use(snippetPlugin, srcDir)
.use(containerPlugin) .use(containerPlugin, { hasSingleTheme })
.use(imagePlugin) .use(imagePlugin)
.use( .use(
linkPlugin, linkPlugin,

@ -3,9 +3,13 @@ import type { RenderRule } from 'markdown-it/lib/renderer'
import type Token from 'markdown-it/lib/token' import type Token from 'markdown-it/lib/token'
import container from 'markdown-it-container' import container from 'markdown-it-container'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { extractTitle } from './preWrapper' import {
extractTitle,
getAdaptiveThemeMarker,
type Options
} from './preWrapper'
export const containerPlugin = (md: MarkdownIt) => { export const containerPlugin = (md: MarkdownIt, options: Options) => {
md.use(...createContainer('tip', 'TIP', md)) md.use(...createContainer('tip', 'TIP', md))
.use(...createContainer('info', 'INFO', md)) .use(...createContainer('info', 'INFO', md))
.use(...createContainer('warning', 'WARNING', md)) .use(...createContainer('warning', 'WARNING', md))
@ -20,7 +24,7 @@ export const containerPlugin = (md: MarkdownIt) => {
render: (tokens: Token[], idx: number) => render: (tokens: Token[], idx: number) =>
tokens[idx].nesting === 1 ? `<div class="vp-raw">\n` : `</div>\n` tokens[idx].nesting === 1 ? `<div class="vp-raw">\n` : `</div>\n`
}) })
.use(...createCodeGroup()) .use(...createCodeGroup(options))
} }
type ContainerArgs = [typeof container, string, { render: RenderRule }] type ContainerArgs = [typeof container, string, { render: RenderRule }]
@ -51,7 +55,7 @@ function createContainer(
] ]
} }
function createCodeGroup(): ContainerArgs { function createCodeGroup(options: Options): ContainerArgs {
return [ return [
container, container,
'code-group', 'code-group',
@ -82,7 +86,9 @@ function createCodeGroup(): ContainerArgs {
} }
} }
return `<div class="vp-code-group"><div class="tabs">${tabs}</div><div class="blocks">\n` return `<div class="vp-code-group${getAdaptiveThemeMarker(
options
)}"><div class="tabs">${tabs}</div><div class="blocks">\n`
} }
return `</div></div>\n` return `</div></div>\n`
} }

@ -62,7 +62,7 @@ const errorLevelProcessor = defineProcessor({
}) })
export async function highlight( export async function highlight(
theme: ThemeOptions = 'material-theme-palenight', theme: ThemeOptions,
languages: ILanguageRegistration[] = [], languages: ILanguageRegistration[] = [],
defaultLang: string = '', defaultLang: string = '',
logger: Pick<Logger, 'warn'> = console logger: Pick<Logger, 'warn'> = console

@ -1,6 +1,10 @@
import type MarkdownIt from 'markdown-it' import type MarkdownIt from 'markdown-it'
export function preWrapperPlugin(md: MarkdownIt) { export interface Options {
hasSingleTheme: boolean
}
export function preWrapperPlugin(md: MarkdownIt, options: Options) {
const fence = md.renderer.rules.fence! const fence = md.renderer.rules.fence!
md.renderer.rules.fence = (...args) => { md.renderer.rules.fence = (...args) => {
const [tokens, idx] = args const [tokens, idx] = args
@ -10,17 +14,21 @@ export function preWrapperPlugin(md: MarkdownIt) {
const lang = extractLang(token.info) const lang = extractLang(token.info)
const rawCode = fence(...args) const rawCode = fence(...args)
return `<div class="language-${lang}${ return `<div class="language-${lang}${getAdaptiveThemeMarker(options)}${
/ active( |$)/.test(token.info) ? ' active' : '' / active( |$)/.test(token.info) ? ' active' : ''
}"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>${rawCode}</div>` }"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>${rawCode}</div>`
} }
} }
export function getAdaptiveThemeMarker(options: Options) {
return options.hasSingleTheme ? '' : ' vp-adaptive-theme'
}
export function extractTitle(info: string) { export function extractTitle(info: string) {
return info.match(/\[(.*)\]/)?.[1] || extractLang(info) || 'txt' return info.match(/\[(.*)\]/)?.[1] || extractLang(info) || 'txt'
} }
const extractLang = (info: string) => { function extractLang(info: string) {
return info return info
.trim() .trim()
.replace(/:(no-)?line-numbers({| |$).*/, '') .replace(/:(no-)?line-numbers({| |$).*/, '')

Loading…
Cancel
Save