Renders highlighted Prism output using React with render props pattern for syntax highlighting
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Utility functions and the bundled Prism instance for advanced usage, custom implementations, and direct access to tokenization functionality.
Pre-configured Prism.js instance with common programming languages bundled for optimal performance and no global namespace pollution.
/**
* Pre-configured Prism.js instance with bundled language definitions
* Includes common programming languages without polluting global namespace
*/
declare const Prism: PrismLib;
interface PrismLib {
/** Object containing grammar definitions for supported languages */
languages: Record<string, PrismGrammar>;
/** Tokenize text using a specific grammar */
tokenize(text: string, grammar: PrismGrammar): (string | PrismToken)[];
/** Hook system for extending Prism functionality */
hooks: {
/** Run hooks for specific events */
run(name: string, env: EnvConfig): void;
};
}
type PrismGrammar = import("prismjs").Grammar;Supported Languages:
Usage Examples:
import { Prism } from "prism-react-renderer";
// Check if a language is supported
function isLanguageSupported(language: string): boolean {
return language.toLowerCase() in Prism.languages;
}
// Get available languages
const availableLanguages = Object.keys(Prism.languages);
console.log("Supported languages:", availableLanguages);
// Direct tokenization
const code = "const greeting = 'Hello, World!';";
const grammar = Prism.languages.javascript;
const tokens = Prism.tokenize(code, grammar);
// Use with custom hook implementations
function useCustomTokenizer(code: string, language: string) {
const grammar = Prism.languages[language.toLowerCase()];
if (!grammar) {
console.warn(`Grammar not found for language: ${language}`);
return [code]; // Return as plain text
}
return Prism.tokenize(code, grammar);
}
// Language fallback handling
function getGrammarWithFallback(language: string): PrismGrammar | null {
const normalizedLang = language.toLowerCase();
// Direct match
if (Prism.languages[normalizedLang]) {
return Prism.languages[normalizedLang];
}
// Common aliases
const aliases: Record<string, string> = {
'js': 'javascript',
'ts': 'typescript',
'py': 'python',
'md': 'markdown',
'yml': 'yaml'
};
const aliasTarget = aliases[normalizedLang];
if (aliasTarget && Prism.languages[aliasTarget]) {
return Prism.languages[aliasTarget];
}
return null;
}Utility function that converts Prism's raw token output into a normalized 2D array structure organized by lines.
/**
* Converts Prism tokens into normalized Token structure grouped by lines
* Handles nested tokens, newlines, and empty lines consistently
* @param tokens - Raw tokens from Prism.tokenize()
* @returns 2D array of normalized tokens organized by lines
*/
declare function normalizeTokens(tokens: (PrismToken | string)[]): Token[][];
interface Token {
/** Array of token type classifications */
types: string[];
/** Token content/text */
content: string;
/** Whether this token represents an empty line */
empty?: boolean;
}Usage Examples:
import { normalizeTokens, Prism } from "prism-react-renderer";
// Basic normalization
const code = `function greet(name) {
console.log('Hello, ' + name);
}`;
const grammar = Prism.languages.javascript;
const rawTokens = Prism.tokenize(code, grammar);
const normalizedTokens = normalizeTokens(rawTokens);
console.log(normalizedTokens);
// [
// [{ types: ['keyword'], content: 'function' }, { types: ['plain'], content: ' ' }, ...],
// [{ types: ['plain'], content: ' ' }, { types: ['builtin'], content: 'console' }, ...],
// [{ types: ['punctuation'], content: '}' }]
// ]
// Handle empty lines
const codeWithEmptyLines = `const a = 1;
const b = 2;`;
const tokensWithEmpty = normalizeTokens(Prism.tokenize(codeWithEmptyLines, grammar));
// Second array will contain: [{ types: ['plain'], content: '\n', empty: true }]
// Custom rendering with normalized tokens
function renderTokens(tokens: Token[][]) {
return tokens.map((line, lineIndex) => (
<div key={lineIndex} className="code-line">
{line.map((token, tokenIndex) => (
<span
key={tokenIndex}
className={token.types.join(' ')}
data-empty={token.empty || undefined}
>
{token.content}
</span>
))}
</div>
));
}For languages not included in the bundle, you can extend Prism:
import { Prism } from "prism-react-renderer";
// Note: This requires additional Prism language definitions
// You would need to import and register the language manually
// Example of how to check and handle unsupported languages
function highlightWithFallback(code: string, language: string) {
const grammar = Prism.languages[language.toLowerCase()];
if (!grammar) {
// Fallback to plain text
return normalizeTokens([code]);
}
const tokens = Prism.tokenize(code, grammar);
return normalizeTokens(tokens);
}import { useTokenize, Prism } from "prism-react-renderer";
import { useMemo } from "react";
function OptimizedHighlighter({ code, language }) {
// Grammar lookup is memoized
const grammar = useMemo(() => {
return Prism.languages[language.toLowerCase()];
}, [language]);
// useTokenize already includes memoization
const tokens = useTokenize({
prism: Prism,
code,
language,
grammar
});
return (
<div>
{tokens.map((line, i) => (
<div key={i}>
{line.map((token, j) => (
<span key={j} className={token.types.join(' ')}>
{token.content}
</span>
))}
</div>
))}
</div>
);
}type Language = string;
type PrismGrammar = import("prismjs").Grammar;
type PrismLib = typeof import("prismjs");Install with Tessl CLI
npx tessl i tessl/npm-prism-react-renderer