From af27fed35cb32d1af9c81ec2562109a3dc0a204a Mon Sep 17 00:00:00 2001 From: Vivianne Langdon Date: Sun, 11 Feb 2024 13:02:13 -0500 Subject: [PATCH] Some cleanup of the API pre-documentation --- termenv/color.scm | 165 +++++++++++++++++---------------------------- termenv/screen.scm | 6 +- termenv/style.scm | 30 +++------ termenv/unix.scm | 1 + 4 files changed, 76 insertions(+), 126 deletions(-) diff --git a/termenv/color.scm b/termenv/color.scm index 5e79c5e..478ced5 100644 --- a/termenv/color.scm +++ b/termenv/color.scm @@ -7,61 +7,18 @@ #:use-module (srfi srfi-9 gnu) #:export (make-foreground make-background - current-color-profile color-r color-g color-b color? - color-styled - rgb->hsl - rgb->cie-lab - hex->color - rgb->ansi - rgb->ansi-index - rgb->ansi256 - rgb->ansi256-index - hsl-uv-distance)) -(define current-color-profile (make-parameter #f)) - -(define-immutable-record-type - (make-color r g b type) - color? - (r color-r) - (g color-g) - (b color-b) - (type color-type)) - -(define (make-foreground hex) - "Create a foreground color" - (hex->color hex 'foreground)) - -(define (make-background hex) - "Create a background color" - (hex->color hex 'background)) - -(define %FOREGROUND "38") -(define %BACKGROUND "48") - -(define (color-styled color) - (define type-code - (if (eqv? 'foreground (color-type color)) - %FOREGROUND - %BACKGROUND)) - - ;; if user has parameterized a profile we use that but otherwise we use the profile of the active output port - (define profile - (or (current-color-profile) - (color-profile (current-output-port)))) - - (case profile - ((true-color) - (format #f "~a;2;~a;~a;~a" type-code (color-r color) (color-g color) (color-b color))) - ((ansi256) (format #f "~a;5;~d" type-code (rgb->ansi256-index color))) - ((ansi) (format #f "~d" (rgb->ansi-index color))) - (else ""))) - -;; TODO: probably could do oop goops and be neater + current-color-profile + color->sequence + color->ansi + color->ansi-index + color->ansi256 + color->ansi256-index + hex->color)) (define %ANSI-COLOR-NAMES '(black @@ -339,6 +296,14 @@ "#e4e4e4" "#eeeeee")) +(define-immutable-record-type + (make-color r g b type) + color? + (r color-r) + (g color-g) + (b color-b) + (type color-type)) + (define %ANSI256-COLORS (map hex->color %ANSI256-HEX)) @@ -347,39 +312,43 @@ (define %ANSI-COLORS (map hex->color %ANSI-HEX)) -;; https://stackoverflow.com/a/58426404/826692 -(define (rgb->hsl c) - (define r (/ (color-r c) 255.0)) - (define g (/ (color-g c) 255.0)) - (define b (/ (color-b c) 255.0)) - (define c-min (min r g b)) - (define c-max (max r g b)) - (define delta (- c-max c-min)) - (define h - (round - (* 60.0 - (cond - ((= delta 0.0) 0.0) - ((= c-max r) (floor-remainder (/ (- g b) delta) 6.0)) - (else (+ (/ (- r g) delta) 4.0)))))) - (when (< h 0.0) - (set! h (+ h 360.0))) +(define %FOREGROUND "38") +(define %BACKGROUND "48") - (define l (/ (+ c-max c-min) 2.0)) +;; Parameter determining the color profile to use. Can be one of: 'true-color 'ansi256 'ansi 'ascii +;; If #f, formatting will use the value returned by (color-profile (current-input-port)) +(define current-color-profile (make-parameter #f)) - (define s - (if (= delta 0.0) - 0.0 - (/ delta (- 1.0 (abs (- (* 2.0 l) 1.0)))))) +(define (make-foreground hex) + "Create a foreground color from a hex code" + (hex->color hex 'foreground)) - (set! s (* s 100.0)) - (set! l (* l 100.0)) - (values h s l)) +(define (make-background hex) + "Create a background color from a hex code" + (hex->color hex 'background)) +(define (color->sequence color) + "Function to transform the color into the sequence representing the color. Uses `current-color-profile` or the profile that `current-output-port` supports to determine the sequence to print" + (define type-code + (if (eqv? 'foreground (color-type color)) + %FOREGROUND + %BACKGROUND)) + + ;; if user has parameterized a profile we use that but otherwise we use the profile of the active output port + (define profile + (or (current-color-profile) + (color-profile (current-output-port)))) + + (case profile + ((true-color) + (format #f "~a;2;~a;~a;~a" type-code (color-r color) (color-g color) (color-b color))) + ((ansi256) (format #f "~a;5;~d" type-code (color->ansi256-index color))) + ((ansi) (format #f "~d" (color->ansi-index color))) + (else ""))) ;; http://www.easyrgb.com/en/math.php -(define (rgb->cie-lab c) +(define (color->cie-lab c) (define (modulate x) (if (> x 0.008856) (expt x 1/3) @@ -393,27 +362,15 @@ (* 500 (- x y)) (* 200 (- y z)))) -(define (rgb->delta-e-cie c1 c2) - (define-values (cie-l1 cie-a1 cie-b1) (rgb->cie-lab c1)) - (define-values (cie-l2 cie-a2 cie-b2) (rgb->cie-lab c2)) +(define (delta-e-cie c1 c2) + "Given two colors, determine their E-CIE distance" + (define-values (cie-l1 cie-a1 cie-b1) (color->cie-lab c1)) + (define-values (cie-l2 cie-a2 cie-b2) (color->cie-lab c2)) (sqrt (+ (expt (- cie-l1 cie-l2) 2) (expt (- cie-a1 cie-a2) 2) (expt (- cie-b1 cie-b2) 2)))) - -(define (hsl-uv-distance c1 c2) - "the Euclidean distance in the HSLuv colorspace" - (define (sq x) (* x x)) - (define-values (h1 s1 l1) (rgb->hsl c1)) - (define-values (h2 s2 l2) (rgb->hsl c2)) - - (define dh (/ (min (abs (- h2 h1)) (- 360.0 (abs (- h2 h1)))) 180.0)) - (define ds (abs (- s2 s1))) - (define dv (/ (abs (- l2 l1)) 255.0)) - - (sqrt (+ (sq (/ (- h1 h2) 100.0)) (sq (- s1 s2)) (sq (- l1 l2))))) - (define* (hex->color str #:optional (type 'foreground)) (define trimmed (string-trim str #\#)) (define width (floor (/ (string-length trimmed) 3))) @@ -431,31 +388,31 @@ (locale-string->integer b 16) type)) -(define (rgb->ansi color) +(define (color->ansi color) "Given a full color, convert to the nearest ansi color equivalent" - (rgb->table color %ANSI-COLORS)) + (color->table color %ANSI-COLORS)) -(define (rgb->ansi256 color) +(define (color->ansi256 color) "Given a full color, convert to the nearest ansi256 color equivalent" - (rgb->table color %ANSI256-COLORS)) + (color->table color %ANSI256-COLORS)) -(define (rgb->table color table) - (list-ref (rgb->table-index color table) table)) +(define (color->table color table) + (list-ref (color->table-index color table) table)) -(define (rgb->ansi-index color) +(define (color->ansi-index color) "Given a full color, convert to the index of the nearest ansi color equivalent" - (rgb->table-index color %ANSI-COLORS)) + (color->table-index color %ANSI-COLORS)) -(define (rgb->ansi256-index color) +(define (color->ansi256-index color) "Given a full color, convert to the index of the nearest ansi color equivalent" - (rgb->table-index color %ANSI256-COLORS)) + (color->table-index color %ANSI256-COLORS)) -(define (rgb->table-index color table) +(define (color->table-index color table) (define cur-min #f) (define min-index #f) (fold (λ (val acc) - (let ((min (rgb->delta-e-cie color val))) + (let ((min (delta-e-cie color val))) (unless (and cur-min (> min cur-min)) (set! cur-min min) (set! min-index acc))) diff --git a/termenv/screen.scm b/termenv/screen.scm index 9d6a399..6a724a0 100644 --- a/termenv/screen.scm +++ b/termenv/screen.scm @@ -76,15 +76,15 @@ (define* (set-foreground-color hex #:optional (port #t)) "Sets the default foreground color" - (format port (string-append %OSC %SET-FOREGROUND-COLOR) (color-styled (make-foreground hex)))) + (format port (string-append %OSC %SET-FOREGROUND-COLOR) (color->sequence (make-foreground hex)))) (define* (set-background-color hex #:optional (port #t)) "Sets the default background color" - (format port (string-append %OSC %SET-BACKGROUND-COLOR) (color-styled (make-background hex)))) + (format port (string-append %OSC %SET-BACKGROUND-COLOR) (color->sequence (make-background hex)))) (define* (set-cursor-color hex #:optional (port #t)) "Sets the cursor color" - (format port (string-append %OSC %SET-CURSOR-COLOR) (color-styled (make-foreground hex)))) + (format port (string-append %OSC %SET-CURSOR-COLOR) (color->sequence (make-foreground hex)))) (define* (restore-screen #:optional (port #t)) "Restores a previously saved screen state" diff --git a/termenv/style.scm b/termenv/style.scm index 762fbd3..5e3c32a 100644 --- a/termenv/style.scm +++ b/termenv/style.scm @@ -5,10 +5,7 @@ #:use-module (ice-9 match) #:use-module (srfi srfi-26) #:use-module (srfi srfi-9 gnu) - #:export (make-style - styled - style-sequences - foreground + #:export (foreground background bold faint @@ -17,9 +14,7 @@ overline blink reverse - cross-out - ;; get-width - )) + cross-out)) (define %RESET "0") (define %BOLD "1") @@ -33,7 +28,7 @@ ;; Leaf node of style tree (define-immutable-record-type