@visulima/colorize
Version:
Terminal and Console string styling done right.
204 lines (197 loc) • 8.33 kB
JavaScript
import { isStdoutColorSupported } from '@visulima/is-ansi-color-supported';
import { convertHexToRgb } from './convertHexToRgb-DOIRmKxM.mjs';
import { rgbToAnsi16, rgbToAnsi256, ansi256To16 } from './rgbToAnsi256-DcQVMIqi.mjs';
var __defProp$4 = Object.defineProperty;
var __name$4 = (target, value) => __defProp$4(target, "name", { value, configurable: true });
function ansiRegex({ onlyFirst = false } = {}) {
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
const pattern = [
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"
].join("|");
return new RegExp(pattern, onlyFirst ? void 0 : "g");
}
__name$4(ansiRegex, "ansiRegex");
var __defProp$3 = Object.defineProperty;
var __name$3 = (target, value) => __defProp$3(target, "name", { value, configurable: true });
const clamp = /* @__PURE__ */ __name$3((number_, min, max) => min > number_ ? min : number_ > max ? max : number_, "clamp");
var __defProp$2 = Object.defineProperty;
var __name$2 = (target, value) => __defProp$2(target, "name", { value, configurable: true });
const closeCode = 39;
const bgCloseCode = 49;
const bgOffset = 10;
const supportedColor = isStdoutColorSupported();
const mono = { close: "", open: "" };
const esc = supportedColor > 0 ? (open, close) => {
return { close: "\x1B[" + close + "m", open: "\x1B[" + open + "m" };
} : () => mono;
const createRgbFunction = /* @__PURE__ */ __name$2((function_) => (r, g, b) => function_(rgbToAnsi256(Number(r), Number(g), Number(b))), "createRgbFunction");
const createHexFunction = /* @__PURE__ */ __name$2((function_) => (hex) => {
const [r, g, b] = convertHexToRgb(hex);
return function_(r, g, b);
}, "createHexFunction");
let createAnsi256 = /* @__PURE__ */ __name$2((code) => esc("38;5;" + code, closeCode), "createAnsi256");
let createBgAnsi256 = /* @__PURE__ */ __name$2((code) => esc("48;5;" + code, bgCloseCode), "createBgAnsi256");
let createRgb = /* @__PURE__ */ __name$2((r, g, b) => esc("38;2;" + r + ";" + g + ";" + b, closeCode), "createRgb");
let createBgRgb = /* @__PURE__ */ __name$2((r, g, b) => esc("48;2;" + r + ";" + g + ";" + b, bgCloseCode), "createBgRgb");
if (supportedColor === 1) {
createAnsi256 = /* @__PURE__ */ __name$2((code) => esc(ansi256To16(Number(code)), closeCode), "createAnsi256");
createBgAnsi256 = /* @__PURE__ */ __name$2((code) => esc(ansi256To16(Number(code)) + bgOffset, bgCloseCode), "createBgAnsi256");
createRgb = /* @__PURE__ */ __name$2((r, g, b) => esc(rgbToAnsi16(Number(r), Number(g), Number(b)), closeCode), "createRgb");
createBgRgb = /* @__PURE__ */ __name$2((r, g, b) => esc(rgbToAnsi16(Number(r), Number(g), Number(b)) + bgOffset, bgCloseCode), "createBgRgb");
} else if (supportedColor === 2) {
createRgb = createRgbFunction(createAnsi256);
createBgRgb = createRgbFunction(createBgAnsi256);
}
const baseStyles = {
// 21 isn't widely supported and 22 does the same thing
bold: esc(1, 22),
dim: esc(2, 22),
hidden: esc(8, 28),
inverse: esc(7, 27),
italic: esc(3, 23),
overline: esc(53, 55),
reset: esc(0, 0),
strike: esc(9, 29),
// alias for strikethrough
strikethrough: esc(9, 29),
underline: esc(4, 24),
visible: mono
};
const baseColors = {
bgBlack: esc(40, bgCloseCode),
bgBlackBright: esc(100, bgCloseCode),
bgBlue: esc(44, bgCloseCode),
bgBlueBright: esc(104, bgCloseCode),
bgCyan: esc(46, bgCloseCode),
bgCyanBright: esc(106, bgCloseCode),
bgGray: esc(100, bgCloseCode),
// US spelling alias for bgBlackBright
bgGreen: esc(42, bgCloseCode),
bgGreenBright: esc(102, bgCloseCode),
bgGrey: esc(100, bgCloseCode),
// UK spelling alias for bgBlackBright
bgMagenta: esc(45, bgCloseCode),
bgMagentaBright: esc(105, bgCloseCode),
bgRed: esc(41, bgCloseCode),
bgRedBright: esc(101, bgCloseCode),
bgWhite: esc(47, bgCloseCode),
bgWhiteBright: esc(107, bgCloseCode),
bgYellow: esc(43, bgCloseCode),
bgYellowBright: esc(103, bgCloseCode),
black: esc(30, closeCode),
blackBright: esc(90, closeCode),
blue: esc(34, closeCode),
blueBright: esc(94, closeCode),
cyan: esc(36, closeCode),
cyanBright: esc(96, closeCode),
gray: esc(90, closeCode),
// US spelling alias for blackBright
green: esc(32, closeCode),
greenBright: esc(92, closeCode),
grey: esc(90, closeCode),
// UK spelling alias for blackBright
magenta: esc(35, closeCode),
magentaBright: esc(95, closeCode),
red: esc(31, closeCode),
redBright: esc(91, closeCode),
white: esc(37, closeCode),
whiteBright: esc(97, closeCode),
yellow: esc(33, closeCode),
yellowBright: esc(93, closeCode)
};
const styleMethods = {
bg: /* @__PURE__ */ __name$2((code) => createBgAnsi256(clamp(code, 0, 255)), "bg"),
bgHex: createHexFunction(createBgRgb),
bgRgb: /* @__PURE__ */ __name$2((r, g, b) => createBgRgb(clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255)), "bgRgb"),
fg: /* @__PURE__ */ __name$2((code) => createAnsi256(clamp(code, 0, 255)), "fg"),
hex: createHexFunction(createRgb),
rgb: /* @__PURE__ */ __name$2((r, g, b) => createRgb(clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255)), "rgb")
};
var __defProp$1 = Object.defineProperty;
var __name$1 = (target, value) => __defProp$1(target, "name", { value, configurable: true });
const stringReplaceAll = /* @__PURE__ */ __name$1((string_, searchValue, replaceValue) => {
if (searchValue === "") {
return string_;
}
let pos = string_.indexOf(searchValue);
if (pos < 0) {
return string_;
}
const substringLength = searchValue.length;
let lastPos = 0;
let result = "";
while (~pos) {
result += string_.slice(lastPos, pos) + replaceValue;
lastPos = pos + substringLength;
pos = string_.indexOf(searchValue, lastPos);
}
return result + string_.slice(lastPos);
}, "stringReplaceAll");
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
const styles = {};
let stylePrototype = null;
const wrapText = /* @__PURE__ */ __name((strings, values, properties) => {
if (!strings) {
return "";
}
let string = strings.raw == null ? strings + "" : String.raw(strings, ...values);
if (string.includes("\x1B")) {
for (let currentProperties = properties; currentProperties; currentProperties = currentProperties.props) {
string = stringReplaceAll(string, currentProperties.close, currentProperties.open);
}
}
if (string.includes("\n")) {
string = string.replace(/(\r*\n)/g, properties.closeStack + "$1" + properties.openStack);
}
return properties.openStack + string + properties.closeStack;
}, "wrapText");
const createStyle = /* @__PURE__ */ __name(({ props }, { close, open }) => {
const openStack = (props?.openStack ?? "") + open;
const closeStack = close + (props?.closeStack ?? "");
const style = /* @__PURE__ */ __name((strings, ...values) => wrapText(strings, values, style.props), "style");
Object.setPrototypeOf(style, stylePrototype);
style.props = { close, closeStack, open, openStack, props };
style.open = openStack;
style.close = closeStack;
return style;
}, "createStyle");
const Colorize = /* @__PURE__ */ __name(function() {
const self = /* @__PURE__ */ __name((string_) => string_ + "", "self");
self.strip = (value) => value.replaceAll(ansiRegex(), "");
for (const name in baseColors) {
styles[name] = {
get() {
const style = createStyle(this, baseColors[name]);
Object.defineProperty(this, name, { value: style });
return style;
}
};
}
for (const name in baseStyles) {
styles[name] = {
get() {
const style = createStyle(this, baseStyles[name]);
Object.defineProperty(this, name, { value: style });
return style;
}
};
}
stylePrototype = Object.defineProperties({}, styles);
Object.setPrototypeOf(self, stylePrototype);
return self;
}, "Colorize");
for (const name in styleMethods) {
styles[name] = {
get() {
return (...arguments_) => (
// @ts-expect-error: TODO: fix typing of `arguments_`
createStyle(this, styleMethods[name](...arguments_))
);
}
};
}
styles.ansi256 = styles.fg;
styles.bgAnsi256 = styles.bg;
export { Colorize as C };