text-ansi-0.3.0.1/0000755000000000000000000000000007346545000011756 5ustar0000000000000000text-ansi-0.3.0.1/CHANGELOG.md0000644000000000000000000000252607346545000013574 0ustar0000000000000000## [0.3.0.1] - 2023-10-12 - Fix broken links to ECMA-48 standard ## [0.3.0] - 2023-09-24 - Switch the underlying text builder from `text-builder` to `text-builder-linear`. This also affects the API provided by `Text.Builder.ANSI`; users that were relying on the `Buidler` type from `text-builder` specificially are encouraged to simply use older versions of this package until they are able to update their own code to use `text-builder-linear` instead. The motivation for this change is performance and encoraging the ecosystem to move in the right direction. See the `text-builder-linear` project for more details. In a nutshell, it is the superior builder type ;) ## [0.2.1.1] - 2023-05-11 - [#6](https://github.com/awkward-squad/text-ansi/pull/6) Fix Windows linker errors on GHC 9.4.5+ ## [0.2.1] - 2022-11-05 - Add `String.ANSI` module ## [0.2.0] - 2022-10-28 - Drop the `Data` prefix from `Data.Text.ANSI` and `Data.Text.Builder.ANSI` modules - Rename `Text.Builder.ANSI` to `Text.Lazy.Builder.ANSI` - Add `Text.Builder.ANSI` back, but based on `text-builder`'s builder instead of `text`'s builder ## [0.1.1] - 2021-01-07 - Add `Data.Text.Builder.ANSI` module ## [0.1.0.2] - 2020-12-26 - Fix bug in `italic` ## [0.1.0.1] - 2020-06-14 - Relax `base` bounds - Drop `text-builder` dependency ## [0.1.0] - 2018-11-14 - Initial release text-ansi-0.3.0.1/LICENSE0000644000000000000000000000267007346545000012770 0ustar0000000000000000Copyright 2018-2022 Mitchell Rosen Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. text-ansi-0.3.0.1/README.md0000644000000000000000000000114407346545000013235 0ustar0000000000000000[![GitHub CI](https://github.com/awkward-squad/text-ansi/workflows/Haskell-CI/badge.svg)](https://github.com/awkward-squad/text-ansi/actions) [![Hackage](https://img.shields.io/hackage/v/text-ansi.svg)](https://hackage.haskell.org/package/text-ansi) [![Stackage LTS](https://stackage.org/package/text-ansi/badge/lts)](https://www.stackage.org/lts/package/text-ansi) [![Stackage Nightly](https://stackage.org/package/text-ansi/badge/nightly)](https://www.stackage.org/nightly/package/text-ansi) [![Dependencies](https://img.shields.io/hackage-deps/v/text-ansi)](https://packdeps.haskellers.com/reverse/text-ansi) text-ansi-0.3.0.1/src/String/0000755000000000000000000000000007346545000014013 5ustar0000000000000000text-ansi-0.3.0.1/src/String/ANSI.hs0000644000000000000000000001607207346545000015107 0ustar0000000000000000module String.ANSI ( -- $intro -- * Foreground color black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, rgb, -- * Background color blackBg, redBg, greenBg, yellowBg, blueBg, magentaBg, cyanBg, whiteBg, brightBlackBg, brightRedBg, brightGreenBg, brightYellowBg, brightBlueBg, brightMagentaBg, brightCyanBg, brightWhiteBg, rgbBg, -- * Style bold, faint, italic, underline, doubleUnderline, strikethrough, frame, encircle, overline, ) where import qualified Data.Text as Text import Data.Text.Builder.Linear (Builder) import qualified Data.Text.Builder.Linear as Builder import Data.Word (Word8) import qualified Text.Builder.ANSI as Builder.ANSI -- $intro -- -- Text styling for ANSI terminals using SGR codes, as defined by the -- -- standard. -- -- Supports foreground\/background color, bold\/faint intensity, italic, -- single\/double underline, strikethrough, frame, encircle, and overline escape -- sequences. Some styles may not work on your terminal. -- -- Also features terminal detection, so redirecting styled output to a file will -- automatically strip the ANSI escape sequences. -- | Black foreground. black :: String -> String black = lift Builder.ANSI.black {-# INLINE black #-} -- | Red foreground. red :: String -> String red = lift Builder.ANSI.red {-# INLINE red #-} -- | Green foreground. green :: String -> String green = lift Builder.ANSI.green {-# INLINE green #-} -- | Yellow foreground. yellow :: String -> String yellow = lift Builder.ANSI.yellow {-# INLINE yellow #-} -- | Blue foreground. blue :: String -> String blue = lift Builder.ANSI.blue {-# INLINE blue #-} -- | Magenta foreground. magenta :: String -> String magenta = lift Builder.ANSI.magenta {-# INLINE magenta #-} -- | Cyan foreground. cyan :: String -> String cyan = lift Builder.ANSI.cyan {-# INLINE cyan #-} -- | White foreground. white :: String -> String white = lift Builder.ANSI.white {-# INLINE white #-} -- | Bright black foreground. brightBlack :: String -> String brightBlack = lift Builder.ANSI.brightBlack {-# INLINE brightBlack #-} -- | Bright red foreground. brightRed :: String -> String brightRed = lift Builder.ANSI.brightRed {-# INLINE brightRed #-} -- | Bright green foreground. brightGreen :: String -> String brightGreen = lift Builder.ANSI.brightGreen {-# INLINE brightGreen #-} -- | Bright yellow foreground. brightYellow :: String -> String brightYellow = lift Builder.ANSI.brightYellow {-# INLINE brightYellow #-} -- | Bright blue foreground. brightBlue :: String -> String brightBlue = lift Builder.ANSI.brightBlue {-# INLINE brightBlue #-} -- | Bright magenta foreground. brightMagenta :: String -> String brightMagenta = lift Builder.ANSI.brightMagenta {-# INLINE brightMagenta #-} -- | Bright cyan foreground. brightCyan :: String -> String brightCyan = lift Builder.ANSI.brightCyan {-# INLINE brightCyan #-} -- | Bright white foreground. brightWhite :: String -> String brightWhite = lift Builder.ANSI.brightWhite {-# INLINE brightWhite #-} -- | RGB foreground. rgb :: Word8 -> Word8 -> Word8 -> String -> String rgb r g b = lift (Builder.ANSI.rgb r g b) {-# INLINE rgb #-} -- | Black background. blackBg :: String -> String blackBg = lift Builder.ANSI.blackBg {-# INLINE blackBg #-} -- | Red background. redBg :: String -> String redBg = lift Builder.ANSI.redBg {-# INLINE redBg #-} -- | Green background. greenBg :: String -> String greenBg = lift Builder.ANSI.greenBg {-# INLINE greenBg #-} -- | Yellow background. yellowBg :: String -> String yellowBg = lift Builder.ANSI.yellowBg {-# INLINE yellowBg #-} -- | Blue background. blueBg :: String -> String blueBg = lift Builder.ANSI.blueBg {-# INLINE blueBg #-} -- | Magenta background. magentaBg :: String -> String magentaBg = lift Builder.ANSI.magentaBg {-# INLINE magentaBg #-} -- | Cyan background. cyanBg :: String -> String cyanBg = lift Builder.ANSI.cyanBg {-# INLINE cyanBg #-} -- | White background. whiteBg :: String -> String whiteBg = lift Builder.ANSI.whiteBg {-# INLINE whiteBg #-} -- | Bright black background. brightBlackBg :: String -> String brightBlackBg = lift Builder.ANSI.brightBlackBg {-# INLINE brightBlackBg #-} -- | Bright red background. brightRedBg :: String -> String brightRedBg = lift Builder.ANSI.brightRedBg {-# INLINE brightRedBg #-} -- | Bright green background. brightGreenBg :: String -> String brightGreenBg = lift Builder.ANSI.brightGreenBg {-# INLINE brightGreenBg #-} -- | Bright yellow background. brightYellowBg :: String -> String brightYellowBg = lift Builder.ANSI.brightYellowBg {-# INLINE brightYellowBg #-} -- | Bright blue background. brightBlueBg :: String -> String brightBlueBg = lift Builder.ANSI.brightBlueBg {-# INLINE brightBlueBg #-} -- | Bright magenta background. brightMagentaBg :: String -> String brightMagentaBg = lift Builder.ANSI.brightMagentaBg {-# INLINE brightMagentaBg #-} -- | Bright cyan background. brightCyanBg :: String -> String brightCyanBg = lift Builder.ANSI.brightCyanBg {-# INLINE brightCyanBg #-} -- | Bright white background. brightWhiteBg :: String -> String brightWhiteBg = lift Builder.ANSI.brightWhiteBg {-# INLINE brightWhiteBg #-} -- | RGB background. rgbBg :: Word8 -> Word8 -> Word8 -> String -> String rgbBg r g b = lift (Builder.ANSI.rgbBg r g b) {-# INLINE rgbBg #-} -- | __Bold__ style (high intensity). bold :: String -> String bold = lift Builder.ANSI.bold {-# INLINE bold #-} -- | Faint style (low intensity). faint :: String -> String faint = lift Builder.ANSI.faint {-# INLINE faint #-} -- | /Italic/ style. italic :: String -> String italic = lift Builder.ANSI.italic {-# INLINE italic #-} -- | U̲n̲d̲e̲r̲l̲i̲n̲e̲ style. underline :: String -> String underline = lift Builder.ANSI.underline {-# INLINE underline #-} -- | D̳o̳u̳b̳l̳e̳ ̳u̳n̳d̳e̳r̳l̳i̳n̳e̳ style. doubleUnderline :: String -> String doubleUnderline = lift Builder.ANSI.doubleUnderline {-# INLINE doubleUnderline #-} -- | S̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h̶ style. strikethrough :: String -> String strikethrough = lift Builder.ANSI.strikethrough {-# INLINE strikethrough #-} -- | Frame style. frame :: String -> String frame = lift Builder.ANSI.frame {-# INLINE frame #-} -- | Encircle style. encircle :: String -> String encircle = lift Builder.ANSI.encircle {-# INLINE encircle #-} -- | O̅v̅e̅r̅l̅i̅n̅e̅ style. overline :: String -> String overline = lift Builder.ANSI.overline {-# INLINE overline #-} -- lift :: (Builder -> Builder) -> String -> String lift f = Text.unpack . Builder.runBuilder . f . foldMap Builder.fromChar -- Don't inline before phase 2 {-# NOINLINE [2] lift #-} -- Collapse lift/lift to a single lift before phase 2 {-# RULES "lift/lift" [~2] forall f g s. lift f (lift g s) = lift (f . g) s #-} text-ansi-0.3.0.1/src/Text/0000755000000000000000000000000007346545000013471 5ustar0000000000000000text-ansi-0.3.0.1/src/Text/ANSI.hs0000644000000000000000000001554707346545000014573 0ustar0000000000000000module Text.ANSI ( -- $intro -- * Foreground color black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, rgb, -- * Background color blackBg, redBg, greenBg, yellowBg, blueBg, magentaBg, cyanBg, whiteBg, brightBlackBg, brightRedBg, brightGreenBg, brightYellowBg, brightBlueBg, brightMagentaBg, brightCyanBg, brightWhiteBg, rgbBg, -- * Style bold, faint, italic, underline, doubleUnderline, strikethrough, frame, encircle, overline, ) where import Data.Text (Text) import Data.Text.Builder.Linear (Builder) import qualified Data.Text.Builder.Linear as Builder import Data.Word (Word8) import qualified Text.Builder.ANSI as Builder.ANSI -- $intro -- -- Text styling for ANSI terminals using SGR codes, as defined by the -- -- standard. -- -- Supports foreground\/background color, bold\/faint intensity, italic, -- single\/double underline, strikethrough, frame, encircle, and overline escape -- sequences. Some styles may not work on your terminal. -- -- Also features terminal detection, so redirecting styled output to a file will -- automatically strip the ANSI escape sequences. -- | Black foreground. black :: Text -> Text black = lift Builder.ANSI.black {-# INLINE black #-} -- | Red foreground. red :: Text -> Text red = lift Builder.ANSI.red {-# INLINE red #-} -- | Green foreground. green :: Text -> Text green = lift Builder.ANSI.green {-# INLINE green #-} -- | Yellow foreground. yellow :: Text -> Text yellow = lift Builder.ANSI.yellow {-# INLINE yellow #-} -- | Blue foreground. blue :: Text -> Text blue = lift Builder.ANSI.blue {-# INLINE blue #-} -- | Magenta foreground. magenta :: Text -> Text magenta = lift Builder.ANSI.magenta {-# INLINE magenta #-} -- | Cyan foreground. cyan :: Text -> Text cyan = lift Builder.ANSI.cyan {-# INLINE cyan #-} -- | White foreground. white :: Text -> Text white = lift Builder.ANSI.white {-# INLINE white #-} -- | Bright black foreground. brightBlack :: Text -> Text brightBlack = lift Builder.ANSI.brightBlack {-# INLINE brightBlack #-} -- | Bright red foreground. brightRed :: Text -> Text brightRed = lift Builder.ANSI.brightRed {-# INLINE brightRed #-} -- | Bright green foreground. brightGreen :: Text -> Text brightGreen = lift Builder.ANSI.brightGreen {-# INLINE brightGreen #-} -- | Bright yellow foreground. brightYellow :: Text -> Text brightYellow = lift Builder.ANSI.brightYellow {-# INLINE brightYellow #-} -- | Bright blue foreground. brightBlue :: Text -> Text brightBlue = lift Builder.ANSI.brightBlue {-# INLINE brightBlue #-} -- | Bright magenta foreground. brightMagenta :: Text -> Text brightMagenta = lift Builder.ANSI.brightMagenta {-# INLINE brightMagenta #-} -- | Bright cyan foreground. brightCyan :: Text -> Text brightCyan = lift Builder.ANSI.brightCyan {-# INLINE brightCyan #-} -- | Bright white foreground. brightWhite :: Text -> Text brightWhite = lift Builder.ANSI.brightWhite {-# INLINE brightWhite #-} -- | RGB foreground. rgb :: Word8 -> Word8 -> Word8 -> Text -> Text rgb r g b = lift (Builder.ANSI.rgb r g b) {-# INLINE rgb #-} -- | Black background. blackBg :: Text -> Text blackBg = lift Builder.ANSI.blackBg {-# INLINE blackBg #-} -- | Red background. redBg :: Text -> Text redBg = lift Builder.ANSI.redBg {-# INLINE redBg #-} -- | Green background. greenBg :: Text -> Text greenBg = lift Builder.ANSI.greenBg {-# INLINE greenBg #-} -- | Yellow background. yellowBg :: Text -> Text yellowBg = lift Builder.ANSI.yellowBg {-# INLINE yellowBg #-} -- | Blue background. blueBg :: Text -> Text blueBg = lift Builder.ANSI.blueBg {-# INLINE blueBg #-} -- | Magenta background. magentaBg :: Text -> Text magentaBg = lift Builder.ANSI.magentaBg {-# INLINE magentaBg #-} -- | Cyan background. cyanBg :: Text -> Text cyanBg = lift Builder.ANSI.cyanBg {-# INLINE cyanBg #-} -- | White background. whiteBg :: Text -> Text whiteBg = lift Builder.ANSI.whiteBg {-# INLINE whiteBg #-} -- | Bright black background. brightBlackBg :: Text -> Text brightBlackBg = lift Builder.ANSI.brightBlackBg {-# INLINE brightBlackBg #-} -- | Bright red background. brightRedBg :: Text -> Text brightRedBg = lift Builder.ANSI.brightRedBg {-# INLINE brightRedBg #-} -- | Bright green background. brightGreenBg :: Text -> Text brightGreenBg = lift Builder.ANSI.brightGreenBg {-# INLINE brightGreenBg #-} -- | Bright yellow background. brightYellowBg :: Text -> Text brightYellowBg = lift Builder.ANSI.brightYellowBg {-# INLINE brightYellowBg #-} -- | Bright blue background. brightBlueBg :: Text -> Text brightBlueBg = lift Builder.ANSI.brightBlueBg {-# INLINE brightBlueBg #-} -- | Bright magenta background. brightMagentaBg :: Text -> Text brightMagentaBg = lift Builder.ANSI.brightMagentaBg {-# INLINE brightMagentaBg #-} -- | Bright cyan background. brightCyanBg :: Text -> Text brightCyanBg = lift Builder.ANSI.brightCyanBg {-# INLINE brightCyanBg #-} -- | Bright white background. brightWhiteBg :: Text -> Text brightWhiteBg = lift Builder.ANSI.brightWhiteBg {-# INLINE brightWhiteBg #-} -- | RGB background. rgbBg :: Word8 -> Word8 -> Word8 -> Text -> Text rgbBg r g b = lift (Builder.ANSI.rgbBg r g b) {-# INLINE rgbBg #-} -- | __Bold__ style (high intensity). bold :: Text -> Text bold = lift Builder.ANSI.bold {-# INLINE bold #-} -- | Faint style (low intensity). faint :: Text -> Text faint = lift Builder.ANSI.faint {-# INLINE faint #-} -- | /Italic/ style. italic :: Text -> Text italic = lift Builder.ANSI.italic {-# INLINE italic #-} -- | U̲n̲d̲e̲r̲l̲i̲n̲e̲ style. underline :: Text -> Text underline = lift Builder.ANSI.underline {-# INLINE underline #-} -- | D̳o̳u̳b̳l̳e̳ ̳u̳n̳d̳e̳r̳l̳i̳n̳e̳ style. doubleUnderline :: Text -> Text doubleUnderline = lift Builder.ANSI.doubleUnderline {-# INLINE doubleUnderline #-} -- | S̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h̶ style. strikethrough :: Text -> Text strikethrough = lift Builder.ANSI.strikethrough {-# INLINE strikethrough #-} -- | Frame style. frame :: Text -> Text frame = lift Builder.ANSI.frame {-# INLINE frame #-} -- | Encircle style. encircle :: Text -> Text encircle = lift Builder.ANSI.encircle {-# INLINE encircle #-} -- | O̅v̅e̅r̅l̅i̅n̅e̅ style. overline :: Text -> Text overline = lift Builder.ANSI.overline {-# INLINE overline #-} -- lift :: (Builder -> Builder) -> Text -> Text lift f = Builder.runBuilder . f . Builder.fromText -- Don't inline before phase 2 {-# NOINLINE [2] lift #-} -- Collapse lift/lift to a single lift before phase 2 {-# RULES "lift/lift" [~2] forall f g s. lift f (lift g s) = lift (f . g) s #-} text-ansi-0.3.0.1/src/Text/Builder/0000755000000000000000000000000007346545000015057 5ustar0000000000000000text-ansi-0.3.0.1/src/Text/Builder/ANSI.hs0000644000000000000000000002102007346545000016140 0ustar0000000000000000{-# LANGUAGE MagicHash #-} module Text.Builder.ANSI ( -- $intro -- * Foreground color black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, rgb, -- * Background color blackBg, redBg, greenBg, yellowBg, blueBg, magentaBg, cyanBg, whiteBg, brightBlackBg, brightRedBg, brightGreenBg, brightYellowBg, brightBlueBg, brightMagentaBg, brightCyanBg, brightWhiteBg, rgbBg, -- * Style bold, faint, italic, underline, doubleUnderline, strikethrough, frame, encircle, overline, ) where import Data.Text.Builder.Linear (Builder) import qualified Data.Text.Builder.Linear as Builder import Data.Word (Word8) import System.IO.Unsafe (unsafePerformIO) import System.Posix.Internals (c_isatty) -- $intro -- -- Text styling for ANSI terminals using SGR codes, as defined by the -- -- standard. -- -- Supports foreground\/background color, bold\/faint intensity, italic, -- single\/double underline, strikethrough, frame, encircle, and overline escape -- sequences. Some styles may not work on your terminal. -- -- Also features terminal detection, so redirecting styled output to a file will -- automatically strip the ANSI escape sequences. -- | Black foreground. black :: Builder -> Builder black = foreground (Builder.fromAddr "30"#) {-# INLINE black #-} -- | Red foreground. red :: Builder -> Builder red = foreground (Builder.fromAddr "31"#) {-# INLINE red #-} -- | Green foreground. green :: Builder -> Builder green = foreground (Builder.fromAddr "32"#) {-# INLINE green #-} -- | Yellow foreground. yellow :: Builder -> Builder yellow = foreground (Builder.fromAddr "33"#) {-# INLINE yellow #-} -- | Blue foreground. blue :: Builder -> Builder blue = foreground (Builder.fromAddr "34"#) {-# INLINE blue #-} -- | Magenta foreground. magenta :: Builder -> Builder magenta = foreground (Builder.fromAddr "35"#) {-# INLINE magenta #-} -- | Cyan foreground. cyan :: Builder -> Builder cyan = foreground (Builder.fromAddr "36"#) {-# INLINE cyan #-} -- | White foreground. white :: Builder -> Builder white = foreground (Builder.fromAddr "37"#) {-# INLINE white #-} -- | Bright black foreground. brightBlack :: Builder -> Builder brightBlack = foreground (Builder.fromAddr "90"#) {-# INLINE brightBlack #-} -- | Bright red foreground. brightRed :: Builder -> Builder brightRed = foreground (Builder.fromAddr "91"#) {-# INLINE brightRed #-} -- | Bright green foreground. brightGreen :: Builder -> Builder brightGreen = foreground (Builder.fromAddr "92"#) {-# INLINE brightGreen #-} -- | Bright yellow foreground. brightYellow :: Builder -> Builder brightYellow = foreground (Builder.fromAddr "93"#) {-# INLINE brightYellow #-} -- | Bright blue foreground. brightBlue :: Builder -> Builder brightBlue = foreground (Builder.fromAddr "94"#) {-# INLINE brightBlue #-} -- | Bright magenta foreground. brightMagenta :: Builder -> Builder brightMagenta = foreground (Builder.fromAddr "95"#) {-# INLINE brightMagenta #-} -- | Bright cyan foreground. brightCyan :: Builder -> Builder brightCyan = foreground (Builder.fromAddr "96"#) {-# INLINE brightCyan #-} -- | Bright white foreground. brightWhite :: Builder -> Builder brightWhite = foreground (Builder.fromAddr "97"#) {-# INLINE brightWhite #-} -- | RGB foreground. rgb :: Word8 -> Word8 -> Word8 -> Builder -> Builder rgb r g b = foreground (Builder.fromAddr "38;2;"# <> Builder.fromDec r <> semi <> Builder.fromDec g <> semi <> Builder.fromDec b) {-# INLINE rgb #-} foreground :: Builder -> Builder -> Builder foreground s = surround s (Builder.fromAddr "39"#) {-# INLINE foreground #-} -- | Black background. blackBg :: Builder -> Builder blackBg = background (Builder.fromAddr "40"#) {-# INLINE blackBg #-} -- | Red background. redBg :: Builder -> Builder redBg = background (Builder.fromAddr "41"#) {-# INLINE redBg #-} -- | Green background. greenBg :: Builder -> Builder greenBg = background (Builder.fromAddr "42"#) {-# INLINE greenBg #-} -- | Yellow background. yellowBg :: Builder -> Builder yellowBg = background (Builder.fromAddr "43"#) {-# INLINE yellowBg #-} -- | Blue background. blueBg :: Builder -> Builder blueBg = background (Builder.fromAddr "44"#) {-# INLINE blueBg #-} -- | Magenta background. magentaBg :: Builder -> Builder magentaBg = background (Builder.fromAddr "45"#) {-# INLINE magentaBg #-} -- | Cyan background. cyanBg :: Builder -> Builder cyanBg = background (Builder.fromAddr "46"#) {-# INLINE cyanBg #-} -- | White background. whiteBg :: Builder -> Builder whiteBg = background (Builder.fromAddr "47"#) {-# INLINE whiteBg #-} -- | Bright black background. brightBlackBg :: Builder -> Builder brightBlackBg = background (Builder.fromAddr "100"#) {-# INLINE brightBlackBg #-} -- | Bright red background. brightRedBg :: Builder -> Builder brightRedBg = background (Builder.fromAddr "101"#) {-# INLINE brightRedBg #-} -- | Bright green background. brightGreenBg :: Builder -> Builder brightGreenBg = background (Builder.fromAddr "102"#) {-# INLINE brightGreenBg #-} -- | Bright yellow background. brightYellowBg :: Builder -> Builder brightYellowBg = background (Builder.fromAddr "103"#) {-# INLINE brightYellowBg #-} -- | Bright blue background. brightBlueBg :: Builder -> Builder brightBlueBg = background (Builder.fromAddr "104"#) {-# INLINE brightBlueBg #-} -- | Bright magenta background. brightMagentaBg :: Builder -> Builder brightMagentaBg = background (Builder.fromAddr "105"#) {-# INLINE brightMagentaBg #-} -- | Bright cyan background. brightCyanBg :: Builder -> Builder brightCyanBg = background (Builder.fromAddr "106"#) {-# INLINE brightCyanBg #-} -- | Bright white background. brightWhiteBg :: Builder -> Builder brightWhiteBg = background (Builder.fromAddr "107"#) {-# INLINE brightWhiteBg #-} background :: Builder -> Builder -> Builder background s = surround s (Builder.fromAddr "49"#) {-# INLINE background #-} -- | RGB background. rgbBg :: Word8 -> Word8 -> Word8 -> Builder -> Builder rgbBg r g b = background (Builder.fromAddr "48;2;"# <> Builder.fromDec r <> semi <> Builder.fromDec g <> semi <> Builder.fromDec b) {-# INLINE rgbBg #-} -- | __Bold__ style (high intensity). bold :: Builder -> Builder bold = surround (Builder.fromAddr "1"#) (Builder.fromAddr "22"#) {-# INLINE bold #-} -- | Faint style (low intensity). faint :: Builder -> Builder faint = surround (Builder.fromAddr "2"#) (Builder.fromAddr "22"#) {-# INLINE faint #-} -- | /Italic/ style. italic :: Builder -> Builder italic = surround (Builder.fromAddr "3"#) (Builder.fromAddr "23"#) {-# INLINE italic #-} -- | U̲n̲d̲e̲r̲l̲i̲n̲e̲ style. underline :: Builder -> Builder underline = surround (Builder.fromAddr "4"#) (Builder.fromAddr "24"#) {-# INLINE underline #-} -- | D̳o̳u̳b̳l̳e̳ ̳u̳n̳d̳e̳r̳l̳i̳n̳e̳ style. doubleUnderline :: Builder -> Builder doubleUnderline = surround (Builder.fromAddr "21"#) (Builder.fromAddr "24"#) {-# INLINE doubleUnderline #-} -- | S̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h̶ style. strikethrough :: Builder -> Builder strikethrough = surround (Builder.fromAddr "9"#) (Builder.fromAddr "29"#) {-# INLINE strikethrough #-} -- | Frame style. frame :: Builder -> Builder frame = surround (Builder.fromAddr "51"#) (Builder.fromAddr "54"#) {-# INLINE frame #-} -- | Encircle style. encircle :: Builder -> Builder encircle = surround (Builder.fromAddr "52"#) (Builder.fromAddr "54"#) {-# INLINE encircle #-} -- | O̅v̅e̅r̅l̅i̅n̅e̅ style. overline :: Builder -> Builder overline = surround (Builder.fromAddr "53"#) (Builder.fromAddr "55"#) {-# INLINE overline #-} -------------------------------------------------------------------------------- surround :: Builder -> Builder -> Builder -> Builder surround open close text | isatty = esc <> open <> m <> text <> esc <> close <> m | otherwise = text -- Don't inline before phase 1 {-# NOINLINE [1] surround #-} esc :: Builder esc = Builder.fromAddr "\ESC["# m :: Builder m = Builder.fromChar 'm' semi :: Builder semi = Builder.fromChar ';' isatty :: Bool isatty = unsafePerformIO (c_isatty 1) == 1 {-# NOINLINE isatty #-} -- Collapse surround/surround to a single surround before phase 1 {-# RULES "surround/surround" [~1] forall a b c d s. surround a b (surround c d s) = surround (a <> semi <> c) (b <> semi <> d) s #-} text-ansi-0.3.0.1/src/Text/Lazy/Builder/0000755000000000000000000000000007346545000015776 5ustar0000000000000000text-ansi-0.3.0.1/src/Text/Lazy/Builder/ANSI.hs0000644000000000000000000002114507346545000017067 0ustar0000000000000000module Text.Lazy.Builder.ANSI ( -- $intro -- * Foreground color black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, rgb, -- * Background color blackBg, redBg, greenBg, yellowBg, blueBg, magentaBg, cyanBg, whiteBg, brightBlackBg, brightRedBg, brightGreenBg, brightYellowBg, brightBlueBg, brightMagentaBg, brightCyanBg, brightWhiteBg, rgbBg, -- * Style bold, faint, italic, underline, doubleUnderline, strikethrough, frame, encircle, overline, ) where import Data.Text.Lazy.Builder (Builder) import qualified Data.Text.Lazy.Builder as Builder import qualified Data.Text.Lazy.Builder.Int as Builder import Data.Word (Word8) import System.IO.Unsafe (unsafePerformIO) import System.Posix.Internals (c_isatty) -- $intro -- -- Text styling for ANSI terminals using SGR codes, as defined by the -- -- standard. -- -- Supports foreground\/background color, bold\/faint intensity, italic, -- single\/double underline, strikethrough, frame, encircle, and overline escape -- sequences. Some styles may not work on your terminal. -- -- Also features terminal detection, so redirecting styled output to a file will -- automatically strip the ANSI escape sequences. -- | Black foreground. black :: Builder -> Builder black = foreground (Builder.fromString "30") {-# INLINE black #-} -- | Red foreground. red :: Builder -> Builder red = foreground (Builder.fromString "31") {-# INLINE red #-} -- | Green foreground. green :: Builder -> Builder green = foreground (Builder.fromString "32") {-# INLINE green #-} -- | Yellow foreground. yellow :: Builder -> Builder yellow = foreground (Builder.fromString "33") {-# INLINE yellow #-} -- | Blue foreground. blue :: Builder -> Builder blue = foreground (Builder.fromString "34") {-# INLINE blue #-} -- | Magenta foreground. magenta :: Builder -> Builder magenta = foreground (Builder.fromString "35") {-# INLINE magenta #-} -- | Cyan foreground. cyan :: Builder -> Builder cyan = foreground (Builder.fromString "36") {-# INLINE cyan #-} -- | White foreground. white :: Builder -> Builder white = foreground (Builder.fromString "37") {-# INLINE white #-} -- | Bright black foreground. brightBlack :: Builder -> Builder brightBlack = foreground (Builder.fromString "90") {-# INLINE brightBlack #-} -- | Bright red foreground. brightRed :: Builder -> Builder brightRed = foreground (Builder.fromString "91") {-# INLINE brightRed #-} -- | Bright green foreground. brightGreen :: Builder -> Builder brightGreen = foreground (Builder.fromString "92") {-# INLINE brightGreen #-} -- | Bright yellow foreground. brightYellow :: Builder -> Builder brightYellow = foreground (Builder.fromString "93") {-# INLINE brightYellow #-} -- | Bright blue foreground. brightBlue :: Builder -> Builder brightBlue = foreground (Builder.fromString "94") {-# INLINE brightBlue #-} -- | Bright magenta foreground. brightMagenta :: Builder -> Builder brightMagenta = foreground (Builder.fromString "95") {-# INLINE brightMagenta #-} -- | Bright cyan foreground. brightCyan :: Builder -> Builder brightCyan = foreground (Builder.fromString "96") {-# INLINE brightCyan #-} -- | Bright white foreground. brightWhite :: Builder -> Builder brightWhite = foreground (Builder.fromString "97") {-# INLINE brightWhite #-} -- | RGB foreground. rgb :: Word8 -> Word8 -> Word8 -> Builder -> Builder rgb r g b = foreground (Builder.fromString "38;2;" <> Builder.decimal r <> semi <> Builder.decimal g <> semi <> Builder.decimal b) {-# INLINE rgb #-} foreground :: Builder -> Builder -> Builder foreground s = surround s (Builder.fromString "39") {-# INLINE foreground #-} -- | Black background. blackBg :: Builder -> Builder blackBg = background (Builder.fromString "40") {-# INLINE blackBg #-} -- | Red background. redBg :: Builder -> Builder redBg = background (Builder.fromString "41") {-# INLINE redBg #-} -- | Green background. greenBg :: Builder -> Builder greenBg = background (Builder.fromString "42") {-# INLINE greenBg #-} -- | Yellow background. yellowBg :: Builder -> Builder yellowBg = background (Builder.fromString "43") {-# INLINE yellowBg #-} -- | Blue background. blueBg :: Builder -> Builder blueBg = background (Builder.fromString "44") {-# INLINE blueBg #-} -- | Magenta background. magentaBg :: Builder -> Builder magentaBg = background (Builder.fromString "45") {-# INLINE magentaBg #-} -- | Cyan background. cyanBg :: Builder -> Builder cyanBg = background (Builder.fromString "46") {-# INLINE cyanBg #-} -- | White background. whiteBg :: Builder -> Builder whiteBg = background (Builder.fromString "47") {-# INLINE whiteBg #-} -- | Bright black background. brightBlackBg :: Builder -> Builder brightBlackBg = background (Builder.fromString "100") {-# INLINE brightBlackBg #-} -- | Bright red background. brightRedBg :: Builder -> Builder brightRedBg = background (Builder.fromString "101") {-# INLINE brightRedBg #-} -- | Bright green background. brightGreenBg :: Builder -> Builder brightGreenBg = background (Builder.fromString "102") {-# INLINE brightGreenBg #-} -- | Bright yellow background. brightYellowBg :: Builder -> Builder brightYellowBg = background (Builder.fromString "103") {-# INLINE brightYellowBg #-} -- | Bright blue background. brightBlueBg :: Builder -> Builder brightBlueBg = background (Builder.fromString "104") {-# INLINE brightBlueBg #-} -- | Bright magenta background. brightMagentaBg :: Builder -> Builder brightMagentaBg = background (Builder.fromString "105") {-# INLINE brightMagentaBg #-} -- | Bright cyan background. brightCyanBg :: Builder -> Builder brightCyanBg = background (Builder.fromString "106") {-# INLINE brightCyanBg #-} -- | Bright white background. brightWhiteBg :: Builder -> Builder brightWhiteBg = background (Builder.fromString "107") {-# INLINE brightWhiteBg #-} background :: Builder -> Builder -> Builder background s = surround s (Builder.fromString "49") {-# INLINE background #-} -- | RGB background. rgbBg :: Word8 -> Word8 -> Word8 -> Builder -> Builder rgbBg r g b = background (Builder.fromString "48;2;" <> Builder.decimal r <> semi <> Builder.decimal g <> semi <> Builder.decimal b) {-# INLINE rgbBg #-} -- | __Bold__ style (high intensity). bold :: Builder -> Builder bold = surround (Builder.fromString "1") (Builder.fromString "22") {-# INLINE bold #-} -- | Faint style (low intensity). faint :: Builder -> Builder faint = surround (Builder.fromString "2") (Builder.fromString "22") {-# INLINE faint #-} -- | /Italic/ style. italic :: Builder -> Builder italic = surround (Builder.fromString "3") (Builder.fromString "23") {-# INLINE italic #-} -- | U̲n̲d̲e̲r̲l̲i̲n̲e̲ style. underline :: Builder -> Builder underline = surround (Builder.fromString "4") (Builder.fromString "24") {-# INLINE underline #-} -- | D̳o̳u̳b̳l̳e̳ ̳u̳n̳d̳e̳r̳l̳i̳n̳e̳ style. doubleUnderline :: Builder -> Builder doubleUnderline = surround (Builder.fromString "21") (Builder.fromString "24") {-# INLINE doubleUnderline #-} -- | S̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h̶ style. strikethrough :: Builder -> Builder strikethrough = surround (Builder.fromString "9") (Builder.fromString "29") {-# INLINE strikethrough #-} -- | Frame style. frame :: Builder -> Builder frame = surround (Builder.fromString "51") (Builder.fromString "54") {-# INLINE frame #-} -- | Encircle style. encircle :: Builder -> Builder encircle = surround (Builder.fromString "52") (Builder.fromString "54") {-# INLINE encircle #-} -- | O̅v̅e̅r̅l̅i̅n̅e̅ style. overline :: Builder -> Builder overline = surround (Builder.fromString "53") (Builder.fromString "55") {-# INLINE overline #-} -------------------------------------------------------------------------------- surround :: Builder -> Builder -> Builder -> Builder surround open close text | isatty = esc <> open <> m <> text <> esc <> close <> m | otherwise = text -- Don't inline before phase 1 {-# NOINLINE [1] surround #-} esc :: Builder esc = Builder.fromString "\ESC[" m :: Builder m = Builder.singleton 'm' semi :: Builder semi = Builder.singleton ';' isatty :: Bool isatty = unsafePerformIO (c_isatty 1) == 1 {-# NOINLINE isatty #-} -- Collapse surround/surround to a single surround before phase 1 {-# RULES "surround/surround" [~1] forall a b c d s. surround a b (surround c d s) = surround (a <> semi <> c) (b <> semi <> d) s #-} text-ansi-0.3.0.1/text-ansi.cabal0000644000000000000000000000334007346545000014656 0ustar0000000000000000cabal-version: 2.2 name: text-ansi version: 0.3.0.1 category: Data synopsis: Text styling for ANSI terminals. description: Text styling for ANSI terminals using SGR codes, as defined by the standard. . Supports foreground\/background color, bold\/faint intensity, italic, single\/double underline, strikethrough, frame, encircle, and overline escape sequences. Some styles may not work on your terminal. . Also features terminal detection, so redirecting styled output to a file will automatically strip the ANSI escape sequences. author: Mitchell Rosen, Travis Staton maintainer: Mitchell Rosen , Travis Staton homepage: https://github.com/awkward-squad/text-ansi bug-reports: https://github.com/awkward-squad/text-ansi/issues copyright: (c) 2018-2023 Mitchell Rosen, Travis Staton license: BSD-3-Clause license-file: LICENSE build-type: Simple tested-with: GHC == 9.4.7, GHC == 9.6.3, GHC == 9.8.1 extra-source-files: CHANGELOG.md README.md source-repository head type: git location: git://github.com/awkward-squad/text-ansi.git library build-depends: base ^>= 4.16 || ^>= 4.17 || ^>= 4.18 || ^>= 4.19, text >= 1.0 && < 2.2, text-builder-linear ^>= 0.1.1, default-language: Haskell2010 exposed-modules: String.ANSI Text.ANSI Text.Builder.ANSI Text.Lazy.Builder.ANSI ghc-options: -Weverything -Wno-implicit-prelude -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-unsafe if impl(ghc >= 8.10) ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module hs-source-dirs: src