1- import { getLanguage , setLanguage } from '../../shared/dom-util' ;
21import { rest , tokenize } from '../../shared/symbols' ;
3- import { htmlEncode } from '../../shared/util' ;
2+ import { highlight } from '../highlight' ;
3+ import { highlightAll } from '../highlight-all' ;
4+ import { highlightElement } from '../highlight-element' ;
45import { LinkedList } from '../linked-list' ;
56import { Registry } from '../registry' ;
67import { Hooks } from './hooks' ;
78import { Token } from './token' ;
89import type { KnownPlugins } from '../../known-plugins' ;
910import type { Grammar , GrammarToken , GrammarTokens , RegExpLike } from '../../types' ;
11+ import type { HighlightOptions } from '../highlight' ;
12+ import type { HighlightAllOptions } from '../highlight-all' ;
13+ import type { HighlightElementOptions } from '../highlight-element' ;
1014import type { LinkedListHeadNode , LinkedListMiddleNode , LinkedListTailNode } from '../linked-list' ;
11- import type { HookEnv } from './hooks' ;
1215import type { TokenStream } from './token' ;
1316
1417/**
@@ -21,159 +24,24 @@ export default class Prism {
2124 plugins : Partial < Record < string , unknown > & KnownPlugins > = { } ;
2225
2326 /**
24- * This is the most high-level function in Prism’s API.
25- * It queries all the elements that have a `.language-xxxx` class and then calls {@link Prism#highlightElement} on
26- * each one of them.
27- *
28- * The following hooks will be run:
29- * 1. `before-highlightall`
30- * 2. `before-all-elements-highlight`
31- * 3. All hooks of {@link Prism#highlightElement} for each element.
27+ * See {@link highlightAll}.
3228 */
3329 highlightAll ( options : HighlightAllOptions = { } ) {
34- const { root, async, callback } = options ;
35-
36- const env : HookEnv = {
37- callback,
38- root : root ?? document ,
39- selector :
40- 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' ,
41- } ;
42-
43- this . hooks . run ( 'before-highlightall' , env ) ;
44-
45- env . elements = [ ...env . root . querySelectorAll ( env . selector ) ] ;
46-
47- this . hooks . run ( 'before-all-elements-highlight' , env ) ;
48-
49- for ( const element of env . elements ) {
50- this . highlightElement ( element , { async, callback : env . callback } ) ;
51- }
30+ return highlightAll . call ( this , options ) ;
5231 }
5332
5433 /**
55- * Highlights the code inside a single element.
56- *
57- * The following hooks will be run:
58- * 1. `before-sanity-check`
59- * 2. `before-highlight`
60- * 3. All hooks of {@link Prism#highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
61- * 4. `before-insert`
62- * 5. `after-highlight`
63- * 6. `complete`
64- *
65- * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
66- * the element's language.
67- *
68- * @param element The element containing the code.
69- * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
34+ * See {@link highlightElement}
7035 */
7136 highlightElement ( element : Element , options : HighlightElementOptions = { } ) {
72- const { async, callback } = options ;
73-
74- // Find language
75- const language = getLanguage ( element ) ;
76- const languageId = this . components . resolveAlias ( language ) ;
77- const grammar = this . components . getLanguage ( languageId ) ;
78-
79- // Set language on the element, if not present
80- setLanguage ( element , language ) ;
81-
82- // Set language on the parent, for styling
83- let parent = element . parentElement ;
84- if ( parent && parent . nodeName . toLowerCase ( ) === 'pre' ) {
85- setLanguage ( parent , language ) ;
86- }
87-
88- const code = element . textContent as string ;
89-
90- const env : HookEnv = {
91- element,
92- language,
93- grammar,
94- code,
95- } ;
96-
97- const insertHighlightedCode = ( highlightedCode : string ) => {
98- env . highlightedCode = highlightedCode ;
99- this . hooks . run ( 'before-insert' , env ) ;
100-
101- env . element . innerHTML = env . highlightedCode ;
102-
103- this . hooks . run ( 'after-highlight' , env ) ;
104- this . hooks . run ( 'complete' , env ) ;
105- callback ?.( env . element ) ;
106- } ;
107-
108- this . hooks . run ( 'before-sanity-check' , env ) ;
109-
110- // plugins may change/add the parent/element
111- parent = env . element . parentElement ;
112- if ( parent && parent . nodeName . toLowerCase ( ) === 'pre' && ! parent . hasAttribute ( 'tabindex' ) ) {
113- parent . setAttribute ( 'tabindex' , '0' ) ;
114- }
115-
116- if ( ! env . code ) {
117- this . hooks . run ( 'complete' , env ) ;
118- callback ?.( env . element ) ;
119- return ;
120- }
121-
122- this . hooks . run ( 'before-highlight' , env ) ;
123-
124- if ( ! env . grammar ) {
125- insertHighlightedCode ( htmlEncode ( env . code ) ) ;
126- return ;
127- }
128-
129- if ( async ) {
130- async ( {
131- language : env . language ,
132- code : env . code ,
133- grammar : env . grammar ,
134- } ) . then ( insertHighlightedCode , error => console . log ( error ) ) ;
135- }
136- else {
137- insertHighlightedCode ( this . highlight ( env . code , env . language , { grammar : env . grammar } ) ) ;
138- }
37+ return highlightElement . call ( this , element , options ) ;
13938 }
14039
14140 /**
142- * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
143- * and the language definitions to use, and returns a string with the HTML produced.
144- *
145- * The following hooks will be run:
146- * 1. `before-tokenize`
147- * 2. `after-tokenize`
148- * 3. `wrap`: On each {@link Token}.
149- *
150- * @param text A string with the code to be highlighted.
151- * @param language The name of the language definition passed to `grammar`.
152- * @param options An object containing the tokens to use.
153- *
154- * Usually a language definition like `Prism.languages.markup`.
155- * @returns The highlighted HTML.
156- * @example
157- * Prism.highlight('var foo = true;', 'javascript');
41+ * See {@link highlight}
15842 */
159- highlight ( text : string , language : string , options ?: HighlightOptions ) : string {
160- const languageId = this . components . resolveAlias ( language ) ;
161- const grammar = options ?. grammar ?? this . components . getLanguage ( languageId ) ;
162-
163- const env : HookEnv = {
164- code : text ,
165- grammar,
166- language,
167- } ;
168- this . hooks . run ( 'before-tokenize' , env ) ;
169- if ( ! env . grammar ) {
170- throw new Error ( 'The language "' + env . language + '" has no grammar.' ) ;
171- }
172-
173- env . tokens = this . tokenize ( env . code , env . grammar ) ;
174- this . hooks . run ( 'after-tokenize' , env ) ;
175-
176- return stringify ( env . tokens , env . language , this . hooks ) ;
43+ highlight ( text : string , language : string , options : HighlightOptions = { } ) : string {
44+ return highlight . call ( this , text , language , options ) ;
17745 }
17846
17947 /**
@@ -392,42 +260,6 @@ interface RematchOptions {
392260 reach : number ;
393261}
394262
395- export interface AsyncHighlightingData {
396- language : string ;
397- code : string ;
398- grammar : Grammar ;
399- }
400- export type AsyncHighlighter = ( data : AsyncHighlightingData ) => Promise < string > ;
401-
402- export interface HighlightAllOptions {
403- /**
404- * The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
405- */
406- root ?: ParentNode ;
407- async ?: AsyncHighlighter ;
408- /**
409- * An optional callback to be invoked on each element after its highlighting is done.
410- *
411- * @see HighlightElementOptions#callback
412- */
413- callback ?: ( element : Element ) => void ;
414- }
415-
416- export interface HighlightElementOptions {
417- async ?: AsyncHighlighter ;
418- /**
419- * An optional callback to be invoked after the highlighting is done.
420- * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
421- *
422- * @param element The element successfully highlighted.
423- */
424- callback ?: ( element : Element ) => void ;
425- }
426-
427- export interface HighlightOptions {
428- grammar ?: Grammar ;
429- }
430-
431263function matchPattern ( pattern : RegExp , pos : number , text : string , lookbehind : boolean ) {
432264 pattern . lastIndex = pos ;
433265 const match = pattern . exec ( text ) ;
@@ -440,70 +272,6 @@ function matchPattern (pattern: RegExp, pos: number, text: string, lookbehind: b
440272 return match ;
441273}
442274
443- /**
444- * Converts the given token or token stream to an HTML representation.
445- *
446- * The following hooks will be run:
447- * 1. `wrap`: On each {@link Token}.
448- *
449- * @param o The token or token stream to be converted.
450- * @param language The name of current language.
451- * @returns The HTML representation of the token or token stream.
452- */
453- function stringify ( o : string | Token | TokenStream , language : string , hooks : Hooks ) : string {
454- if ( typeof o === 'string' ) {
455- return htmlEncode ( o ) ;
456- }
457- if ( Array . isArray ( o ) ) {
458- let s = '' ;
459- o . forEach ( e => {
460- s += stringify ( e , language , hooks ) ;
461- } ) ;
462- return s ;
463- }
464-
465- const env : HookEnv = {
466- type : o . type ,
467- content : stringify ( o . content , language , hooks ) ,
468- tag : 'span' ,
469- classes : [ 'token' , o . type ] ,
470- attributes : { } ,
471- language,
472- } ;
473-
474- const aliases = o . alias ;
475- if ( aliases ) {
476- if ( Array . isArray ( aliases ) ) {
477- env . classes . push ( ...aliases ) ;
478- }
479- else {
480- env . classes . push ( aliases ) ;
481- }
482- }
483-
484- hooks . run ( 'wrap' , env ) ;
485-
486- let attributes = '' ;
487- for ( const name in env . attributes ) {
488- attributes +=
489- ' ' + name + '="' + ( env . attributes [ name ] || '' ) . replace ( / " / g, '"' ) + '"' ;
490- }
491-
492- return (
493- '<' +
494- env . tag +
495- ' class="' +
496- env . classes . join ( ' ' ) +
497- '"' +
498- attributes +
499- '>' +
500- env . content +
501- '</' +
502- env . tag +
503- '>'
504- ) ;
505- }
506-
507275function toGrammarToken ( pattern : GrammarToken | RegExpLike ) : GrammarToken {
508276 if ( ! pattern . pattern ) {
509277 return { pattern } ;
0 commit comments