UNPKG

3.48 kBJavaScriptView Raw
1'use strict';
2
3const colorize = require('./colorize');
4const colorCodes = require('./colors.json');
5
6const styles = {
7 bold: 1,
8 faint: 2,
9 underline: 4,
10 blink: 5,
11 reverse: 7
12};
13
14function hexToRGB(string) {
15 let red = 255;
16 let green = 255;
17 let blue = 255;
18
19 string = string.replace(/^#/, '');
20
21 if (string.length === 3) {
22 [ red, green, blue ] = string.match(/(\w)/g).
23 map((hex) => {
24 return parseInt(hex.repeat(2), 16);
25 });
26 } else if (string.length === 6) {
27 [ red, green, blue ] = string.match(/(\w\w)/g).
28 map(hex => { return parseInt(hex, 16); });
29 }
30
31 return [ red, green, blue ];
32}
33
34function rgbToAnsi256(red, green, blue) {
35 if (red === green && green === blue) {
36 if (red < 8) {
37 return 16;
38 }
39
40 if (red > 248) {
41 return 231;
42 }
43
44 return Math.round((red - 8) / 247 * 24) + 232;
45 }
46
47 const ansi = 16
48 + 36 * Math.round(red / 255 * 5)
49 + 6 * Math.round(green / 255 * 5)
50 + Math.round(blue / 255 * 5);
51
52 return ansi;
53}
54
55function parseFormatString(string) {
56 const format = {};
57 const items = string.replace(/\s/g, '').split(';');
58 for (const item of items) {
59 const [ key, value ] = item.split(':');
60 format[key] = value;
61 }
62 return format;
63}
64
65function parseColorToCode(color) {
66 if (Array.isArray(color)) {
67 const [ red, green, blue ] = color;
68 return rgbToAnsi256(red, green, blue);
69 } else if (typeof color === 'string') {
70 color = color.toLowerCase();
71 if (color.startsWith('#')) {
72 const [ red, green, blue ] = hexToRGB(color);
73 return rgbToAnsi256(red, green, blue);
74 } else if (colorCodes[color] !== undefined) {
75 return colorCodes[color];
76 } else if (styles[color] !== undefined) {
77 return styles[color];
78 }
79 }
80 return 0;
81}
82
83function style(string, a, b) {
84 if (typeof a === 'string') {
85 if (b === undefined) {
86 if (a.includes(':')) {
87 return style(string, parseFormatString(a));
88 }
89 b = a;
90 a = 'fg';
91 }
92
93 const type = a.toLowerCase();
94 const code = parseColorToCode(b);
95
96 if (type === 'fg' || type === 'foreground') {
97 string = `\u001b[38;5;${ code }m${ string }\u001b[0m`;
98 } else if (type === 'bg' || type === 'background') {
99 string = `\u001b[48;5;${ code }m${ string }\u001b[0m`;
100 } else if (type === 'style' ) {
101 string = `\u001b[${ code }m${ string }\u001b[0m`;
102 } else if (b === undefined) {
103 const styleCode = parseColorToCode(a);
104 string = `\u001b[${ styleCode }m${ string }\u001b[0m`;
105 }
106 } else if (typeof a === 'object') {
107 for (const key in a) {
108 string = style(string, key, a[key]);
109 }
110 }
111
112 string = string.replace(/(\u001b\[0m)+$/, '\u001b[0m');
113 return string;
114}
115
116colorize.rgb = function(color, string) {
117 let red;
118 let green;
119 let blue;
120
121 if (Array.isArray(color)) {
122 [ red, green, blue ] = color;
123 } else {
124 [ red, green, blue ] = hexToRGB(color);
125 }
126
127 const ansi = rgbToAnsi256(red, green, blue);
128
129 return `\u001b[38;5;${ ansi }m${ string }\u001b[0m`;
130};
131
132colorize.frequency = 0.1;
133colorize.seed = Math.floor(Math.random() * 256);
134colorize.spread = 8.0;
135colorize.cycle = function(frequency, i) {
136 const red = Math.round(Math.sin(frequency * i + 0) * 127 + 128);
137 const green = Math.round(Math.sin(frequency * i + 2 * Math.PI / 3) * 127 + 128);
138 const blue = Math.round(Math.sin(frequency * i + 4 * Math.PI / 3) * 127 + 128);
139
140 return [ red, green, blue ];
141};
142
143module.exports = style;