From 4e1d9f39061a92d239d40dc26b5af40a0ada0b07 Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Sun, 1 Jun 2025 19:25:57 +0200 Subject: [PATCH 1/4] color show --- src/Data/Hashable/Color.hs | 63 ++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/Data/Hashable/Color.hs b/src/Data/Hashable/Color.hs index 9650bd7..94039fa 100644 --- a/src/Data/Hashable/Color.hs +++ b/src/Data/Hashable/Color.hs @@ -12,17 +12,49 @@ -- each of the items a different color based on the hash. -- -- This module provides a function 'rgbHash' that can convert any 'Hashable' object to a 'Colour'. -module Data.Hashable.Color (rgbHash) where +module Data.Hashable.Color ( + -- * Determine color + rgbHash + -- * Show items with color + , rgbHashBgShow, rgbHashFgShow + ) where -import Data.Bits (shiftR, (.&.)) +import Data.Bits (shiftR, xor, (.&.)) import Data.Colour (Colour) import Data.Colour.SRGB (sRGB24) import Data.Hashable (Hashable (hash)) import Data.Word (Word8) +type Col8 = (Word8, Word8, Word8) + _word8 :: Int -> Word8 _word8 = toEnum . (255 .&.) +_scramble :: Int -> Int +_scramble x = ((shiftR x 16) `xor` x) * 0x45d9f3b; + +_rgbHash :: Hashable a => a -> Col8 +_rgbHash x = (r, g, b) + where + h = _scramble (_scramble (hash x)) + b = _word8 h + g = _word8 (shiftR h 8) + r = _word8 (shiftR h 16) + +_ansiSeq :: Int -> Col8 -> String -> String +_ansiSeq md ~(r, g, b) = (("\027[" ++ show md ++ ";2;" ++ show r ++ ";" ++ show g ++ ";" ++ show b ++ "m") ++) + +_ansiSeqBg :: Col8 -> String -> String +_ansiSeqBg = _ansiSeq 48 + +_ansiSeqFg :: Col8 -> String -> String +_ansiSeqFg = _ansiSeq 38 + +_altColor :: Col8 -> Col8 +_altColor ~(r, g, b) + | 1063 * fromEnum r + 3576 * fromEnum g + 361 * fromEnum b <= 200000 = (255, 255, 255) + | otherwise = (0, 0, 0) + -- | Convert a given 'Hashable' object to a 'Colour' by determining the hash, and using the last 24 bits as source for the red, green, and blue channels of the 'Colour' to construct. rgbHash :: (Hashable a, Floating b, Ord b) => @@ -32,7 +64,26 @@ rgbHash :: Colour b rgbHash x = sRGB24 r g b where - h = hash x - b = _word8 h - g = _word8 (shiftR h 8) - r = _word8 (shiftR h 16) + ~(r, g, b) = _rgbHash x + +-- | Show the given 'Hashable' object with ANSI terminal codes such that the background is colorized by the hash of that object. This will only work if the terminal supports [24-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit). The foreground is either black or white depending on whether the color is more light or dark. +rgbHashBgShow :: (Hashable a, Show a) => + -- | The 'Hashable' object to print in a colorized way. + a -> + -- | A String with ANSI terminal codes to colorize the object + String +rgbHashBgShow x = _ansiSeqBg c (_ansiSeqFg ca (showsPrec 0 x "\027[0m")) + where + c = _rgbHash x + ca = _altColor c + +-- | Show the given 'Hashable' object with ANSI terminal codes such that the foreground is colorized by the hash of that object. This will only work if the terminal supports [24-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit). The background is either black or white depending on whether the color is more light or dark. +rgbHashFgShow :: (Hashable a, Show a) => + -- | The 'Hashable' object to print in a colorized way. + a -> + -- | A String with ANSI terminal codes to colorize the object + String +rgbHashFgShow x = _ansiSeqFg c (_ansiSeqBg ca (showsPrec 0 x "\027[0m")) + where + c = _rgbHash x + ca = _altColor c From 6bd9b072ee1b79d365f87fdf6cff9022245e3eee Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Sun, 1 Jun 2025 19:26:05 +0200 Subject: [PATCH 2/4] ormolu --- src/Data/Hashable/Color.hs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Data/Hashable/Color.hs b/src/Data/Hashable/Color.hs index 94039fa..45dfe0e 100644 --- a/src/Data/Hashable/Color.hs +++ b/src/Data/Hashable/Color.hs @@ -12,12 +12,15 @@ -- each of the items a different color based on the hash. -- -- This module provides a function 'rgbHash' that can convert any 'Hashable' object to a 'Colour'. -module Data.Hashable.Color ( - -- * Determine color - rgbHash - -- * Show items with color - , rgbHashBgShow, rgbHashFgShow - ) where +module Data.Hashable.Color + ( -- * Determine color + rgbHash, + + -- * Show items with color + rgbHashBgShow, + rgbHashFgShow, + ) +where import Data.Bits (shiftR, xor, (.&.)) import Data.Colour (Colour) @@ -31,9 +34,9 @@ _word8 :: Int -> Word8 _word8 = toEnum . (255 .&.) _scramble :: Int -> Int -_scramble x = ((shiftR x 16) `xor` x) * 0x45d9f3b; +_scramble x = ((shiftR x 16) `xor` x) * 0x45d9f3b -_rgbHash :: Hashable a => a -> Col8 +_rgbHash :: (Hashable a) => a -> Col8 _rgbHash x = (r, g, b) where h = _scramble (_scramble (hash x)) @@ -67,7 +70,8 @@ rgbHash x = sRGB24 r g b ~(r, g, b) = _rgbHash x -- | Show the given 'Hashable' object with ANSI terminal codes such that the background is colorized by the hash of that object. This will only work if the terminal supports [24-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit). The foreground is either black or white depending on whether the color is more light or dark. -rgbHashBgShow :: (Hashable a, Show a) => +rgbHashBgShow :: + (Hashable a, Show a) => -- | The 'Hashable' object to print in a colorized way. a -> -- | A String with ANSI terminal codes to colorize the object @@ -78,7 +82,8 @@ rgbHashBgShow x = _ansiSeqBg c (_ansiSeqFg ca (showsPrec 0 x "\027[0m")) ca = _altColor c -- | Show the given 'Hashable' object with ANSI terminal codes such that the foreground is colorized by the hash of that object. This will only work if the terminal supports [24-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit). The background is either black or white depending on whether the color is more light or dark. -rgbHashFgShow :: (Hashable a, Show a) => +rgbHashFgShow :: + (Hashable a, Show a) => -- | The 'Hashable' object to print in a colorized way. a -> -- | A String with ANSI terminal codes to colorize the object From 2b1c0fe6d81a7cc6ee5a0263752c53472f1c4169 Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Sun, 1 Jun 2025 19:26:37 +0200 Subject: [PATCH 3/4] version bump --- colorhash.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colorhash.cabal b/colorhash.cabal index 74e905e..8af8da7 100644 --- a/colorhash.cabal +++ b/colorhash.cabal @@ -1,7 +1,7 @@ cabal-version: 2.2 name: colorhash -version: 0.1.0.0 +version: 0.2.0.0 synopsis: Generate a color for a hashable object. -- description: homepage: https://github.com/hapytex/colorhash#readme From 33aef8226a20ad1f3f84e654d54e5c7a9f94ce8a Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Sun, 1 Jun 2025 19:28:24 +0200 Subject: [PATCH 4/4] hlint --- src/Data/Hashable/Color.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Data/Hashable/Color.hs b/src/Data/Hashable/Color.hs index 45dfe0e..0ca68fa 100644 --- a/src/Data/Hashable/Color.hs +++ b/src/Data/Hashable/Color.hs @@ -34,7 +34,7 @@ _word8 :: Int -> Word8 _word8 = toEnum . (255 .&.) _scramble :: Int -> Int -_scramble x = ((shiftR x 16) `xor` x) * 0x45d9f3b +_scramble x = (shiftR x 16 `xor` x) * 0x45d9f3b _rgbHash :: (Hashable a) => a -> Col8 _rgbHash x = (r, g, b) @@ -76,7 +76,7 @@ rgbHashBgShow :: a -> -- | A String with ANSI terminal codes to colorize the object String -rgbHashBgShow x = _ansiSeqBg c (_ansiSeqFg ca (showsPrec 0 x "\027[0m")) +rgbHashBgShow x = _ansiSeqBg c (_ansiSeqFg ca (shows x "\027[0m")) where c = _rgbHash x ca = _altColor c @@ -88,7 +88,7 @@ rgbHashFgShow :: a -> -- | A String with ANSI terminal codes to colorize the object String -rgbHashFgShow x = _ansiSeqFg c (_ansiSeqBg ca (showsPrec 0 x "\027[0m")) +rgbHashFgShow x = _ansiSeqFg c (_ansiSeqBg ca (shows x "\027[0m")) where c = _rgbHash x ca = _altColor c