High-performance Markdown parser with full CommonMark support, syntax extensions, and configurable rule systems.
—
The utils module provides helper functions for custom rule development, text processing, and HTML manipulation. These utilities are exposed to enable consistent behavior in custom rendering rules and plugins.
Functions for runtime type checking and validation.
/**
* Check if value is a string
* @param obj - Value to check
* @returns True if value is a string
*/
function isString(obj: any): boolean;Usage Examples:
import { utils } from "remarkable";
// Type checking in custom rules
function customRule(state, start, end, silent) {
const line = state.getLines(start, start + 1, 0, false);
if (!utils.isString(line)) {
return false;
}
// Process string content
return processLine(line);
}
// Validating plugin options
function myPlugin(md, options) {
if (options.template && !utils.isString(options.template)) {
throw new Error('Template option must be a string');
}
}Functions for object property checking and manipulation.
/**
* Check if object has own property
* @param object - Object to check
* @param key - Property key to look for
* @returns True if object has the property
*/
function has(object: object, key: string): boolean;
/**
* Merge multiple objects into target object (Object.assign polyfill)
* @param target - Target object to merge into
* @param sources - Source objects to merge from
* @returns Modified target object
*/
function assign(target: object, ...sources: object[]): object;Usage Examples:
import { utils } from "remarkable";
// Property checking in custom rules
function processToken(token, options) {
if (utils.has(token, 'attrs') && token.attrs) {
// Process attributes
token.attrs.forEach(([name, value]) => {
console.log(`${name}: ${value}`);
});
}
if (utils.has(options, 'customClass')) {
token.attrSet('class', options.customClass);
}
}
// Object merging for plugin options
function configurePlugin(defaultOptions, userOptions) {
return utils.assign({}, defaultOptions, userOptions);
}
// Example usage
const defaultOpts = { theme: 'default', showNumbers: false };
const userOpts = { showNumbers: true, highlighter: 'prism' };
const finalOpts = utils.assign({}, defaultOpts, userOpts);
// Result: { theme: 'default', showNumbers: true, highlighter: 'prism' }Functions for processing and escaping text content.
/**
* Unescape markdown escape sequences
* @param str - String with markdown escapes
* @returns String with escapes resolved
*/
function unescapeMd(str: string): string;
/**
* Replace HTML entities with their character equivalents
* @param str - String containing HTML entities
* @returns String with entities replaced
*/
function replaceEntities(str: string): string;
/**
* Escape HTML special characters
* @param str - String to escape
* @returns HTML-safe string
*/
function escapeHtml(str: string): string;Usage Examples:
import { utils } from "remarkable";
// Unescaping markdown in custom rules
function processMarkdown(content) {
// Handle escaped characters like \* \_ \#
const unescaped = utils.unescapeMd(content);
return unescaped;
}
// Entity replacement in text processing
function processEntities(text) {
// Convert & < > " ' etc. to actual characters
const withEntities = utils.replaceEntities(text);
return withEntities;
}
// HTML escaping for safe output
function customTextRule(tokens, idx, options, env, renderer) {
const token = tokens[idx];
const safeContent = utils.escapeHtml(token.content);
return safeContent;
}
// Example transformations
console.log(utils.unescapeMd('\\*not italic\\*')); // → *not italic*
console.log(utils.replaceEntities('<p>')); // → <p>
console.log(utils.escapeHtml('<script>alert(1)</script>')); // → <script>alert(1)</script>Advanced utilities for Unicode and HTML entity processing.
/**
* Check if Unicode code point is valid
* @param code - Unicode code point to validate
* @returns True if code point is valid
*/
function isValidEntityCode(code: number): boolean;
/**
* Convert Unicode code point to string character
* @param code - Unicode code point
* @returns String character for the code point
*/
function fromCodePoint(code: number): string;Usage Examples:
import { utils } from "remarkable";
// Unicode validation
const validCode = 0x1F600; // 😀 emoji
console.log(utils.isValidEntityCode(validCode)); // → true
const invalidCode = 0xD800; // Surrogate pair range
console.log(utils.isValidEntityCode(invalidCode)); // → false
// Code point conversion
console.log(utils.fromCodePoint(0x1F600)); // → 😀
console.log(utils.fromCodePoint(0x41)); // → A
console.log(utils.fromCodePoint(0x20AC)); // → €
// Custom entity processing
function processCustomEntities(text) {
return text.replace(/&#(\d+);/g, (match, code) => {
const codeNum = parseInt(code, 10);
return utils.isValidEntityCode(codeNum)
? utils.fromCodePoint(codeNum)
: match; // Keep original if invalid
});
}Common patterns for using utilities in custom rules and plugins.
Custom Renderer Rules:
import { Remarkable, utils } from "remarkable";
const md = new Remarkable();
// Safe text rendering with escaping
md.renderer.rules.text = function(tokens, idx, options, env, renderer) {
const token = tokens[idx];
return utils.escapeHtml(token.content);
};
// Custom code block with entity handling
md.renderer.rules.code = function(tokens, idx, options, env, renderer) {
const token = tokens[idx];
const content = utils.replaceEntities(token.content);
const escaped = utils.escapeHtml(content);
if (token.block) {
return `<pre><code>${escaped}</code></pre>\n`;
}
return `<code>${escaped}</code>`;
};
// Link processing with validation
md.renderer.rules.link_open = function(tokens, idx, options, env, renderer) {
const token = tokens[idx];
const href = token.attrGet('href');
if (utils.isString(href)) {
const safeHref = utils.escapeHtml(href);
token.attrSet('href', safeHref);
}
return '<a' + renderer.renderAttrs(token) + '>';
};Plugin Development:
function safeContentPlugin(md, options) {
const defaultOptions = {
escapeLevel: 'basic',
preserveEntities: false
};
// Merge options safely
const opts = utils.assign({}, defaultOptions, options);
// Custom rule for safe content processing
md.core.ruler.push('safe_content', function(state) {
state.tokens.forEach(token => {
if (token.type === 'inline' && token.children) {
token.children.forEach(child => {
if (child.type === 'text' && utils.isString(child.content)) {
// Process text content safely
if (!opts.preserveEntities) {
child.content = utils.replaceEntities(child.content);
}
if (opts.escapeLevel === 'full') {
child.content = utils.escapeHtml(child.content);
}
}
});
}
});
});
}
// Usage
const md = new Remarkable().use(safeContentPlugin, {
escapeLevel: 'full',
preserveEntities: true
});Token Processing:
function processTokens(tokens) {
return tokens.map(token => {
// Check for required properties
if (!utils.has(token, 'type')) {
throw new Error('Token missing required type property');
}
// Process text tokens
if (token.type === 'text' && utils.isString(token.content)) {
const processed = utils.assign({}, token);
processed.content = utils.unescapeMd(token.content);
return processed;
}
// Process container tokens
if (utils.has(token, 'children') && Array.isArray(token.children)) {
const processed = utils.assign({}, token);
processed.children = processTokens(token.children);
return processed;
}
return token;
});
}Complete reference of all available utility functions with their signatures.
interface Utils {
/** Type checking */
isString(obj: any): boolean;
/** Object utilities */
has(object: object, key: string): boolean;
assign(target: object, ...sources: object[]): object;
/** String processing */
unescapeMd(str: string): string;
replaceEntities(str: string): string;
escapeHtml(str: string): string;
/** Entity processing (advanced utilities) */
isValidEntityCode(code: number): boolean;
fromCodePoint(code: number): string;
}
// Import patterns
import { utils } from "remarkable";
const { utils } = require("remarkable");
// Individual function imports (not available - import from utils object)
// import { escapeHtml } from "remarkable"; // ❌ Not available
// const { escapeHtml } = utils; // ✅ Correct wayInstall with Tessl CLI
npx tessl i tessl/npm-remarkable