safe-coloured-text-layout 0.1.0.0 → 0.2.0.0
raw patch · 4 files changed
+80/−42 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Text.Colour.Layout: layoutAsTableLines :: [[[Chunk]]] -> [[Chunk]]
+ Text.Colour.Layout: renderTableLines :: Table -> [[Chunk]]
- Text.Colour.Layout: Table :: [[Chunk]] -> Chunk -> Maybe TableBackground -> Table
+ Text.Colour.Layout: Table :: [[[Chunk]]] -> Chunk -> Maybe TableBackground -> Table
- Text.Colour.Layout: [tableCells] :: Table -> [[Chunk]]
+ Text.Colour.Layout: [tableCells] :: Table -> [[[Chunk]]]
- Text.Colour.Layout: layoutAsTable :: [[Chunk]] -> [Chunk]
+ Text.Colour.Layout: layoutAsTable :: [[[Chunk]]] -> [Chunk]
- Text.Colour.Layout: table :: [[Chunk]] -> Table
+ Text.Colour.Layout: table :: [[[Chunk]]] -> Table
Files
- CHANGELOG.md +11/−0
- safe-coloured-text-layout.cabal +2/−2
- src/Text/Colour/Layout.hs +53/−26
- test/Text/Colour/LayoutSpec.hs +14/−14
CHANGELOG.md view
@@ -1,5 +1,16 @@ # Changelog for safe-coloured-text-layout +## [0.2.0.0] - 2024-06-23++### Added++* `layoutAsTableLines`+* `renderTableLines`++### Changed++* Table cells are now lists of chunks instead of individual chunks.+ ## [0.1.0.0] - 2024-03-26 ### Changed
safe-coloured-text-layout.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack name: safe-coloured-text-layout-version: 0.1.0.0+version: 0.2.0.0 synopsis: Safely layout output coloured text category: User Interfaces homepage: https://github.com/NorfairKing/safe-coloured-text#readme
src/Text/Colour/Layout.hs view
@@ -1,13 +1,16 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-} module Text.Colour.Layout ( layoutAsTable,+ layoutAsTableLines, table, Table (..), TableBackground (..), renderTable,+ renderTableLines, ) where @@ -17,15 +20,19 @@ import Data.Validity import GHC.Generics (Generic) import Text.Colour+import Text.Colour.Chunk -- | Render as a default-settings table.-layoutAsTable :: [[Chunk]] -> [Chunk]+layoutAsTable :: [[[Chunk]]] -> [Chunk] layoutAsTable = renderTable . table +layoutAsTableLines :: [[[Chunk]]] -> [[Chunk]]+layoutAsTableLines = renderTableLines . table+ -- | Make a table with default settings -- -- You can then update table settings by changing the fields in the resulting 'Table'.-table :: [[Chunk]] -> Table+table :: [[[Chunk]]] -> Table table cs = Table { tableCells = cs,@@ -35,8 +42,8 @@ -- | Table with separator and background settings data Table = Table- { -- | A list of rows. They must be of the same length.- tableCells :: [[Chunk]],+ { -- | A list of rows. They must be of the same total length.+ tableCells :: [[[Chunk]]], tableColumnSeparator :: Chunk, tableBackground :: Maybe TableBackground }@@ -47,52 +54,72 @@ data TableBackground = SingleColour Colour | Bicolour+ -- Even-numbered table rows (0-indexed) (Maybe Colour)- -- ^ Even-numbered table rows (0-indexed)+ -- Odd-numbered table rows (Maybe Colour)- -- ^ Odd-numbered table rows deriving (Show, Eq, Generic) instance Validity TableBackground -- | Render a table to chunks that can be rendered to text. renderTable :: Table -> [Chunk]-renderTable Table {..} =- let asColumns = transpose (padRows tableCells)- addLengthsToColumn :: [Chunk] -> [(Int, Chunk)]- addLengthsToColumn = map (\c -> (T.length (chunkText c), c))- maxLengthOfColum :: [(Int, Chunk)] -> Int+renderTable = unlinesChunks . renderTableLines++renderTableLines :: Table -> [[Chunk]]+renderTableLines Table {..} =+ let asColumns :: [[[Chunk]]]+ asColumns = transpose (padRows [] tableCells)++ addLengthsToColumn :: [[Chunk]] -> [(Int, [Chunk])]+ addLengthsToColumn = map (\c -> (cellWidth c, c))+ maxLengthOfColum :: [(Int, [Chunk])] -> Int maxLengthOfColum = maximum . map fst- padColumn :: Int -> [(Int, Chunk)] -> [(Chunk, Chunk)]- padColumn maxLength = map (\(l, c) -> (c, paddingChunk (maxLength - l) ' '))- padEntireColumn :: [(Int, Chunk)] -> [(Chunk, Chunk)]+ padColumn :: Int -> [(Int, [Chunk])] -> [[Chunk]]+ padColumn maxLength = map (\(l, c) -> c ++ [paddingChunk (maxLength - l) ' '])+ padEntireColumn :: [(Int, [Chunk])] -> [[Chunk]] padEntireColumn col = let maxLength = maxLengthOfColum col in padColumn maxLength col- paddedColumns :: [[(Chunk, Chunk)]]+ paddedColumns :: [[[Chunk]]] paddedColumns = map (padEntireColumn . addLengthsToColumn) asColumns- paddedRows :: [[(Chunk, Chunk)]]+ paddedRows :: [[[Chunk]]] paddedRows = transpose paddedColumns+ withBg :: Int -> Chunk -> Chunk withBg i = possiblyAddBackground $ backgroundForRow i tableBackground- renderRow :: Int -> [(Chunk, Chunk)] -> [Chunk]+ renderRow :: Int -> [[Chunk]] -> [Chunk] renderRow i = go where- go [] = ["\n"]- go [(c, p)] = withBg i c : withBg i p : go []- go ((c1, p1) : t2 : rest) = withBg i c1 : withBg i p1 : withBg i tableColumnSeparator : go (t2 : rest)- in concat $ iterateLikeInPython renderRow paddedRows+ go :: [[Chunk]] -> [Chunk]+ go [] = []+ go [cs] = map (withBg i) cs ++ go []+ go (cs1 : cs2 : rest) =+ map (withBg i) cs1+ ++ [withBg i tableColumnSeparator]+ ++ go (cs2 : rest)+ in iterateLikeInPython renderRow paddedRows iterateLikeInPython :: (Int -> a -> b) -> [a] -> [b] iterateLikeInPython f = zipWith f [0 ..] -padRows :: [[Chunk]] -> [[Chunk]]-padRows [] = []-padRows css =- let withLengths = map (\ls -> (length ls, ls)) css+-- | Make every row contain the same number of cells, irrespective of the+-- width of the cells.+--+-- Use the first argument to fill as the extra cells.+padRows :: forall a. a -> [[a]] -> [[a]]+padRows _ [] = []+padRows d css =+ let withLengths :: [(Int, [a])]+ withLengths = map (\ls -> (length ls, ls)) css+ maximumLength :: Int maximumLength = maximum $ map fst withLengths- pad (l, cs) = cs ++ replicate (maximumLength - l) ""+ pad :: (Int, [a]) -> [a]+ pad (l, cs) = cs ++ replicate (maximumLength - l) d in map pad withLengths++cellWidth :: [Chunk] -> Int+cellWidth = sum . map chunkWidth paddingChunk :: Int -> Char -> Chunk paddingChunk l c = chunk $ T.pack $ replicate l c
test/Text/Colour/LayoutSpec.hs view
@@ -17,10 +17,10 @@ ( renderChunksText With24BitColours ( layoutAsTable- [ ["this"],- ["is"],- ["a"],- ["list"]+ [ [["this"]],+ [["is"]],+ [["a"]],+ [["list"]] ] ) )@@ -30,10 +30,10 @@ ( renderChunksText With24BitColours ( layoutAsTable- [ ["this", "this"],- ["is", "is"],- ["a", "another"],- ["list", "list"]+ [ [["this"], ["this"]],+ [["is"], ["is"]],+ [["a"], ["another"]],+ [["list"], ["list"]] ] ) )@@ -43,9 +43,9 @@ ( renderChunksText With24BitColours ( layoutAsTable- [ ["what", "the", ""],- ["is", "this", "", "-ing", ""],- ["I", "don't", "understand", "one", "", "of", "it"]+ [ [["what"], ["the"], []],+ [["is"], ["this"], [], ["-ing"], []],+ [["I"], ["don't"], ["understand"], ["one"], [], ["of"], ["it"]] ] ) )@@ -55,7 +55,7 @@ ( renderChunksText With24BitColours ( renderTable $- ( table $ [[chunk (T.pack (show (x + y))) | x <- [0 :: Int .. 9]] | y <- [0 :: Int .. 9]]+ ( table $ [[[chunk (T.pack (show (x + y)))] | x <- [0 :: Int .. 9]] | y <- [0 :: Int .. 9]] ) { tableColumnSeparator = "@" }@@ -67,7 +67,7 @@ ( renderChunksText With24BitColours ( renderTable $- ( table $ [[fore red $ chunk (T.pack (show (x ^ y))) | x <- [0 :: Int .. 4]] | y <- [0 :: Int .. 4]]+ ( table $ [[[fore red $ chunk (T.pack (show (x ^ y)))] | x <- [0 :: Int .. 4]] | y <- [0 :: Int .. 4]] ) { tableBackground = Just (SingleColour black) }@@ -79,7 +79,7 @@ ( renderChunksText With24BitColours ( renderTable $- ( table $ [[fore red $ chunk (T.pack (show (x ^ y))) | x <- [0 :: Int .. 4]] | y <- [0 :: Int .. 4]]+ ( table $ [[[fore red $ chunk (T.pack (show (x ^ y)))] | x <- [0 :: Int .. 4]] | y <- [0 :: Int .. 4]] ) { tableBackground = Just (Bicolour (Just black) (Just brightBlack)) }