UNPKG

styled-string-builder

Version:

String Styler class based on a builder design pattern

462 lines (456 loc) 29.5 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["styled-string-builder"] = {})); })(this, (function (exports) { 'use strict'; /** * @description ANSI escape code for resetting text formatting. * @summary This constant holds the ANSI escape sequence used to reset all text formatting to default. * @const AnsiReset * @memberOf module:StyledString */ const AnsiReset = "\x1b[0m"; /** * @description Standard foreground color codes for ANSI text formatting. * @summary This object maps color names to their corresponding ANSI color codes for standard foreground colors. * @const StandardForegroundColors * @property {number} black - ANSI code for black text (30). * @property {number} red - ANSI code for red text (31). * @property {number} green - ANSI code for green text (32). * @property {number} yellow - ANSI code for yellow text (33). * @property {number} blue - ANSI code for blue text (34). * @property {number} magenta - ANSI code for magenta text (35). * @property {number} cyan - ANSI code for cyan text (36). * @property {number} white - ANSI code for white text (37). * @memberOf module:StyledString */ const StandardForegroundColors = { black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, }; /** * @description Bright foreground color codes for ANSI text formatting. * @summary This object maps color names to their corresponding ANSI color codes for bright foreground colors. * @const BrightForegroundColors * @property {number} black - ANSI code for bright black text (90). * @property {number} red - ANSI code for bright red text (91). * @property {number} green - ANSI code for bright green text (92). * @property {number} yellow - ANSI code for bright yellow text (93). * @property {number} blue - ANSI code for bright blue text (94). * @property {number} magenta - ANSI code for bright magenta text (95). * @property {number} cyan - ANSI code for bright cyan text (96). * @property {number} white - ANSI code for bright white text (97). * @memberOf module:@StyledString */ const BrightForegroundColors = { brightBlack: 90, brightRed: 91, brightGreen: 92, brightYellow: 93, brightBlue: 94, brightMagenta: 95, brightCyan: 96, brightWhite: 97, }; /** * @description Standard background color codes for ANSI text formatting. * @summary This object maps color names to their corresponding ANSI color codes for standard background colors. * @const StandardBackgroundColors * @property {number} bgBlack - ANSI code for black background (40). * @property {number} bgRed - ANSI code for red background (41). * @property {number} bgGreen - ANSI code for green background (42). * @property {number} bgYellow - ANSI code for yellow background (43). * @property {number} bgBlue - ANSI code for blue background (44). * @property {number} bgMagenta - ANSI code for magenta background (45). * @property {number} bgCyan - ANSI code for cyan background (46). * @property {number} bgWhite - ANSI code for white background (47). * @memberOf module:@StyledString */ const StandardBackgroundColors = { bgBlack: 40, bgRed: 41, bgGreen: 42, bgYellow: 43, bgBlue: 44, bgMagenta: 45, bgCyan: 46, bgWhite: 47, }; /** * @description Bright background color codes for ANSI text formatting. * @summary This object maps color names to their corresponding ANSI color codes for bright background colors. * @const BrightBackgroundColors * @property {number} bgBrightBlack - ANSI code for bright black background (100). * @property {number} bgBrightRed - ANSI code for bright red background (101). * @property {number} bgBrightGreen - ANSI code for bright green background (102). * @property {number} bgBrightYellow - ANSI code for bright yellow background (103). * @property {number} bgBrightBlue - ANSI code for bright blue background (104). * @property {number} bgBrightMagenta - ANSI code for bright magenta background (105). * @property {number} bgBrightCyan - ANSI code for bright cyan background (106). * @property {number} bgBrightWhite - ANSI code for bright white background (107). * @memberOf module:@StyledString */ const BrightBackgroundColors = { bgBrightBlack: 100, bgBrightRed: 101, bgBrightGreen: 102, bgBrightYellow: 103, bgBrightBlue: 104, bgBrightMagenta: 105, bgBrightCyan: 106, bgBrightWhite: 107, }; /** * @description Text style codes for ANSI text formatting. * @summary This object maps style names to their corresponding ANSI codes for various text styles. * @const styles * @property {number} reset - ANSI code to reset all styles (0). * @property {number} bold - ANSI code for bold text (1). * @property {number} dim - ANSI code for dim text (2). * @property {number} italic - ANSI code for italic text (3). * @property {number} underline - ANSI code for underlined text (4). * @property {number} blink - ANSI code for blinking text (5). * @property {number} inverse - ANSI code for inverse colors (7). * @property {number} hidden - ANSI code for hidden text (8). * @property {number} strikethrough - ANSI code for strikethrough text (9). * @property {number} doubleUnderline - ANSI code for double underlined text (21). * @property {number} normalColor - ANSI code to reset color to normal (22). * @property {number} noItalicOrFraktur - ANSI code to turn off italic (23). * @property {number} noUnderline - ANSI code to turn off underline (24). * @property {number} noBlink - ANSI code to turn off blink (25). * @property {number} noInverse - ANSI code to turn off inverse (27). * @property {number} noHidden - ANSI code to turn off hidden (28). * @property {number} noStrikethrough - ANSI code to turn off strikethrough (29). * @memberOf module:@StyledString */ const styles = { reset: 0, bold: 1, dim: 2, italic: 3, underline: 4, blink: 5, inverse: 7, hidden: 8, strikethrough: 9, doubleUnderline: 21, normalColor: 22, noItalicOrFraktur: 23, noUnderline: 24, noBlink: 25, noInverse: 27, noHidden: 28, noStrikethrough: 29, }; /** * @description Applies a basic ANSI color code to text. * @summary This function takes a string, an ANSI color code number, and an optional background flag. * It returns the text wrapped in the appropriate ANSI escape codes for either foreground or background coloring. * This function is used for basic 16-color ANSI formatting. * * @param {string} text - The text to be colored. * @param {number} n - The ANSI color code number. * @param {boolean} [bg=false] - If true, applies the color to the background instead of the foreground. * @return {string} The text wrapped in ANSI color codes. * * @function colorizeANSI * @memberOf module:@StyledString */ function colorizeANSI(text, n, bg = false) { if (isNaN(n)) { console.warn(`Invalid color number on the ANSI scale: ${n}. ignoring...`); return text; } if (bg && ((n > 30 && n <= 40) || (n > 90 && n <= 100))) { n = n + 10; } return `\x1b[${n}m${text}${AnsiReset}`; } /** * @description Applies a 256-color ANSI code to text. * @summary This function takes a string and a color number (0-255) and returns the text * wrapped in ANSI escape codes for either foreground or background coloring. * * @param {string} text - The text to be colored. * @param {number} n - The color number (0-255). * @param {boolean} [bg=false] - If true, applies the color to the background instead of the foreground. * @return {string} The text wrapped in ANSI color codes. * * @function colorize256 * @memberOf module:@StyledString */ function colorize256(text, n, bg = false) { if (isNaN(n)) { console.warn(`Invalid color number on the 256 scale: ${n}. ignoring...`); return text; } if (n < 0 || n > 255) { console.warn(`Invalid color number on the 256 scale: ${n}. ignoring...`); return text; } return `\x1b[${bg ? 48 : 38};5;${n}m${text}${AnsiReset}`; } /** * @description Applies an RGB color ANSI code to text. * @summary This function takes a string and RGB color values (0-255 for each component) * and returns the text wrapped in ANSI escape codes for either foreground or background coloring. * * @param {string} text - The text to be colored. * @param {number} r - The red component of the color (0-255). * @param {number} g - The green component of the color (0-255). * @param {number} b - The blue component of the color (0-255). * @param {boolean} [bg=false] - If true, applies the color to the background instead of the foreground. * @return {string} The text wrapped in ANSI color codes. * * @function colorizeRGB * @memberOf module:StyledString */ function colorizeRGB(text, r, g, b, bg = false) { if (isNaN(r) || isNaN(g) || isNaN(b)) { console.warn(`Invalid RGB color values: r=${r}, g=${g}, b=${b}. Ignoring...`); return text; } if ([r, g, b].some(v => v < 0 || v > 255)) { console.warn(`Invalid RGB color values: r=${r}, g=${g}, b=${b}. Ignoring...`); return text; } return `\x1b[${bg ? 48 : 38};2;${r};${g};${b}m${text}${AnsiReset}`; } /** * @description Applies an ANSI style code to text. * @summary This function takes a string and a style code (either a number or a key from the styles object) * and returns the text wrapped in the appropriate ANSI escape codes for that style. * * @param {string} text - The text to be styled. * @param {number | string} n - The style code or style name. * @return {string} The text wrapped in ANSI style codes. * * @function applyStyle * @memberOf module:StyledString */ function applyStyle(text, n) { const styleCode = typeof n === "number" ? n : styles[n]; return `\x1b[${styleCode}m${text}${AnsiReset}`; } /** * @description Removes all ANSI formatting codes from text. * @summary This function takes a string that may contain ANSI escape codes for formatting * and returns a new string with all such codes removed, leaving only the plain text content. * It uses a regular expression to match and remove ANSI escape sequences. * * @param {string} text - The text potentially containing ANSI formatting codes. * @return {string} The input text with all ANSI formatting codes removed. * * @function clear * @memberOf module:StyledString */ function clear(text) { // Regular expression to match ANSI escape codes // eslint-disable-next-line no-control-regex const ansiRegex = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g; return text.replace(ansiRegex, ''); } /** * @description Applies raw ANSI escape codes to text. * @summary This function takes a string and a raw ANSI escape code, and returns the text * wrapped in the provided raw ANSI code and the reset code. This allows for applying custom * or complex ANSI formatting that may not be covered by other utility functions. * * @param {string} text - The text to be formatted. * @param {string} raw - The raw ANSI escape code to be applied. * @return {string} The text wrapped in the raw ANSI code and the reset code. * * @function raw * @memberOf module:StyledString */ function raw(text, raw) { return `${raw}${text}${AnsiReset}`; } /** * @class StyledString * @description A class that extends string functionality with ANSI color and style options. * @summary StyledString provides methods to apply various ANSI color and style options to text strings. * It implements the ColorizeOptions interface and proxies native string methods to the underlying text. * This class allows for chaining of styling methods and easy application of colors and styles to text. * * @implements {ColorizeOptions} * @param {string} text - The initial text string to be styled. */ class StyledString { constructor(text) { this.text = text; // Basic colors Object.entries(StandardForegroundColors).forEach(([name, code]) => { Object.defineProperty(this, name, { get: () => this.foreground(code), }); }); Object.entries(BrightForegroundColors).forEach(([name, code]) => { Object.defineProperty(this, name, { get: () => this.foreground(code), }); }); // Background colors Object.entries(StandardBackgroundColors).forEach(([name, code]) => { Object.defineProperty(this, name, { get: () => this.background(code), }); }); Object.entries(BrightBackgroundColors).forEach(([name, code]) => { Object.defineProperty(this, name, { get: () => this.background(code), }); }); // Styles Object.entries(styles).forEach(([name, code]) => { Object.defineProperty(this, name, { get: () => this.style(code), }); }); } /** * @description Clears all styling from the text. * @summary Removes all ANSI color and style codes from the text. * @return {StyledString} The StyledString instance with cleared styling. */ clear() { this.text = clear(this.text); return this; } /** * @description Applies raw ANSI codes to the text. * @summary Allows direct application of ANSI escape sequences to the text. * @param {string} rawAnsi - The raw ANSI escape sequence to apply. * @return {StyledString} The StyledString instance with the raw ANSI code applied. */ raw(rawAnsi) { this.text = raw(this.text, rawAnsi); return this; } /** * @description Applies a foreground color to the text. * @summary Sets the text color using ANSI color codes. * @param {number} n - The ANSI color code for the foreground color. * @return {StyledString} The StyledString instance with the foreground color applied. */ foreground(n) { this.text = colorizeANSI(this.text, n); return this; } /** * @description Applies a background color to the text. * @summary Sets the background color of the text using ANSI color codes. * @param {number} n - The ANSI color code for the background color. * @return {StyledString} The StyledString instance with the background color applied. */ background(n) { this.text = colorizeANSI(this.text, n, true); return this; } /** * @description Applies a text style to the string. * @summary Sets text styles such as bold, italic, or underline using ANSI style codes. * @param {number | string} n - The style code or key from the styles object. * @return {StyledString} The StyledString instance with the style applied. */ style(n) { if (typeof n === "string" && !(n in styles)) { console.warn(`Invalid style: ${n}`); return this; } this.text = applyStyle(this.text, n); return this; } /** * @description Applies a 256-color foreground color to the text. * @summary Sets the text color using the extended 256-color palette. * @param {number} n - The color number from the 256-color palette. * @return {StyledString} The StyledString instance with the 256-color foreground applied. */ color256(n) { this.text = colorize256(this.text, n); return this; } /** * @description Applies a 256-color background color to the text. * @summary Sets the background color using the extended 256-color palette. * @param {number} n - The color number from the 256-color palette. * @return {StyledString} The StyledString instance with the 256-color background applied. */ bgColor256(n) { this.text = colorize256(this.text, n, true); return this; } /** * @description Applies an RGB foreground color to the text. * @summary Sets the text color using RGB values. * @param {number} r - The red component (0-255). * @param {number} g - The green component (0-255). * @param {number} b - The blue component (0-255). * @return {StyledString} The StyledString instance with the RGB foreground color applied. */ rgb(r, g, b) { this.text = colorizeRGB(this.text, r, g, b); return this; } /** * @description Applies an RGB background color to the text. * @summary Sets the background color using RGB values. * @param {number} r - The red component (0-255). * @param {number} g - The green component (0-255). * @param {number} b - The blue component (0-255). * @return {StyledString} The StyledString instance with the RGB background color applied. */ bgRgb(r, g, b) { this.text = colorizeRGB(this.text, r, g, b, true); return this; } /** * @description Converts the StyledString to a regular string. * @summary Returns the underlying text with all applied styling. * @return {string} The styled text as a regular string. */ toString() { return this.text; } } /** * @description Applies styling to a given text string. * @summary This function takes a string and returns a StyledString object, which is an enhanced * version of the original string with additional methods for applying various ANSI color and style * options. It sets up a mapper object with methods for different styling operations and then * defines properties on the text string to make these methods accessible. * * @param {string[]} t The input text to be styled. * @return {StyledString} A StyledString object with additional styling methods. * * @function style * * @memberOf StyledString */ function style(...t) { return new StyledString(t.join(" ")); } exports.AnsiReset = AnsiReset; exports.BrightBackgroundColors = BrightBackgroundColors; exports.BrightForegroundColors = BrightForegroundColors; exports.StandardBackgroundColors = StandardBackgroundColors; exports.StandardForegroundColors = StandardForegroundColors; exports.StyledString = StyledString; exports.applyStyle = applyStyle; exports.clear = clear; exports.colorize256 = colorize256; exports.colorizeANSI = colorizeANSI; exports.colorizeRGB = colorizeRGB; exports.raw = raw; exports.style = style; exports.styles = styles; })); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGVkLXN0cmluZy1idWlsZGVyLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9jb2xvcnMudHMiLCIuLi9zcmMvc3RyaW5ncy50cyJdLCJzb3VyY2VzQ29udGVudCI6W251bGwsbnVsbCxudWxsXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQ0E7Ozs7O0lBS0c7QUFDSSxVQUFNLFNBQVMsR0FBRztJQUV6Qjs7Ozs7Ozs7Ozs7OztJQWFHO0FBQ0ksVUFBTSx3QkFBd0IsR0FBRztJQUN0QyxJQUFBLEtBQUssRUFBRSxFQUFFO0lBQ1QsSUFBQSxHQUFHLEVBQUUsRUFBRTtJQUNQLElBQUEsS0FBSyxFQUFFLEVBQUU7SUFDVCxJQUFBLE1BQU0sRUFBRSxFQUFFO0lBQ1YsSUFBQSxJQUFJLEVBQUUsRUFBRTtJQUNSLElBQUEsT0FBTyxFQUFFLEVBQUU7SUFDWCxJQUFBLElBQUksRUFBRSxFQUFFO0lBQ1IsSUFBQSxLQUFLLEVBQUUsRUFBRTs7SUFHWDs7Ozs7Ozs7Ozs7OztJQWFHO0FBQ0ksVUFBTSxzQkFBc0IsR0FBRztJQUNwQyxJQUFBLFdBQVcsRUFBRSxFQUFFO0lBQ2YsSUFBQSxTQUFTLEVBQUUsRUFBRTtJQUNiLElBQUEsV0FBVyxFQUFFLEVBQUU7SUFDZixJQUFBLFlBQVksRUFBRSxFQUFFO0lBQ2hCLElBQUEsVUFBVSxFQUFFLEVBQUU7SUFDZCxJQUFBLGFBQWEsRUFBRSxFQUFFO0lBQ2pCLElBQUEsVUFBVSxFQUFFLEVBQUU7SUFDZCxJQUFBLFdBQVcsRUFBRSxFQUFFOztJQUdqQjs7Ozs7Ozs7Ozs7OztJQWFHO0FBQ0ksVUFBTSx3QkFBd0IsR0FBRztJQUN0QyxJQUFBLE9BQU8sRUFBRSxFQUFFO0lBQ1gsSUFBQSxLQUFLLEVBQUUsRUFBRTtJQUNULElBQUEsT0FBTyxFQUFFLEVBQUU7SUFDWCxJQUFBLFFBQVEsRUFBRSxFQUFFO0lBQ1osSUFBQSxNQUFNLEVBQUUsRUFBRTtJQUNWLElBQUEsU0FBUyxF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