Skip to content

Commit 8a857ff

Browse files
committed
Add highlightSync - fix #15
1 parent 4780ffc commit 8a857ff

File tree

9 files changed

+169
-47
lines changed

9 files changed

+169
-47
lines changed

.changeset/good-zebras-help.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@code-hike/lighter": patch
3+
---
4+
5+
Add highlightSync

lib/dist/browser.esm.mjs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3056,6 +3056,9 @@ class UnknownThemeError extends Error {
30563056
function isAnnotatedConfig(config) {
30573057
return "annotations" in config;
30583058
}
3059+
async function preload(langs, theme) {
3060+
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
3061+
}
30593062
async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}) {
30603063
const theCode = code || "";
30613064
const theLang = lang || "text";
@@ -3066,6 +3069,17 @@ async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}
30663069
throw new Error("Syntax highlighter error: lang must be a string");
30673070
}
30683071
await preload([theLang], themeOrThemeName);
3072+
return highlightSync(theCode, theLang, themeOrThemeName, config);
3073+
}
3074+
function highlightSync(code, lang, themeOrThemeName = "dark-plus", config = {}) {
3075+
const theCode = code || "";
3076+
const theLang = lang || "text";
3077+
if (typeof theCode !== "string") {
3078+
throw new Error("Syntax highlighter error: code must be a string");
3079+
}
3080+
if (typeof theLang !== "string") {
3081+
throw new Error("Syntax highlighter error: lang must be a string");
3082+
}
30693083
const { langId, grammar } = getGrammar(theLang);
30703084
const theme = getTheme(themeOrThemeName);
30713085
const lines = langId == "text"
@@ -3089,9 +3103,6 @@ async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}
30893103
};
30903104
}
30913105
}
3092-
async function preload(langs, theme) {
3093-
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
3094-
}
30953106
/** @deprecated use highlight instead */
30963107
async function highlightWithScopes(code, alias, themeOrThemeName = "dark-plus") {
30973108
return highlight(code, alias, themeOrThemeName, { scopes: true });
@@ -3110,4 +3121,4 @@ async function extractAnnotations(code, lang, annotationNames = []) {
31103121
return { code: newCode, annotations };
31113122
}
31123123

3113-
export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightWithScopes, preload };
3124+
export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightSync, highlightWithScopes, preload };

lib/dist/index.cjs.js

Lines changed: 15 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/dist/index.d.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,33 +126,35 @@ declare class UnknownThemeError extends Error {
126126
theme: string;
127127
constructor(theme: string);
128128
}
129-
130129
type Config = {
131130
scopes?: boolean;
132131
};
133132
type AnnotatedConfig = {
134133
annotations: Annotation[];
135134
} & Config;
136-
type Result = {
135+
type LighterResult = {
137136
lines: Token[][];
138137
lang: LanguageName;
139138
colors: ThemeColors;
140139
};
141-
type AnnotatedResult = {
140+
type AnnotatedLighterResult = {
142141
lines: Lines;
143142
lang: LanguageName;
144143
colors: ThemeColors;
145144
};
146-
declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName?: Theme, config?: Config): Promise<Result>;
147-
declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName: Theme, config: AnnotatedConfig): Promise<AnnotatedResult>;
145+
148146
declare function preload(langs: LanguageAlias[], theme?: Theme): Promise<void>;
147+
declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName?: Theme, config?: Config): Promise<LighterResult>;
148+
declare function highlight(code: string, lang: LanguageAlias, themeOrThemeName: Theme, config: AnnotatedConfig): Promise<AnnotatedLighterResult>;
149+
declare function highlightSync(code: string, lang: LanguageAlias, themeOrThemeName?: Theme, config?: Config): LighterResult;
150+
declare function highlightSync(code: string, lang: LanguageAlias, themeOrThemeName: Theme, config: AnnotatedConfig): AnnotatedLighterResult;
149151
/** @deprecated use highlight instead */
150-
declare function highlightWithScopes(code: string, alias: LanguageAlias, themeOrThemeName?: Theme): Promise<Result>;
152+
declare function highlightWithScopes(code: string, alias: LanguageAlias, themeOrThemeName?: Theme): Promise<LighterResult>;
151153
/** @deprecated use highlight instead */
152-
declare function annotatedHighlight(code: string, alias: LanguageAlias, themeOrThemeName?: Theme, annotations?: Annotation[]): Promise<AnnotatedResult>;
154+
declare function annotatedHighlight(code: string, alias: LanguageAlias, themeOrThemeName?: Theme, annotations?: Annotation[]): Promise<AnnotatedLighterResult>;
153155
declare function extractAnnotations(code: string, lang: LanguageAlias, annotationNames?: string[]): Promise<{
154156
code: string;
155157
annotations: Annotation[];
156158
}>;
157159

158-
export { Annotation, LANG_NAMES, LanguageAlias, Line, LineGroup, Lines, RawTheme, StringTheme, THEME_NAMES, Theme, ThemeColors, Token, TokenGroup, Tokens, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightWithScopes, preload };
160+
export { AnnotatedLighterResult, Annotation, LANG_NAMES, LanguageAlias, LighterResult, Line, LineGroup, Lines, RawTheme, StringTheme, THEME_NAMES, Theme, ThemeColors, Token, TokenGroup, Tokens, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightSync, highlightWithScopes, preload };

lib/dist/index.esm.mjs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,6 +3404,9 @@ class UnknownThemeError extends Error {
34043404
function isAnnotatedConfig(config) {
34053405
return "annotations" in config;
34063406
}
3407+
async function preload(langs, theme) {
3408+
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
3409+
}
34073410
async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}) {
34083411
const theCode = code || "";
34093412
const theLang = lang || "text";
@@ -3414,6 +3417,17 @@ async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}
34143417
throw new Error("Syntax highlighter error: lang must be a string");
34153418
}
34163419
await preload([theLang], themeOrThemeName);
3420+
return highlightSync(theCode, theLang, themeOrThemeName, config);
3421+
}
3422+
function highlightSync(code, lang, themeOrThemeName = "dark-plus", config = {}) {
3423+
const theCode = code || "";
3424+
const theLang = lang || "text";
3425+
if (typeof theCode !== "string") {
3426+
throw new Error("Syntax highlighter error: code must be a string");
3427+
}
3428+
if (typeof theLang !== "string") {
3429+
throw new Error("Syntax highlighter error: lang must be a string");
3430+
}
34173431
const { langId, grammar } = getGrammar(theLang);
34183432
const theme = getTheme(themeOrThemeName);
34193433
const lines = langId == "text"
@@ -3437,9 +3451,6 @@ async function highlight(code, lang, themeOrThemeName = "dark-plus", config = {}
34373451
};
34383452
}
34393453
}
3440-
async function preload(langs, theme) {
3441-
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
3442-
}
34433454
/** @deprecated use highlight instead */
34443455
async function highlightWithScopes(code, alias, themeOrThemeName = "dark-plus") {
34453456
return highlight(code, alias, themeOrThemeName, { scopes: true });
@@ -3458,4 +3469,4 @@ async function extractAnnotations(code, lang, annotationNames = []) {
34583469
return { code: newCode, annotations };
34593470
}
34603471

3461-
export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightWithScopes, preload };
3472+
export { LANG_NAMES, THEME_NAMES, UnknownLanguageError, UnknownThemeError, annotatedHighlight, extractAnnotations, highlight, highlightSync, highlightWithScopes, preload };

lib/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"build": "rollup -c",
3636
"watch": "rollup -c -w",
3737
"test": "vitest",
38+
"typecheck": "vitest typecheck",
3839
"regenerate": "node ./utils/update.mjs"
3940
},
4041
"repository": "https://github.com/code-hike/lighter",

lib/src/index.ts

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,6 @@ import {
2727
Token,
2828
} from "./annotations";
2929

30-
export type {
31-
LanguageAlias,
32-
Theme,
33-
StringTheme,
34-
RawTheme,
35-
Annotation,
36-
Lines,
37-
LineGroup,
38-
Line,
39-
TokenGroup,
40-
Tokens,
41-
Token,
42-
ThemeColors,
43-
};
44-
4530
class UnknownThemeError extends Error {
4631
theme: string;
4732
constructor(theme: string) {
@@ -50,44 +35,65 @@ class UnknownThemeError extends Error {
5035
}
5136
}
5237

53-
export { UnknownLanguageError, UnknownThemeError, THEME_NAMES, LANG_NAMES };
54-
5538
type Config = { scopes?: boolean };
5639
type AnnotatedConfig = { annotations: Annotation[] } & Config;
57-
type Result = {
40+
type LighterResult = {
5841
lines: Token[][];
5942
lang: LanguageName;
6043
colors: ThemeColors;
6144
};
62-
type AnnotatedResult = {
45+
type AnnotatedLighterResult = {
6346
lines: Lines;
6447
lang: LanguageName;
6548
colors: ThemeColors;
6649
};
6750

51+
export { UnknownLanguageError, UnknownThemeError, THEME_NAMES, LANG_NAMES };
52+
53+
export type {
54+
LanguageAlias,
55+
Theme,
56+
StringTheme,
57+
RawTheme,
58+
Annotation,
59+
Lines,
60+
LineGroup,
61+
Line,
62+
TokenGroup,
63+
Tokens,
64+
Token,
65+
ThemeColors,
66+
LighterResult,
67+
AnnotatedLighterResult,
68+
};
69+
6870
function isAnnotatedConfig(
6971
config: Config | AnnotatedConfig
7072
): config is AnnotatedConfig {
7173
return "annotations" in config;
7274
}
7375

76+
export async function preload(langs: LanguageAlias[], theme?: Theme) {
77+
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
78+
}
79+
7480
export async function highlight(
7581
code: string,
7682
lang: LanguageAlias,
7783
themeOrThemeName?: Theme,
7884
config?: Config
79-
): Promise<Result>;
85+
): Promise<LighterResult>;
8086
export async function highlight(
8187
code: string,
8288
lang: LanguageAlias,
8389
themeOrThemeName: Theme,
8490
config: AnnotatedConfig
85-
): Promise<AnnotatedResult>;
86-
export async function highlight<GivenConfig extends Config>(
91+
): Promise<AnnotatedLighterResult>;
92+
export async function highlight(
8793
code: string,
8894
lang: LanguageAlias,
8995
themeOrThemeName: Theme = "dark-plus",
90-
config: Config = {}
96+
config: Config | AnnotatedConfig = {}
9197
) {
9298
const theCode = code || "";
9399
const theLang = lang || "text";
@@ -100,6 +106,36 @@ export async function highlight<GivenConfig extends Config>(
100106
}
101107

102108
await preload([theLang], themeOrThemeName);
109+
return highlightSync(theCode, theLang, themeOrThemeName, config) as any;
110+
}
111+
export function highlightSync(
112+
code: string,
113+
lang: LanguageAlias,
114+
themeOrThemeName?: Theme,
115+
config?: Config
116+
): LighterResult;
117+
export function highlightSync(
118+
code: string,
119+
lang: LanguageAlias,
120+
themeOrThemeName: Theme,
121+
config: AnnotatedConfig
122+
): AnnotatedLighterResult;
123+
export function highlightSync(
124+
code: string,
125+
lang: LanguageAlias,
126+
themeOrThemeName: Theme = "dark-plus",
127+
config: Config | AnnotatedConfig = {}
128+
) {
129+
const theCode = code || "";
130+
const theLang = lang || "text";
131+
132+
if (typeof theCode !== "string") {
133+
throw new Error("Syntax highlighter error: code must be a string");
134+
}
135+
if (typeof theLang !== "string") {
136+
throw new Error("Syntax highlighter error: lang must be a string");
137+
}
138+
103139
const { langId, grammar } = getGrammar(theLang);
104140
const theme = getTheme(themeOrThemeName);
105141

@@ -126,10 +162,6 @@ export async function highlight<GivenConfig extends Config>(
126162
}
127163
}
128164

129-
export async function preload(langs: LanguageAlias[], theme?: Theme) {
130-
await Promise.all([preloadGrammars(langs), preloadTheme(theme)]);
131-
}
132-
133165
/** @deprecated use highlight instead */
134166
export async function highlightWithScopes(
135167
code: string,

lib/test/scopes.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { expect, test } from "vitest";
22
import { highlight } from "..";
33

4-
test.only("highlight with scopes", async () => {
4+
test("highlight with scopes", async () => {
55
const code = `export default function Gallery() {
66
77
}`;

lib/test/types.test-d.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import {
2+
highlight,
3+
preload,
4+
highlightSync,
5+
LighterResult,
6+
AnnotatedLighterResult,
7+
} from "../src";
8+
import { expectTypeOf, test } from "vitest";
9+
10+
test("highlight sync types", async () => {
11+
await preload(["typescript"], "dark-plus");
12+
const notAnnotatedResult = highlightSync(
13+
"const x = 1;",
14+
"typescript",
15+
"dark-plus"
16+
);
17+
const annotatedResult = highlightSync(
18+
"const x = 1;",
19+
"typescript",
20+
"dark-plus",
21+
{
22+
annotations: [],
23+
}
24+
);
25+
26+
expectTypeOf(notAnnotatedResult).toMatchTypeOf<LighterResult>();
27+
expectTypeOf(annotatedResult).toMatchTypeOf<AnnotatedLighterResult>();
28+
});
29+
30+
test("highlight types", async () => {
31+
const notAnnotatedResult = await highlight(
32+
"const x = 1;",
33+
"typescript",
34+
"dark-plus",
35+
{}
36+
);
37+
const annotatedResult = await highlight(
38+
"const x = 1;",
39+
"typescript",
40+
"dark-plus",
41+
{
42+
annotations: [],
43+
}
44+
);
45+
46+
expectTypeOf(notAnnotatedResult).toMatchTypeOf<LighterResult>();
47+
expectTypeOf(annotatedResult).toMatchTypeOf<AnnotatedLighterResult>();
48+
});

0 commit comments

Comments
 (0)