styled-string-builder
Version:
String Styler class based on a builder design pattern
462 lines (456 loc) • 29.5 kB
JavaScript
(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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