-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Expand file tree
/
Copy pathhighlighter.mjs
More file actions
66 lines (59 loc) · 2.29 KB
/
highlighter.mjs
File metadata and controls
66 lines (59 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { createHighlighterCoreSync } from '@shikijs/core';
import { createJavaScriptRegexEngine } from '@shikijs/engine-javascript';
import shikiNordTheme from 'shiki/themes/nord.mjs';
const DEFAULT_THEME = {
// We updating this color because the background color and comment text color
// in the Codebox component do not comply with accessibility standards
// @see https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html
colorReplacements: { '#616e88': '#707e99' },
...shikiNordTheme,
};
/**
* Creates a syntax highlighter with utility functions
* @param {import('@shikijs/core').HighlighterCoreOptions} options - Configuration options for the highlighter
*/
export const createHighlighter = options => {
const shiki = createHighlighterCoreSync({
themes: [DEFAULT_THEME],
engine: createJavaScriptRegexEngine(),
...options,
});
const theme = options.themes?.[0] ?? DEFAULT_THEME;
const langs = options.langs ?? [];
const getLanguageDisplayName = language => {
const languageByIdOrAlias = langs.find(
({ name, aliases }) =>
name.toLowerCase() === language.toLowerCase() ||
(aliases !== undefined && aliases.includes(language.toLowerCase()))
);
return languageByIdOrAlias?.displayName ?? language;
};
/**
* Highlights code and returns the inner HTML inside the <code> tag
*
* @param {string} code - The code to highlight
* @param {string} language - The programming language to use for highlighting
* @returns {string} The inner HTML of the highlighted code
*/
const highlightToHtml = (code, language) =>
shiki
.codeToHtml(code, { lang: language, theme })
// Shiki will always return the Highlighted code encapsulated in a <pre> and <code> tag
// since our own CodeBox component handles the <code> tag, we just want to extract
// the inner highlighted code to the CodeBox
.match(/<code>(.+?)<\/code>/s)[1];
/**
* Highlights code and returns a HAST tree
*
* @param {string} code - The code to highlight
* @param {string} language - The programming language to use for highlighting
*/
const highlightToHast = (code, language) =>
shiki.codeToHast(code, { lang: language, theme });
return {
shiki,
getLanguageDisplayName,
highlightToHtml,
highlightToHast,
};
};