UNPKG

remark-directive-sugar

Version:

Remark plugin built on remark-directive, providing predefined directives for image captions, video embedding, styled GitHub links, badges, and more.

87 lines (86 loc) 2.98 kB
const reservedDirectiveNames = new Set(['image', 'video', 'badge', 'link']); /** * Creates a regex for matching the directive. */ export const createDirectiveRegex = (directiveName, alias) => { const aliases = new Set([ directiveName, ...(Array.isArray(alias) ? alias : typeof alias === 'string' ? [alias] : []), ]); const otherDirectives = [...reservedDirectiveNames].filter((name) => name !== directiveName); for (const reserved of otherDirectives) { if (aliases.has(reserved)) { throw new Error(`The alias '${reserved}' is reserved and cannot be used for the '${directiveName}' directive.`); } } const aliasPattern = [...aliases] .map((alias) => alias.replaceAll(/[-/\\^$*+?.()|[\]{}]/g, String.raw `\$&`)) .join('|'); return new RegExp(`^(?:${aliasPattern})(?:-(\\w+))?$`); }; /** * Call a function to get a return value or use the value. */ export function createIfNeeded(value, node) { return typeof value === 'function' ? value(node) : value; } /** * Merges the props of global, preset, and local into a single object: * - The order of precedence is: localProps > presetProps > globalProps. * - For class or className, do not override but merge into a new className. */ export function mergeProps(globalProps, presetProps, localProps) { const configs = [globalProps, presetProps, localProps]; const classes = new Set(); const newProps = {}; const addClasses = (value) => { if (typeof value === 'string') { for (const c of value.split(/\s+/)) { if (c) classes.add(c); } } else if (Array.isArray(value)) { for (const c of value) { if (typeof c === 'string' && c) { classes.add(c); } } } }; for (const config of configs) { if (!config) continue; for (const key of Object.keys(config)) { const value = config[key]; if (value) { if (key === 'class' || key === 'className') { addClasses(value); } else { newProps[key] = value; } } } } if (classes.size > 0) newProps.className = [...classes]; return newProps; } /** * Process a URL by removing the protocol and shortening the path * to a maximum length. */ export function processUrl(url, maxPathLength = 14) { const urlWithoutProtocol = url.replace(/(^\w+:|^)\/\//, ''); const [hostname, ...pathParts] = urlWithoutProtocol.split('/'); const path = pathParts.join('/'); const shortenedPath = path.length > maxPathLength ? path.slice(0, Math.max(0, maxPathLength)) : path; return hostname + (shortenedPath ? '/' + shortenedPath + '...' : ''); }