UNPKG

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