UNPKG

@visulima/colorize

Version:

Terminal and Console string styling done right.

267 lines (255 loc) 10.2 kB
'use strict'; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); const isAnsiColorSupported = require('@visulima/is-ansi-color-supported'); var __defProp$6 = Object.defineProperty; var __name$6 = (target, value) => __defProp$6(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$6(ansiRegex, "ansiRegex"); var __defProp$5 = Object.defineProperty; var __name$5 = (target, value) => __defProp$5(target, "name", { value, configurable: true }); const clamp = /* @__PURE__ */ __name$5((number_, min, max) => min > number_ ? min : number_ > max ? max : number_, "clamp"); var __defProp$4 = Object.defineProperty; var __name$4 = (target, value) => __defProp$4(target, "name", { value, configurable: true }); const convertHexToRgb = /* @__PURE__ */ __name$4((hex) => { let [, color] = /([a-f\d]{3,6})/i.exec(hex) ?? []; const length_ = color ? color.length : 0; if (length_ === 3) { color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; } else if (length_ !== 6) { return [0, 0, 0]; } const number_ = Number.parseInt(color, 16); return [number_ >> 16 & 255, number_ >> 8 & 255, number_ & 255]; }, "convertHexToRgb"); var __defProp$3 = Object.defineProperty; var __name$3 = (target, value) => __defProp$3(target, "name", { value, configurable: true }); const rgbToAnsi256 = /* @__PURE__ */ __name$3((r, g, b) => { if (r === g && g === b) { if (r < 8) { return 16; } if (r > 248) { return 231; } return Math.round((r - 8) / 247 * 24) + 232; } return 16 + // r / 255 * 5 => r / 51 36 * Math.round(r / 51) + 6 * Math.round(g / 51) + Math.round(b / 51); }, "rgbToAnsi256"); const ansi256To16 = /* @__PURE__ */ __name$3((code) => { let r; let g; let b; if (code < 8) { return 30 + code; } if (code < 16) { return 90 + (code - 8); } if (code >= 232) { r = g = b = ((code - 232) * 10 + 8) / 255; } else { code -= 16; const remainder = code % 36; r = Math.floor(code / 36) / 5; g = Math.floor(remainder / 6) / 5; b = remainder % 6 / 5; } const value = Math.max(r, g, b) * 2; if (value === 0) { return 30; } const code16 = 30 + (Math.round(b) << 2 | Math.round(g) << 1 | Math.round(r)); return value === 2 ? code16 + 60 : code16; }, "ansi256To16"); const rgbToAnsi16 = /* @__PURE__ */ __name$3((r, g, b) => ansi256To16(rgbToAnsi256(r, g, b)), "rgbToAnsi16"); 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 = isAnsiColorSupported.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$1 = /* @__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; const colorize = new Colorize$1(); const Colorize = Colorize$1; module.exports = colorize; module.exports.Colorize = Colorize;