blob: c0ff978223496494550cb12bf58cfb168e22faa8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
{-# LANGUAGE OverloadedStrings #-}
module Erebos.TextFormat.Ansi (
FormattedText,
AnsiText(..),
renderAnsiText,
) where
import Control.Applicative
import Data.String
import Data.Text (Text)
import Data.Text qualified as T
import Erebos.TextFormat.Types
newtype AnsiText = AnsiText { fromAnsiText :: Text }
deriving (Eq, Ord, Semigroup, Monoid, IsString)
renderAnsiText :: FormattedText -> AnsiText
renderAnsiText = AnsiText . go ( Nothing, Nothing )
where
go cur@( cfg, cbg ) = \case
PlainText text -> text
ConcatenatedText ftexts -> mconcat $ map (go cur) ftexts
FormattedText (CustomTextColor fg bg) ftext -> mconcat
[ ansiColor fg bg
, go ( fg <|> cfg, bg <|> cbg ) ftext
, ansiColor
(if fg /= cfg then cfg <|> Just DefaultColor else Nothing)
(if bg /= cbg then cbg <|> Just DefaultColor else Nothing)
]
ansiColor :: Maybe Color -> Maybe Color -> Text
ansiColor Nothing Nothing = ""
ansiColor (Just fg) Nothing = "\ESC[" <> T.pack (show (colorNum fg)) <> "m"
ansiColor Nothing (Just bg) = "\ESC[" <> T.pack (show (colorNum bg + 10)) <> "m"
ansiColor (Just fg) (Just bg) = "\ESC[" <> T.pack (show (colorNum fg)) <> ";" <> T.pack (show (colorNum bg + 10)) <> "m"
colorNum :: Color -> Int
colorNum = \case
DefaultColor -> 39
Black -> 30
Red -> 31
Green -> 32
Yellow -> 33
Blue -> 34
Magenta -> 35
Cyan -> 36
White -> 37
BrightBlack -> 90
BrightRed -> 91
BrightGreen -> 92
BrightYellow -> 93
BrightBlue -> 94
BrightMagenta -> 95
BrightCyan -> 96
BrightWhite -> 97
|