summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Lenehan <sunsetkookaburra+git@outlook.com.au>2020-05-09 20:29:44 +1000
committerGitHub <noreply@github.com>2020-05-09 06:29:44 -0400
commit7d3728e3f4b8c9764518bcbe7e4a49cd18fb1f90 (patch)
treeb1cd1f334e14ef188c0c96a4dcc699b7b09fc09a
parent9790399bcea36091da85799c4ed86ead6c9af92a (diff)
feat(std/fmt): 8bit and 24bit ANSI colors (#5168)
-rw-r--r--std/fmt/colors.ts113
-rw-r--r--std/fmt/colors_test.ts38
2 files changed, 124 insertions, 27 deletions
diff --git a/std/fmt/colors.ts b/std/fmt/colors.ts
index ad2a6a1be..64b4458fc 100644
--- a/std/fmt/colors.ts
+++ b/std/fmt/colors.ts
@@ -19,6 +19,13 @@ interface Code {
regexp: RegExp;
}
+/** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */
+interface Rgb {
+ r: number;
+ g: number;
+ b: number;
+}
+
let enabled = !noColor;
export function setColorEnabled(value: boolean): void {
@@ -33,9 +40,9 @@ export function getColorEnabled(): boolean {
return enabled;
}
-function code(open: number, close: number): Code {
+function code(open: number[], close: number): Code {
return {
- open: `\x1b[${open}m`,
+ open: `\x1b[${open.join(";")}m`,
close: `\x1b[${close}m`,
regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
};
@@ -48,101 +55,153 @@ function run(str: string, code: Code): string {
}
export function reset(str: string): string {
- return run(str, code(0, 0));
+ return run(str, code([0], 0));
}
export function bold(str: string): string {
- return run(str, code(1, 22));
+ return run(str, code([1], 22));
}
export function dim(str: string): string {
- return run(str, code(2, 22));
+ return run(str, code([2], 22));
}
export function italic(str: string): string {
- return run(str, code(3, 23));
+ return run(str, code([3], 23));
}
export function underline(str: string): string {
- return run(str, code(4, 24));
+ return run(str, code([4], 24));
}
export function inverse(str: string): string {
- return run(str, code(7, 27));
+ return run(str, code([7], 27));
}
export function hidden(str: string): string {
- return run(str, code(8, 28));
+ return run(str, code([8], 28));
}
export function strikethrough(str: string): string {
- return run(str, code(9, 29));
+ return run(str, code([9], 29));
}
export function black(str: string): string {
- return run(str, code(30, 39));
+ return run(str, code([30], 39));
}
export function red(str: string): string {
- return run(str, code(31, 39));
+ return run(str, code([31], 39));
}
export function green(str: string): string {
- return run(str, code(32, 39));
+ return run(str, code([32], 39));
}
export function yellow(str: string): string {
- return run(str, code(33, 39));
+ return run(str, code([33], 39));
}
export function blue(str: string): string {
- return run(str, code(34, 39));
+ return run(str, code([34], 39));
}
export function magenta(str: string): string {
- return run(str, code(35, 39));
+ return run(str, code([35], 39));
}
export function cyan(str: string): string {
- return run(str, code(36, 39));
+ return run(str, code([36], 39));
}
export function white(str: string): string {
- return run(str, code(37, 39));
+ return run(str, code([37], 39));
}
export function gray(str: string): string {
- return run(str, code(90, 39));
+ return run(str, code([90], 39));
}
export function bgBlack(str: string): string {
- return run(str, code(40, 49));
+ return run(str, code([40], 49));
}
export function bgRed(str: string): string {
- return run(str, code(41, 49));
+ return run(str, code([41], 49));
}
export function bgGreen(str: string): string {
- return run(str, code(42, 49));
+ return run(str, code([42], 49));
}
export function bgYellow(str: string): string {
- return run(str, code(43, 49));
+ return run(str, code([43], 49));
}
export function bgBlue(str: string): string {
- return run(str, code(44, 49));
+ return run(str, code([44], 49));
}
export function bgMagenta(str: string): string {
- return run(str, code(45, 49));
+ return run(str, code([45], 49));
}
export function bgCyan(str: string): string {
- return run(str, code(46, 49));
+ return run(str, code([46], 49));
}
export function bgWhite(str: string): string {
- return run(str, code(47, 49));
+ return run(str, code([47], 49));
+}
+
+/* Special Color Sequences */
+
+function clampAndTruncate(n: number, max = 255, min = 0): number {
+ return Math.trunc(Math.max(Math.min(n, max), min));
+}
+
+/** Set text color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit */
+export function rgb8(str: string, color: number): string {
+ return run(str, code([38, 5, clampAndTruncate(color)], 39));
+}
+
+/** Set background color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit */
+export function bgRgb8(str: string, color: number): string {
+ return run(str, code([48, 5, clampAndTruncate(color)], 49));
+}
+
+/** Set text color using 24bit rgb. */
+export function rgb24(str: string, color: Rgb): string {
+ return run(
+ str,
+ code(
+ [
+ 38,
+ 2,
+ clampAndTruncate(color.r),
+ clampAndTruncate(color.g),
+ clampAndTruncate(color.b),
+ ],
+ 39
+ )
+ );
+}
+
+/** Set background color using 24bit rgb. */
+export function bgRgb24(str: string, color: Rgb): string {
+ return run(
+ str,
+ code(
+ [
+ 48,
+ 2,
+ clampAndTruncate(color.r),
+ clampAndTruncate(color.g),
+ clampAndTruncate(color.b),
+ ],
+ 49
+ )
+ );
}
diff --git a/std/fmt/colors_test.ts b/std/fmt/colors_test.ts
index 6c80b4109..cfa189d30 100644
--- a/std/fmt/colors_test.ts
+++ b/std/fmt/colors_test.ts
@@ -118,3 +118,41 @@ Deno.test("testBgCyan", function (): void {
Deno.test("testBgWhite", function (): void {
assertEquals(c.bgWhite("foo bar"), "foo bar");
});
+
+Deno.test("testClampUsingRgb8", function (): void {
+ assertEquals(c.rgb8("foo bar", -10), "foo bar");
+});
+
+Deno.test("testTruncateUsingRgb8", function (): void {
+ assertEquals(c.rgb8("foo bar", 42.5), "foo bar");
+});
+
+Deno.test("testRgb8", function (): void {
+ assertEquals(c.rgb8("foo bar", 42), "foo bar");
+});
+
+Deno.test("test_bgRgb8", function (): void {
+ assertEquals(c.bgRgb8("foo bar", 42), "foo bar");
+});
+
+Deno.test("test_rgb24", function (): void {
+ assertEquals(
+ c.rgb24("foo bar", {
+ r: 41,
+ g: 42,
+ b: 43,
+ }),
+ "foo bar"
+ );
+});
+
+Deno.test("test_bgRgb24", function (): void {
+ assertEquals(
+ c.bgRgb24("foo bar", {
+ r: 41,
+ g: 42,
+ b: 43,
+ }),
+ "foo bar"
+ );
+});