Skip to content

feat: Dynamic CSS Variables - #314

Merged
orta merged 7 commits into
shikijs:mainfrom
OskarGroth:css-variables
Aug 11, 2022
Merged

feat: Dynamic CSS Variables#314
orta merged 7 commits into
shikijs:mainfrom
OskarGroth:css-variables

Conversation

@OskarGroth

@OskarGroth OskarGroth commented Apr 24, 2022

Copy link
Copy Markdown
Contributor

This PR adds the option to override the output of the highlighter. It uses the existing COLOR_REPLACEMENTS functionality that was added to support limited functionality for dark mode via CSS variables: #33

That approach had several issues, as described in #313

This PR resolves those issues and achieves true support for CSS variables with small, non-breaking changes. By making this record customisable, we add support for the user to provide a map of any colors they wish to remap to whatever CSS variables they want.

Instead of triggering this feature based on special theme with a certain name (css-variables), we introduce a new theme type that, when used, allows for CSS variable overrides.

A custom CSS theme can then be on the same format as css-variables one, but have any name you'd like, and remap literally any color you'd like to a CSS variable (#000000...#FFFFFF, not just #000000...#0000012)

@netlify

netlify Bot commented Apr 24, 2022

Copy link
Copy Markdown

Deploy Preview for shiki-matsu ready!

Name Link
🔨 Latest commit b1edee1
🔍 Latest deploy log https://app.netlify.com/sites/shiki-matsu/deploys/62f4bf59cd5fd00009d01f29
😎 Deploy Preview https://deploy-preview-314--shiki-matsu.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@OskarGroth OskarGroth mentioned this pull request Apr 24, 2022
@cpojer

cpojer commented Aug 6, 2022

Copy link
Copy Markdown

Thanks for making this PR. I'm also looking to make use of this feature. Have you thought about using an options object instead of a setter function for this feature? I'm using shiki through remark and don't have access to the highlighter.

@OskarGroth

OskarGroth commented Aug 8, 2022

Copy link
Copy Markdown
Contributor Author

@cpojer Personally I'm using this through remark-rehype via the rehype-pretty-code option object:

async function makeHighlighter() {
	const theme = toShikiTheme(xcodeTheme as any)
	const highlighter = await getHighlighter({
		langs: ['html', 'css', 'swift', 'jsx', 'tsx', 'javascript', 'typescript', 'markdown', 'json', 'mdx'],
		theme: theme
	})

	highlighter.setColorReplacements({
		'#000000': 'var(--syntax-attributes)',
		'#000001': 'var(--syntax-characters)',
		'#000002': 'var(--syntax-comments)',
		'#000003': 'var(--syntax-heading)',
		'#000004': 'var(--syntax-keywords)', // semibold
		'#000005': 'var(--syntax-marks)', // bold
		'#000006': 'var(--syntax-numbers)',
		'#000007': 'var(--syntax-other-class-names)',
		'#000008': 'var(--syntax-other-constants)',
		'#000009': 'var(--syntax-other-declarations)',
		'#000010': 'var(--syntax-other-function-and-method-names)',
		'#000011': 'var(--syntax-other-instance-variables-and-globals)',
		'#000012': 'var(--syntax-other-preprocessor-macros)',
		'#000013': 'var(--syntax-other-type-names)',
		'#000014': 'var(--syntax-param-internal-name)',
		'#000015': 'var(--syntax-plain-text)',
		'#000016': 'var(--syntax-preprocessor-statements)',
		'#000017': 'var(--syntax-project-class-names)',
		'#000018': 'var(--syntax-project-constants)',
		'#000019': 'var(--syntax-project-function-and-method-names)',
		'#000020': 'var(--syntax-project-instance-variables-and-globals)',
		'#000021': 'var(--syntax-project-preprocessor-macros)',
		'#000022': 'var(--syntax-project-type-names)',
		'#000023': 'var(--syntax-strings)',
		'#000024': 'var(--syntax-type-declarations)',
		'#000025': 'var(--syntax-urls)',
		'#000026': 'var(--syntax-documentation-markup)',
		'#000027': 'var(--syntax-documentation-markup-keywords)', // bold
		'#FFFFF0': 'var(--theme-text)'
	})
	return highlighter
}
	const prettyOptions = {
                ...
		getHighlighter: (options: Pick<PrettyOptions, 'theme'>) => {
			return makeHighlighter()
		}
	}
		mdxOptions(options, frontmatter) {
			options.remarkPlugins = [
				...(options.remarkPlugins ?? []),
				remarkExtractFrontmatter,
				[remarkTocHeadings, { exportRef: toc }],
				remarkGfm,
				remarkCodeTitles,
				[remarkFootnotes, { inlineNotes: true }],
				remarkMath,
				remarkImgToJsx
			]
			options.rehypePlugins = [
				...(options.rehypePlugins ?? []),
				rehypeSlug,
				rehypeAutolinkHeadings,
				[rehypeCitation, { path: path.join(root, 'data') }],
				[rehypePrettyCode, prettyOptions],
				rehypePresetMinify
			]
			return options
		}

Using it live at my blog here.

@orta

orta commented Aug 8, 2022

Copy link
Copy Markdown
Contributor

I'm thinking of doing something in this space also with ( shikijs/twoslash#159 ) - so @OskarGroth I think the CI is failing on TypeScript errors.

If you get this PR green, 2 days from now (to give @octref a chance to give an opinion) I'll merge and make a release 👍🏻

@OskarGroth

Copy link
Copy Markdown
Contributor Author

@orta Resolved build errors.

@orta

orta commented Aug 11, 2022

Copy link
Copy Markdown
Contributor

@FredKSchott I don't know how you're using the css-variables feature - but the old version of your code relied on the name being 'css-variables' and there's a chance you might be relying on this in a custom theme. This code should break that, but I think the chance of you doing this is very slim. So, I'm OK with the potential break but wanted you to know ahead incase you get a surprise on an update (you change the theme type to css to fix it)

@orta
orta merged commit f8bd1fb into shikijs:main Aug 11, 2022
@cpojer

cpojer commented Aug 11, 2022

Copy link
Copy Markdown

Thanks everyone! I was able to reduce the file size of code heavy blog posts on cpojer.net by almost half!

@SanderCokart

Copy link
Copy Markdown

Sadly this is super incomplete its not enough variance. It is impossible to replicate existing themes like one-dark due to there not being enough options.

Best one dark you can make with css variables
image

Actual one dark
image

Notice how --shiki-token-string-expression is applied even for html tags as well as other strings.

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

Successfully merging this pull request may close these issues.

Support CSS Variables

4 participants