Skip to content

Commit

Permalink
Highlight text - fix #5
Browse files Browse the repository at this point in the history
  • Loading branch information
pomber committed Apr 2, 2023
1 parent 7d65b36 commit ee37d6d
Show file tree
Hide file tree
Showing 13 changed files with 507 additions and 346 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-hounds-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@code-hike/lighter": patch
---

Add text grammar
122 changes: 89 additions & 33 deletions lib/dist/browser.esm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,37 @@ const defaults = {
"tab.hoverForeground": "tab.inactiveForeground",
};

async function loadTheme(theme) {
let rawTheme = typeof theme === "string" ? await loadThemeByName(theme) : theme;
return toFinalTheme(rawTheme);
}
const promiseCache = new Map();
const themeCache = new Map();
function loadThemeByName(name) {
if (!THEME_NAMES.includes(name)) {
return Promise.resolve(undefined);
async function preloadTheme(theme) {
if (typeof theme === "string") {
const name = theme;
if (!THEME_NAMES.includes(name)) {
throw new UnknownThemeError$1(name);
}
if (!promiseCache.has(name)) {
const promise = reallyLoadThemeByName(name).then((theme) => {
themeCache.set(name, theme);
return theme;
});
promiseCache.set(name, promise);
}
return promiseCache.get(name);
}
if (!themeCache.has(name)) {
themeCache.set(name, reallyLoadThemeByName(name));
return theme;
}
function getTheme(theme) {
let rawTheme = null;
if (typeof theme === "string") {
rawTheme = themeCache.get(theme);
if (!rawTheme) {
throw new Error("Syntax highlighting error: theme not loaded");
}
}
else {
rawTheme = theme;
}
return themeCache.get(name);
return toFinalTheme(rawTheme);
}
async function reallyLoadThemeByName(name) {
try {
Expand Down Expand Up @@ -309,7 +327,13 @@ const THEME_NAMES = [
"slack-ochin",
"solarized-dark",
"solarized-light",
];
];
class UnknownThemeError$1 extends Error {
constructor(theme) {
super(`Unknown theme: ${theme}`);
this.theme = theme;
}
}

// generated by lib/utils/3.update-languages-data.mjs
const LANG_NAMES = [
Expand Down Expand Up @@ -2465,13 +2489,7 @@ function getStyle(metadata, colors) {
}

let registry = null;
function loadGrammars(alias) {
// get the language object from the alias
const langData = aliasToLangData(alias);
// if the language object is not found, throw
if (!langData) {
throw new UnknownLanguageError(alias);
}
function preloadGrammars(languages) {
// initialize the registry the first time
if (!registry) {
const onigLibPromise = main.exports.loadWASM(onig).then(() => ({
Expand All @@ -2483,8 +2501,40 @@ function loadGrammars(alias) {
loadGrammar: (scopeName) => loadGrammarByScope(scopeName),
});
}
const grammarsPromise = registry.loadGrammar(langData.scopeName);
return { langId: langData.id, grammarsPromise };
const promises = languages
.filter((alias) => alias != "text")
.map((alias) => {
const langData = aliasToLangData(alias);
if (!langData) {
throw new UnknownLanguageError(alias);
}
return registry.loadGrammar(langData.scopeName);
});
return Promise.all(promises);
}
function getGrammar(alias) {
if (alias == "text") {
return {
langId: "text",
grammar: null,
};
}
const langData = aliasToLangData(alias);
if (!langData) {
throw new UnknownLanguageError(alias);
}
const grammar = getGrammarFromRegistry(langData.scopeName);
if (!grammar) {
throw new Error(`Syntax highlighting error: grammar for ${alias} not loaded`);
}
return {
langId: langData.id,
grammar,
};
}
function getGrammarFromRegistry(scopeName) {
const { _syncRegistry } = registry;
return _syncRegistry === null || _syncRegistry === void 0 ? void 0 : _syncRegistry._grammars[scopeName];
}
class UnknownLanguageError extends Error {
constructor(alias) {
Expand All @@ -2501,6 +2551,10 @@ function highlightTokensWithScopes(code, grammar, theme) {
registry.setTheme(theme);
const colorMap = registry.getColorMap();
return tokenizeWithScopes(code, grammar, colorMap);
}
function highlightText(code) {
const lines = code.split(/\r?\n|\r/g);
return lines.map((line) => [{ content: line, style: {} }]);
}

function parseRelativeRanges(relativeRange, lineNumber) {
Expand Down Expand Up @@ -2971,22 +3025,21 @@ function isAnnotatedConfig(config) {
}
async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}) {
const theCode = code || "";
const theLang = lang || "js"; // TODO default to text
const theLang = lang || "text";
if (typeof theCode !== "string") {
throw new Error("Syntax highlighter error: code must be a string");
}
if (typeof theLang !== "string") {
throw new Error("Syntax highlighter error: lang must be a string");
}
const { langId, grammarsPromise } = loadGrammars(theLang);
const theme = await loadTheme(themeOrThemeName);
if (!theme) {
throw new UnknownThemeError(themeOrThemeName);
}
const grammar = await grammarsPromise;
const lines = (config === null || config === void 0 ? void 0 : config.scopes)
? highlightTokensWithScopes(theCode, grammar, theme)
: highlightTokens(theCode, grammar, theme);
await preload([theLang], themeOrThemeName);
const { langId, grammar } = getGrammar(theLang);
const theme = getTheme(themeOrThemeName);
const lines = langId == "text"
? highlightText(theCode)
: (config === null || config === void 0 ? void 0 : config.scopes)
? highlightTokensWithScopes(theCode, grammar, theme)
: highlightTokens(theCode, grammar, theme);
if (isAnnotatedConfig(config)) {
const annotations = (config === null || config === void 0 ? void 0 : config.annotations) || [];
return {
Expand All @@ -3003,6 +3056,9 @@ async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}
};
}
}
async function preload(langs, theme) {
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
}
/** @deprecated use highlight instead */
async function highlightWithScopes(code, alias, themeOrThemeName = "dark-plus") {
return highlight(code, alias, themeOrThemeName, { scopes: true });
Expand All @@ -3015,10 +3071,10 @@ async function extractAnnotations(code, lang, annotationNames = []) {
if (annotationNames.length === 0) {
return { code, annotations: [] };
}
const { grammarsPromise } = loadGrammars(lang);
const grammar = await grammarsPromise;
await preloadGrammars([lang]);
const { grammar } = getGrammar(lang);
const { newCode, annotations } = extractCommentsFromCode(code, grammar, annotationNames);
return { code: newCode, annotations };
}

export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightWithScopes };
export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightWithScopes, preload };
121 changes: 89 additions & 32 deletions lib/dist/index.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

1 comment on commit ee37d6d

@vercel
Copy link

@vercel vercel bot commented on ee37d6d Apr 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lighter – ./

lighter-codehike.vercel.app
lighter.codehike.org
lighter-git-main-codehike.vercel.app

Please sign in to comment.