packages feed

ansi-terminal 1.0.2 → 1.1

raw patch · 7 files changed

+183/−65 lines, 7 filesdep ~ansi-terminal-typesPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: ansi-terminal-types

API changes (from Hackage documentation)

+ System.Console.ANSI.Codes: csi' :: [ParamWithSubs] -> String -> String
+ System.Console.ANSI.Codes: sgrToCode' :: SGR -> Either ParamWithSubs [Parameter]
+ System.Console.ANSI.Codes: type ParamWithSubs = (Parameter, [SubParam])
+ System.Console.ANSI.Codes: type Parameter = Int
+ System.Console.ANSI.Codes: type SubParam = Maybe Int
- System.Console.ANSI.Codes: csi :: [Int] -> String -> String
+ System.Console.ANSI.Codes: csi :: [Parameter] -> String -> String
- System.Console.ANSI.Codes: sgrToCode :: SGR -> [Int]
+ System.Console.ANSI.Codes: sgrToCode :: SGR -> [Parameter]

Files

CHANGELOG.md view
@@ -1,6 +1,17 @@ Changes
 =======
 
+Version 1.1
+-----------
+
+* Add support for console layer `Underlining` and underlining styles
+  `CurlyUnderline`, `DottedUnderline` and `DashedUnderline`.
+* Add type synonyms `Parameter`, `SubParam`, and `ParamWithSubs` to represent
+  SGR parameter values with and without following parameter substrings comprised
+  of one or more parameter elements (including empty elements).
+* Add `csi'` and `sgrToCode'`, corresponding to `csi` and `sgrToCode` but
+  capable of handling a parameter value followed by a parameter substring.
+
 Version 1.0.2
 -------------
 
@@ -18,11 +29,10 @@   action can try to enable the processing of \'ANSI\' control characters in
   output.
 * In Windows Terminal and ConHost terminals, `hSupportsANSI` will yield `False`
-  if the the processing of \'ANSI\' control characters in output is not enabled.
+  if the processing of \'ANSI\' control characters in output is not enabled.
 * Deprecated `hSupportsANSIWithoutEmulation` is now consistent with
   `hNowSupportsANSI`.
 * Improvements to Haddock documentation.
-
 Version 1.0
 -----------
 
LICENSE view
@@ -1,22 +1,25 @@ Copyright (c) 2008, Maximilian Bolingbroke
 All rights reserved.
 
-Redistribution and use in source and binary forms, with or without modification, are permitted
-provided that the following conditions are met:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
 
-    * Redistributions of source code must retain the above copyright notice, this list of
-      conditions and the following disclaimer.
-    * 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.
-    * Neither the name of Maximilian Bolingbroke nor the names of other contributors may be used to
-      endorse or promote products derived from this software without specific prior written permission.
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+* 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.
+* Neither the name of Maximilian Bolingbroke nor the names of other 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 OWNER 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.
+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 OWNER 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.
README.md view
@@ -9,8 +9,8 @@  ['ANSI' terminal escape code](http://en.wikipedia.org/wiki/ANSI_escape_sequences) support for Haskell, which allows:--   Colored text output, with control over both foreground and background-    colors+-   Colored text output, with control over foreground, background and (where+    supported) underlining colors -   Clearing parts of a line or the screen -   Hiding or showing the cursor -   Moving the cursor around
ansi-terminal.cabal view
@@ -1,6 +1,6 @@ Cabal-Version:       1.22
 Name:                ansi-terminal
-Version:             1.0.2
+Version:             1.1
 Category:            User Interfaces
 Synopsis:            Simple ANSI terminal support
 Description:         ANSI terminal support for Haskell: allows cursor movement,
@@ -39,7 +39,7 @@         Other-Modules:          System.Console.ANSI.Internal
 
         Build-Depends:          base >= 4.8.0.0 && < 5
-                              , ansi-terminal-types == 0.11.5
+                              , ansi-terminal-types == 1.1
                               , colour >= 2.1.0
         if os(windows)
             Hs-Source-Dirs:     win
app/Example.hs view
@@ -243,15 +243,16 @@ sgrColorExample :: IO ()
 sgrColorExample = do
   let colors = enumFromTo minBound maxBound :: [Color]
-  forM_ [Foreground, Background] $ \layer ->  do
+  forM_ [Foreground, Background, Underlining] $ \layer ->  do
     forM_ [Dull, Vivid] $ \intensity -> do
       resetScreen
       forM_ colors $ \color -> do
         setSGR [Reset]
         setSGR [SetColor layer intensity color]
+        setSGR [SetUnderlining SingleUnderline]
         print color
       pause
-  -- The ANSI eight standard colors, 4 times in sequence (two layers and two
+  -- The ANSI eight standard colors, 6 times in sequence (three layers and two
   -- intensities)
 
   resetScreen
@@ -333,6 +334,25 @@         putStr " "
   replicateM_ 5 pause
 
+  resetScreen
+  setSGR [Reset]
+  setSGR [SetUnderlining SingleUnderline]
+  forM_
+    (zip "Underlining: True color (24 bit color depth)" (cycle [0, 10 .. 255])) $
+    \(c, i) -> do
+      setSGR [SetRGBColor Underlining $ sRGB24 i 0 0]
+      putChar c
+  putChar '\n'
+  putChar '\n'
+  setSGR [Reset]
+  setSGR [SetUnderlining SingleUnderline]
+  forM_ (zip "Underlining: A 256-color palette" (cycle [0 .. 5])) $
+    \(c, i) -> do
+      setSGR [SetPaletteColor Underlining $ xterm6LevelRGB i 0 0]
+      putChar c
+  putChar '\n'
+  replicateM_ 5 pause
+
 sgrOtherExample :: IO ()
 sgrOtherExample = do
   let named_styles = [ (SetConsoleIntensity BoldIntensity, "Bold")
@@ -342,6 +362,9 @@                      , (SetItalicized False, "No Italics")
                      , (SetUnderlining SingleUnderline, "Single Underline")
                      , (SetUnderlining DoubleUnderline, "Double Underline")
+                     , (SetUnderlining CurlyUnderline, "Curly Underline")
+                     , (SetUnderlining DottedUnderline, "Dotted Underline")
+                     , (SetUnderlining DashedUnderline, "Dashed Underline")
                      , (SetUnderlining NoUnderline, "No Underline")
                      , (SetBlinkSpeed SlowBlink, "Slow Blink")
                      , (SetBlinkSpeed RapidBlink, "Rapid Blink")
src/System/Console/ANSI.hs view
@@ -10,7 +10,8 @@ codes) provide a rich range of functionality for terminal control, which
 includes:
 
- * Colored text output, with control over both foreground and background colors
+ * Colored text output, with control over foreground, background and (where
+   supported) underlining colors
 
  * Clearing parts of a line or the screen
 
@@ -897,6 +898,7 @@   void $ string $ case layer of
     Foreground -> "10"
     Background -> "11"
+    Underlining -> fail "reportLayerColor does not support underlining"
   void $ string ";rgb:"
   redHex <- hexadecimal -- A non-negative whole hexadecimal number
   void $ char '/'
src/System/Console/ANSI/Codes.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Safe          #-}
+{-# LANGUAGE TupleSections #-}
 
 {-| This module exports functions that return 'String' values containing codes
 in accordance with the \'ANSI\' standards for control character sequences
@@ -62,7 +63,15 @@   , setTitleCode
 
     -- * Utilities
-  , colorToCode, csi, osc, sgrToCode
+  , colorToCode
+  , Parameter
+  , SubParam
+  , ParamWithSubs
+  , csi
+  , csi'
+  , osc
+  , sgrToCode
+  , sgrToCode'
   ) where
 
 import Data.Char (isPrint)
@@ -72,17 +81,61 @@ 
 import System.Console.ANSI.Types
 
+-- | Type synonym representing parameter values (without parameter substrings).
+-- To represent a paramater value followed by a parameter substring, see
+-- 'ParamWithSubs'.
+--
+-- @since 1.1
+type Parameter = Int
+
+-- | Type synonym representing parameter elements of a parameter
+-- substring. An empty parameter element (which represents a default value for
+-- the parameter element) has value 'Nothing'.
+--
+-- @since 1.1
+type SubParam = Maybe Int
+
+-- | Type synonym representing parameter values optionally followed by a
+-- parameter substring. Parameter substrings were introduced by 13.1.8 of T.416
+-- (03/93) for SGR parameter values 38 and 48 and have subsequently been adapted
+-- for other uses.
+--
+-- @since 1.1
+type ParamWithSubs = (Parameter, [SubParam])
+
 -- | 'csi' @parameters controlFunction@, where @parameters@ is a list of 'Int',
 -- returns the control sequence comprising the control function CONTROL
--- SEQUENCE INTRODUCER (CSI) followed by the parameter(s) (separated by \';\')
+-- SEQUENCE INTRODUCER (CSI) followed by the parameter(s) (separated by \'@;@\')
 -- and ending with the @controlFunction@ character(s) that identifies the
--- control function.
+-- control function. See 'csi'' for a function that handles parameter values
+-- that may be followed by a parameter substring.
 csi ::
-     [Int]  -- ^ List of parameters for the control sequence
-  -> String -- ^ Character(s) that identify the control function
+     [Parameter]  -- ^ List of parameters for the control sequence.
+  -> String -- ^ Character(s) that identify the control function.
   -> String
-csi args code = "\ESC[" ++ intercalate ";" (map show args) ++ code
+csi = renderCsi show
 
+-- | Like 'csi' but extended to parameters that may be followed by a parameter
+-- substring. The parameter elements of a parameter substring are separated from
+-- the parameter value and each other by \'@:@\'.
+--
+-- @since 1.1
+csi' ::
+     [ParamWithSubs]
+     -- ^ List of parameters (each of which may be followed by a parameter
+     -- substring).
+  -> String -- ^ Characters(s) that identify the control function.
+  -> String
+csi' = renderCsi render
+ where
+  render (p, []) = show p
+  render (p, pes) = intercalate ":" (show p : map (maybe [] show) pes)
+
+-- | Helper function to render different types of parameters.
+renderCsi :: (a -> String) -> [a] -> String -> String
+renderCsi render args code =
+  "\ESC[" ++ intercalate ";" (map render args) ++ code
+
 -- | 'osc' @parameterS parametersT@, where @parameterS@ specifies the type of
 -- operation to perform and @parametersT@ is the other parameter(s) (if any),
 -- returns the control sequence comprising the control function OPERATING SYSTEM
@@ -110,43 +163,65 @@   White   -> 7
 
 -- | 'sgrToCode' @sgr@ returns the parameter of the SELECT GRAPHIC RENDITION
--- (SGR) aspect identified by @sgr@.
+-- (SGR) aspect identified by @sgr@. If the parameter is followed by a parameter
+-- substring returns an empty list. See 'sgrToCode'' for a function that handles
+-- also parameter values that are followed by a parameter substring.
 sgrToCode ::
      SGR -- ^ The SGR aspect
-  -> [Int]
-sgrToCode sgr = case sgr of
-  Reset -> [0]
+  -> [Parameter]
+sgrToCode sgr = case sgrToCode' sgr of
+  Right args -> args
+  Left _ -> []
+
+-- | 'sgrToCode'' @sgr@ returns the parameter of the SELECT GRAPHIC RENDITION
+-- (SGR) aspect identified by @sgr@.
+--
+-- @since 1.1
+sgrToCode' ::
+     SGR -- ^ The SGR aspect
+  -> Either ParamWithSubs [Parameter]
+sgrToCode' sgr = case sgr of
+  Reset -> Right [0]
   SetConsoleIntensity intensity -> case intensity of
-    BoldIntensity   -> [1]
-    FaintIntensity  -> [2]
-    NormalIntensity -> [22]
-  SetItalicized True  -> [3]
-  SetItalicized False -> [23]
+    BoldIntensity   -> Right [1]
+    FaintIntensity  -> Right [2]
+    NormalIntensity -> Right [22]
+  SetItalicized True  -> Right [3]
+  SetItalicized False -> Right [23]
   SetUnderlining underlining -> case underlining of
-    SingleUnderline -> [4]
-    DoubleUnderline -> [21]
-    NoUnderline     -> [24]
+    SingleUnderline -> Right [4]
+    DoubleUnderline -> Right [21]
+    CurlyUnderline -> Left (4, [Just 3])
+    DottedUnderline -> Left (4, [Just 4])
+    DashedUnderline -> Left (4, [Just 5])
+    NoUnderline     -> Right [24]
   SetBlinkSpeed blink_speed -> case blink_speed of
-    SlowBlink   -> [5]
-    RapidBlink  -> [6]
-    NoBlink     -> [25]
-  SetVisible False -> [8]
-  SetVisible True  -> [28]
-  SetSwapForegroundBackground True  -> [7]
-  SetSwapForegroundBackground False -> [27]
-  SetColor Foreground Dull color  -> [30 + colorToCode color]
-  SetColor Foreground Vivid color -> [90 + colorToCode color]
-  SetColor Background Dull color  -> [40 + colorToCode color]
-  SetColor Background Vivid color -> [100 + colorToCode color]
-  SetPaletteColor Foreground index -> [38, 5, fromIntegral index]
-  SetPaletteColor Background index -> [48, 5, fromIntegral index]
-  SetRGBColor Foreground color -> [38, 2] ++ toRGB color
-  SetRGBColor Background color -> [48, 2] ++ toRGB color
-  SetDefaultColor Foreground -> [39]
-  SetDefaultColor Background -> [49]
+    SlowBlink   -> Right [5]
+    RapidBlink  -> Right [6]
+    NoBlink     -> Right [25]
+  SetVisible False -> Right [8]
+  SetVisible True  -> Right [28]
+  SetSwapForegroundBackground True  -> Right [7]
+  SetSwapForegroundBackground False -> Right [27]
+  SetColor Foreground Dull color  -> Right [30 + colorToCode color]
+  SetColor Foreground Vivid color -> Right [90 + colorToCode color]
+  SetColor Background Dull color  -> Right [40 + colorToCode color]
+  SetColor Background Vivid color -> Right [100 + colorToCode color]
+  SetColor Underlining Dull color  -> Left (58, [Just 5, Just $ colorToCode color])
+  SetColor Underlining Vivid color -> Left (58, [Just 5, Just $ 8 + colorToCode color])
+  SetPaletteColor Foreground index -> Right [38, 5, fromIntegral index]
+  SetPaletteColor Background index -> Right [48, 5, fromIntegral index]
+  SetPaletteColor Underlining index -> Left (58, [Just 5, Just $ fromIntegral index])
+  SetRGBColor Foreground color -> Right $ [38, 2] ++ toRGB color
+  SetRGBColor Background color -> Right $ [48, 2] ++ toRGB color
+  SetRGBColor Underlining color -> Left (58, [Just 2, Nothing] ++ toRGB' color)
+  SetDefaultColor Foreground -> Right [39]
+  SetDefaultColor Background -> Right [49]
+  SetDefaultColor Underlining -> Right [59]
  where
   toRGB color = let RGB r g b = toSRGB24 color
                 in  map fromIntegral [r, g, b]
+  toRGB' = map Just . toRGB
 
 cursorUpCode, cursorDownCode, cursorForwardCode, cursorBackwardCode ::
      Int -- ^ Number of lines or characters to move
@@ -198,9 +273,11 @@ reportCursorPositionCode :: String
 reportCursorPositionCode = csi [] "6n"
 
--- | Code to emit the layer color into the console input stream, immediately
--- after being recognised on the output stream, as:
+-- | Code to emit the foreground or backgrond layer color into the console input
+-- stream, immediately after being recognised on the output stream, as:
+--
 -- @ESC ] \<Ps> ; rgb: \<red> ; \<green> ; \<blue> \<ST>@
+--
 -- where @\<Ps>@ is @10@ for 'Foreground' and @11@ for 'Background'; @\<red>@,
 -- @\<green>@ and @\<blue>@ are the color channel values in hexadecimal (4, 8,
 -- 12 and 16 bit values are possible, although 16 bit values are most common);
@@ -216,6 +293,7 @@ reportLayerColorCode :: ConsoleLayer -> String
 reportLayerColorCode Foreground = osc "10" "?"
 reportLayerColorCode Background = osc "11" "?"
+reportLayerColorCode Underlining = [] -- Not supported.
 
 clearFromCursorToScreenEndCode, clearFromCursorToScreenBeginningCode,
   clearScreenCode :: String
@@ -245,7 +323,9 @@      -- console SGR mode. An empty list of commands is equivalent to the list
      -- @[Reset]@. Commands are applied left to right.
   -> String
-setSGRCode sgrs = csi (concatMap sgrToCode sgrs) "m"
+setSGRCode sgrs = csi' (concatMap sgrToCode'' sgrs) "m"
+ where
+  sgrToCode'' = either (:[]) (map (,[] :: [SubParam])) . sgrToCode'
 
 hideCursorCode, showCursorCode :: String
 hideCursorCode = csi [] "?25l"