1 | 'use strict';
|
2 |
|
3 | const colorize = require('./colorize');
|
4 | const colorCodes = require('./data/colors.json');
|
5 |
|
6 | const styles = {
|
7 | bold: 1,
|
8 | faint: 2,
|
9 | underline: 4,
|
10 | blink: 5,
|
11 | reverse: 7,
|
12 | strike: 9,
|
13 | };
|
14 |
|
15 | function 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 |
|
33 | function 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 |
|
54 | function 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 |
|
76 | function 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 |
|
137 | colorize.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 |
|
153 | colorize.frequency = 0.1;
|
154 | colorize.seed = Math.floor(Math.random() * 256);
|
155 | colorize.spread = 8.0;
|
156 | colorize.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 |
|
164 | module.exports = style;
|