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

feat: Dynamic CSS Variables #314

Merged
merged 7 commits into from
Aug 11, 2022
Merged

feat: Dynamic CSS Variables #314

merged 7 commits into from
Aug 11, 2022

Conversation

OskarGroth
Copy link
Contributor

@OskarGroth OskarGroth commented Apr 24, 2022

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
Copy link

netlify bot commented Apr 24, 2022

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
Copy link

cpojer commented Aug 6, 2022

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
Copy link
Contributor Author

OskarGroth commented Aug 8, 2022

@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
Copy link
Contributor

orta commented Aug 8, 2022

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
Contributor Author

@orta Resolved build errors.

@orta
Copy link
Contributor

orta commented Aug 11, 2022

@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
Copy link

cpojer commented Aug 11, 2022

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

@SanderCokart
Copy link

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