Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
3beff85
[WIP] Simplify core
LeaVerou Apr 26, 2025
46806b6
highlightAll
LeaVerou Apr 26, 2025
e4f6634
Just use properties on env, not a separate `state` property
LeaVerou Apr 26, 2025
183817c
Move singleton, eliminate state further
LeaVerou Apr 26, 2025
d1097d8
Finish removing HookState
LeaVerou Apr 26, 2025
e3e5db2
Update prism-class.ts
LeaVerou Apr 26, 2025
c866261
Delete hook-state.ts
LeaVerou Apr 26, 2025
8ce6c69
Move more functions out of prism-class
LeaVerou Apr 26, 2025
1a2c60b
Merge branch 'v2' into simplify
LeaVerou Apr 26, 2025
52fca5d
Move tokenize
LeaVerou Apr 26, 2025
1158aa9
Update src/core.ts
LeaVerou Apr 27, 2025
9acac36
Update src/types.d.ts
LeaVerou Apr 27, 2025
8a8bc18
Update src/global.ts
LeaVerou Apr 27, 2025
e0ca584
Update hooks.ts
LeaVerou Apr 27, 2025
2727307
Update hooks.ts
LeaVerou Apr 27, 2025
96e93ea
Update src/core/prism-class.ts
LeaVerou Apr 27, 2025
dbbb0dd
Update src/global.ts
LeaVerou Apr 27, 2025
4dfff4c
Update registry.ts
LeaVerou Apr 27, 2025
a2a5d23
Update eslint.config.mjs
LeaVerou Apr 27, 2025
1e31274
Remove known plugins
LeaVerou Apr 27, 2025
ca6df67
Update prism.ts
LeaVerou Apr 27, 2025
051e0e6
Update src/core/highlight.ts
LeaVerou Apr 27, 2025
2147cae
Update src/core/highlight.ts
LeaVerou Apr 27, 2025
aac6bf7
Merge branch 'v2' into simplify
LeaVerou Apr 27, 2025
6513275
Merge branch 'simplify' of https://github.com/PrismJS/prism into simp…
LeaVerou Apr 27, 2025
de0b0bd
Update src/plugins/keep-markup/prism-keep-markup.ts
LeaVerou Apr 27, 2025
83fad95
[build] Delete `known-plugins.d.ts`
DmitrySharabin Apr 27, 2025
b4366b2
[WIP] Make language definitions more declarative, simplify registry, …
LeaVerou Apr 28, 2025
73ef579
Merge branch 'simplify' of https://github.com/PrismJS/prism into simp…
LeaVerou Apr 28, 2025
0762142
Fixes (#3915)
LeaVerou Apr 28, 2025
60cadeb
`extends` -> `base` and a few other things
LeaVerou Apr 29, 2025
c7ce545
Fix `c`
LeaVerou Apr 29, 2025
abf6b71
Concept for language extensions
LeaVerou Apr 29, 2025
52fe2ae
Move $insertBefore and $delete to extend()
LeaVerou Apr 29, 2025
e12f6df
Separate language patches from other eval, attempt to move types to m…
LeaVerou Apr 29, 2025
42312a5
Update actionscript.ts
LeaVerou Apr 29, 2025
4d8b9ea
Update bison.ts
LeaVerou Apr 29, 2025
f997850
Type wrangling
LeaVerou Apr 29, 2025
5bf9582
Merge branch 'v2' into simplify
LeaVerou Apr 29, 2025
93bbe20
Some suggestions (#3919)
DmitrySharabin Apr 29, 2025
0e674d2
Add proper typing for the `Grammar` type (#3918)
DmitrySharabin Apr 29, 2025
107632e
Preserve context
DmitrySharabin Apr 29, 2025
bf68a19
Merge branch 'simplify' of https://github.com/PrismJS/prism into simp…
LeaVerou Apr 30, 2025
b7623b6
Move iterable helpers to separate file
LeaVerou May 1, 2025
b850074
TS
LeaVerou May 1, 2025
bc5144f
Merge branch 'v2' into simplify
LeaVerou May 1, 2025
1deb867
Update eslint.config.mjs
LeaVerou May 1, 2025
257e650
WIP, improve API around languages
LeaVerou May 1, 2025
552c9e6
First pass on transforming `php` and `php-extras` (#3922)
DmitrySharabin May 1, 2025
1c3531c
First pass on transforming ASP.NET (C#) (#3920)
DmitrySharabin May 1, 2025
269f5d4
First pass (#3921)
DmitrySharabin May 1, 2025
9a70161
Move grammar back into types
LeaVerou May 1, 2025
9ffbe35
Languages
LeaVerou May 1, 2025
6a14538
Drop tokenize and rest symbols in favor of $tokenize and $rest proper…
LeaVerou May 1, 2025
0ea3547
Update tokenize.ts
LeaVerou May 1, 2025
586bd55
Sample rewrite to show what group matching + $language can do
LeaVerou May 1, 2025
69f8bf3
Remove effect from languages
LeaVerou May 1, 2025
097f21a
Suggestions to the `simplify` branch (#3925)
DmitrySharabin May 2, 2025
6fb945c
Allow implicit any
LeaVerou May 2, 2025
f7c21f6
Move language utils to `util/` and separate them out
LeaVerou May 2, 2025
1baaebf
Add aliases to C++, C#, F# so markdown doesn't need to handle them sp…
LeaVerou May 2, 2025
b5d562e
Drop xml-doc
LeaVerou May 2, 2025
ff26b79
Drop shared file, not worth it
LeaVerou May 2, 2025
42ebc79
Some more work on dynamic langs (still very WIP)
LeaVerou May 2, 2025
9fb2ed1
`resolveGrammar` -> `grammarPatch`
LeaVerou May 2, 2025
3d760a5
insertAfter, deep keys
LeaVerou May 2, 2025
9dc1677
Make php-extras just a part of PHP
LeaVerou May 2, 2025
ba3a8b4
Add media types and extensions
LeaVerou May 2, 2025
dcf018c
Fix typo
DmitrySharabin May 2, 2025
577eb31
Some more suggestions to the `simplify` branch (#3926)
DmitrySharabin May 3, 2025
6661905
Preserve accessors when extending/copying objects
LeaVerou May 5, 2025
b76f673
Suggestions (next iteration) (#3928)
DmitrySharabin May 7, 2025
a08fd18
Simplify hooks, add type safety
LeaVerou May 7, 2025
e2d15e9
Update util.ts
LeaVerou May 7, 2025
dedc06d
WIP
LeaVerou May 7, 2025
abc87fd
Update src/core/classes/language-registry.ts
LeaVerou May 7, 2025
1b7e413
Update highlight.ts
LeaVerou May 7, 2025
c08e814
Merge branch 'simplify' of https://github.com/PrismJS/prism into simp…
LeaVerou May 7, 2025
5f1da53
Update src/core/classes/hooks.ts
LeaVerou May 7, 2025
97a28fd
Drop `$language`
LeaVerou May 13, 2025
0d0ea00
Break down `tokenize.ts` into separate modules
LeaVerou May 15, 2025
ff0a08b
Prettier
LeaVerou May 15, 2025
4a631e9
Registry -> ComponentRegistry
LeaVerou May 15, 2025
4e3f178
async util
LeaVerou May 15, 2025
c03ab64
Update eslint.config.mjs
LeaVerou May 17, 2025
7c8205a
Update async.ts
LeaVerou May 17, 2025
4a71b8d
Update async.ts
LeaVerou May 17, 2025
3e1e9c7
Update language.ts
LeaVerou May 17, 2025
2f5c194
Update language.ts
LeaVerou May 17, 2025
eb5e425
Update types.d.ts
LeaVerou May 17, 2025
f069a78
tokenize
LeaVerou May 17, 2025
1888f4a
Move Token class to classes
LeaVerou May 17, 2025
3a25f8e
First stab at functional $inside/$rest
LeaVerou May 18, 2025
630b6d4
Some suggestions to the `simplify` branch (#3939)
DmitrySharabin May 18, 2025
7a7979c
Update the `Language` class (#3941)
DmitrySharabin May 25, 2025
a1112bc
Some fixes to `tokenize` (#3942)
DmitrySharabin May 25, 2025
bc34dde
Partially fix tests (in the `simplify` branch) (#3940)
DmitrySharabin May 25, 2025
e07c8b7
Another attempt to avoid the “too deep” structure error and not fall…
DmitrySharabin May 26, 2025
ca7fc26
Update Prettier plugins (#3945)
DmitrySharabin May 27, 2025
ccbc10b
Bug fixes (the `simplify` branch) (#3943)
DmitrySharabin May 28, 2025
3935b1a
Correctly parse CLI arguments (#3949)
DmitrySharabin May 29, 2025
0725758
Make `nextTick()` work in environments other than browsers (#3952)
DmitrySharabin May 29, 2025
b86c4e0
Resolve the language if its definition is already loaded, and it is n…
DmitrySharabin May 29, 2025
830fdff
Fix the Markdown language (#3950)
DmitrySharabin May 29, 2025
5660d05
Transform languages (#3948)
DmitrySharabin May 31, 2025
37bdeeb
Fix the gradle language (#3955)
DmitrySharabin Jun 1, 2025
7c7c598
In addition to waiting for all promises to settle, handle post-hoc ad…
DmitrySharabin Jun 17, 2025
d8246d5
Integrate changes from the `v2` branch (#3982)
DmitrySharabin Jul 11, 2025
54a2dfa
Merge branch 'v2' into simplify
DmitrySharabin Jul 11, 2025
d110fa7
Fix issues after resolving conflicts
DmitrySharabin Jul 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { Prism } from './core/prism';
export { Prism } from './core/prism-class';

Check failure on line 1 in src/core.ts

View workflow job for this annotation

GitHub Actions / type-check

Module '"./core/prism-class"' has no exported member 'Prism'. Did you mean to use 'import Prism from "./core/prism-class"' instead?
export { Token } from './core/token';
41 changes: 41 additions & 0 deletions src/core/highlight-all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import singleton, { type Prism } from './prism';
import type { HighlightElementOptions } from './highlight-element';

/**
* This is the most high-level function in Prism’s API.
* It queries all the elements that have a `.language-xxxx` class and then calls {@link Prism#highlightElement} on
* each one of them.
*
* The following hooks will be run:
* 1. `before-highlightall`
* 2. `before-all-elements-highlight`
* 3. All hooks of {@link Prism#highlightElement} for each element.
*/
export function highlightAll (this: Prism, options: HighlightAllOptions = {}) {
const prism = this ?? singleton;
const { root, async, callback } = options;

const env: Record<any, any> = {
callback,
root: root ?? document,
selector:
'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
};

prism.hooks.run('before-highlightall', env);

env.elements = [...env.root.querySelectorAll(env.selector)];

Check failure on line 27 in src/core/highlight-all.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe spread of an `any` value in an array

Check failure on line 27 in src/core/highlight-all.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe member access .querySelectorAll on an `any` value

prism.hooks.run('before-all-elements-highlight', env);

for (const element of env.elements) {
prism.highlightElement(element, { async, callback: env.callback });

Check failure on line 32 in src/core/highlight-all.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe argument of type `any` assigned to a parameter of type `Element`

Check failure on line 32 in src/core/highlight-all.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an `any` value
}
}

export interface HighlightAllOptions extends HighlightElementOptions {
/**
* The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
*/
root?: ParentNode;
}
114 changes: 114 additions & 0 deletions src/core/highlight-element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { getLanguage, setLanguage } from '../shared/dom-util';
import { htmlEncode } from '../shared/util';
import type { Grammar, GrammarToken, GrammarTokens, RegExpLike } from '../types';

Check failure on line 3 in src/core/highlight-element.ts

View workflow job for this annotation

GitHub Actions / lint

'GrammarToken' is defined but never used
import singleton, { type Prism } from './prism';

Check warning on line 4 in src/core/highlight-element.ts

View workflow job for this annotation

GitHub Actions / lint

`./prism` import should occur before type import of `../types`

/**
* Highlights the code inside a single element.
*
* The following hooks will be run:
* 1. `before-sanity-check`
* 2. `before-highlight`
* 3. All hooks of {@link Prism#highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
* 4. `before-insert`
* 5. `after-highlight`
* 6. `complete`
*
* Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
* the element's language.
*
* @param element The element containing the code.
* It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
*/
export function highlightElement (
this: Prism,
element: Element,
options: HighlightElementOptions = {}
) {
const prism = this ?? singleton;
const { async, callback } = options;

// Find language
const language = getLanguage(element);
const languageId = prism.components.resolveAlias(language);
const grammar = prism.components.getLanguage(languageId);

// Set language on the element, if not present
setLanguage(element, language);

// Set language on the parent, for styling
let parent = element.parentElement;
if (parent && parent.nodeName.toLowerCase() === 'pre') {
setLanguage(parent, language);
}

const code = element.textContent as string;

const env: Record<string, any> = {
element,
language,
grammar,
code,
};

const insertHighlightedCode = (highlightedCode: string) => {
env.highlightedCode = highlightedCode;
prism.hooks.run('before-insert', env);

env.element.innerHTML = env.highlightedCode;

prism.hooks.run('after-highlight', env);
prism.hooks.run('complete', env);
callback?.(env.element);
};

prism.hooks.run('before-sanity-check', env);

// plugins may change/add the parent/element
parent = env.element.parentElement;
if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
parent.setAttribute('tabindex', '0');
}

if (!env.code) {
prism.hooks.run('complete', env);
callback?.(env.element);
return;
}

prism.hooks.run('before-highlight', env);

if (!env.grammar) {
insertHighlightedCode(htmlEncode(env.code));
return;
}

if (async) {
async({
language: env.language,
code: env.code,
grammar: env.grammar,
}).then(insertHighlightedCode, error => console.log(error));
}
else {
insertHighlightedCode(prism.highlight(env.code, env.language, { grammar: env.grammar }));
}
}

export interface HighlightElementOptions {
async?: AsyncHighlighter;
/**
* An optional callback to be invoked after the highlighting is done.
* Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
*
* @param element The element successfully highlighted.
*/
callback?: (element: Element) => void;
}

export interface AsyncHighlightingData {
language: string;
code: string;
grammar: Grammar;
}
export type AsyncHighlighter = (data: AsyncHighlightingData) => Promise<string>;
55 changes: 55 additions & 0 deletions src/core/highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Token } from './token';

Check warning on line 1 in src/core/highlight.ts

View workflow job for this annotation

GitHub Actions / lint

`./token` import should occur after import of `./stringify`
import singleton, { type Prism } from './prism';
import { stringify } from './stringify';
import type { Grammar, GrammarToken, GrammarTokens, RegExpLike } from '../types';

/**
* Low-level function, only use if you know what you’re doing. It accepts a string of text as input
* and the language definitions to use, and returns a string with the HTML produced.
*
* The following hooks will be run:
* 1. `before-tokenize`
* 2. `after-tokenize`
* 3. `wrap`: On each {@link Token}.
*
* @param text A string with the code to be highlighted.
* @param language The name of the language definition passed to `grammar`.
* @param options An object containing the tokens to use.
*
* Usually a language definition like `Prism.languages.markup`.
* @returns The highlighted HTML.
* @example
* Prism.highlight('var foo = true;', 'javascript');
*/
export function highlight (
this: Prism,
text: string,
language: string,
options?: HighlightOptions
): string {
const prism = this ?? singleton;

const languageId = prism.components.resolveAlias(language);
const grammar = options?.grammar ?? prism.components.getLanguage(languageId);

const env: Record<string, any> | Record<string, any> = {
code: text,
grammar,
language,
};

prism.hooks.run('before-tokenize', env);

if (!env.grammar) {
throw new Error('The language "' + env.language + '" has no grammar.');
}

env.tokens = prism.tokenize(env.code, env.grammar);
prism.hooks.run('after-tokenize', env);

return stringify(env.tokens, env.language, prism.hooks);
}

export interface HighlightOptions {
grammar?: Grammar;
}
25 changes: 0 additions & 25 deletions src/core/hook-state.ts

This file was deleted.

106 changes: 2 additions & 104 deletions src/core/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import type { Grammar, TokenName } from '../types';
import type { HookState } from './hook-state';
import type { TokenStream } from './token';

export class Hooks {
// eslint-disable-next-line func-call-spacing
private _all = new Map<string, ((env: unknown) => void)[]>();
Expand Down Expand Up @@ -47,7 +43,7 @@ export class Hooks {
* @param name The name of the hook.
* @param env The environment variables of the hook passed to all callbacks registered.
*/
run<Name extends string> (name: Name, env: HookEnv<Name>): void {
run<Name extends string> (name: Name, env: Record<string, any>): void {
const callbacks = this._all.get(name);

if (!callbacks || !callbacks.length) {
Expand All @@ -60,102 +56,4 @@ export class Hooks {
}
}

/**
* An interface containing all hooks Prism runs.
*/
export interface HookEnvMap {
// Prism.highlightAll
'before-highlightall': BeforeHighlightAllEnv;
'before-all-elements-highlight': BeforeAllElementsHighlightEnv;

// Prism.highlightElement
'before-sanity-check': BeforeSanityCheckEnv;
'before-highlight': BeforeHighlightEnv;

'before-insert': BeforeInsertEnv;
'after-highlight': AfterHighlightEnv;
'complete': CompleteEnv;

// Prism.highlight
'before-tokenize': BeforeTokenizeEnv;
'after-tokenize': AfterTokenizeEnv;

// stringify
'wrap': WrapEnv;
}

export type HookEnv<HookName extends string> = HookName extends keyof HookEnvMap
? HookEnvMap[HookName]
: unknown;

export type HookCallback<HookName extends string> = (env: HookEnv<HookName>) => void;

interface StatefulEnv {
readonly state: HookState;
}

export interface BeforeHighlightAllEnv extends StatefulEnv {
root: ParentNode;
selector: string;
callback?: (element: Element) => void;
}
export interface BeforeAllElementsHighlightEnv extends StatefulEnv {
root: ParentNode;
selector: string;
callback?: (element: Element) => void;
elements: Element[];
}

export interface BeforeSanityCheckEnv extends StatefulEnv {
element: Element;
language: string;
grammar: Grammar | undefined;
code: string;
}
export interface BeforeHighlightEnv extends StatefulEnv {
element: Element;
language: string;
grammar: Grammar | undefined;
code: string;
}
export interface CompleteEnv extends StatefulEnv {
element: Element;
language: string;
grammar: Grammar | undefined;
code: string;
}
export interface BeforeInsertEnv extends StatefulEnv {
element: Element;
language: string;
grammar: Grammar | undefined;
code: string;
highlightedCode: string;
}
export interface AfterHighlightEnv extends StatefulEnv {
element: Element;
language: string;
grammar: Grammar | undefined;
code: string;
highlightedCode: string;
}

export interface BeforeTokenizeEnv {
code: string;
language: string;
grammar: Grammar | undefined;
}
export interface AfterTokenizeEnv {
code: string;
language: string;
grammar: Grammar;
tokens: TokenStream;
}

export interface WrapEnv {
type: TokenName;
content: string;
tag: string;
classes: string[];
attributes: Record<string, string>;
language: string;
}
export type HookCallback<HookName extends string> = (env: Record<string, any>) => void;
Loading
Loading