UNPKG

acquerello

Version:

Template based terminal coloring made really easy.

74 lines (73 loc) 2.68 kB
import { defaultStyles } from './codes.js'; import { convertColorSpec } from './spec.js'; export const templateMatcher = /{{2}([^{}]+?)}{2}/gi; export function clean(raw) { return raw.replaceAll(templateMatcher, ''); } export function colorize(raw) { // Create a new styles stack let stylesStack = []; let stylesInserted = false; // For each tag in the string let modified = raw.replaceAll(templateMatcher, (_, spec)=>{ const revert = []; let replacement = ''; // Get all the styles - Whatever is not found in ansi-styles is ignored const tokens = spec.trim().split(/\s+/).map((s)=>s.trim()); for (const token of tokens){ if (token === '-') { // Remove a style if (stylesStack.length) { // First of all, remove the latest applied style replacement += stylesStack.shift().reverse().map((s)=>s.close).join(''); // If there is a style to restore it, reapply it if (stylesStack.length) { replacement += stylesStack[0].map((s)=>s.open).join(''); } } break; } else if (token === 'reset') { // Forget all previously defined styles stylesStack = []; break; } else { // Search in custom styles first const styles = customStyles.get(token) ?? [ token ]; for (const style of styles){ // Add a style const code = convertColorSpec(style); if (code) { replacement += code.open; revert.push(code); } } } } // If anything was applied, append to the stack if (revert.length) { stylesInserted = true; stylesStack.unshift(revert); } return replacement; }); // Always make sure to reset codes at the end if (stylesInserted) { modified += defaultStyles.reset.close; } return modified; } export function applyStyle(content, ...styles) { return colorize(`{{${styles.join(' ')}}}${content}{{-}}`); } export function addCustomStyle(name, ...styles) { if (!/^[^\s{}]+$/.test(name)) { throw new Error('The custom style name cannot contain spaces or curly braces'); } customStyles.set(name, styles); } export function deleteCustomStyle(name) { customStyles.delete(name); } export const customStyles = new Map();