tabl (empty) → 0.1.0.0
raw patch · 10 files changed
+424/−0 lines, 10 filesdep +basedep +safedep +textsetup-changed
Dependencies added: base, safe, text
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- src/Text/Tabl.hs +51/−0
- src/Text/Tabl/Alignment.hs +24/−0
- src/Text/Tabl/Ascii.hs +94/−0
- src/Text/Tabl/Decoration.hs +56/−0
- src/Text/Tabl/Environment.hs +23/−0
- src/Text/Tabl/Latex.hs +56/−0
- src/Text/Tabl/Util.hs +55/−0
- tabl.cabal +33/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Daniel Lovasko (c) 2016++All rights reserved.++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 Daniel Lovasko 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Text/Tabl.hs view
@@ -0,0 +1,51 @@+{- |+Module : Text.Tabl+Description : Table layout engine that provides alignment and decoration+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Text.Tabl arranges multiple Text instances into a table layout while+providing means of alignment, and visual decoration both horizontally+and vertically.+-}++module Text.Tabl+( Alignment(..)+, Decoration(..)+, Environment(..)+, tabl+) where++import qualified Data.Text as T++import Text.Tabl.Alignment+import Text.Tabl.Ascii+import Text.Tabl.Decoration+import Text.Tabl.Environment+import Text.Tabl.Latex+import Text.Tabl.Util+++-- | Create a table layout based on the specified output environment,+-- decorations and alignments.+tabl :: Environment -- ^ output environment+ -> Decoration -- ^ horizontal decoration+ -> Decoration -- ^ vertical decoration+ -> [Alignment] -- ^ column alignments+ -> [[T.Text]] -- ^ table cell data+ -> T.Text -- ^ final layout+tabl _ _ _ _ [] = T.empty+tabl _ _ _ _ [[]] = T.empty+tabl env hdecor vdecor aligns cells = render env hpres vpres ealigns ecells+ where+ render EnvAscii = ascii+ render EnvLatex = latex+ hpres = presence (length cells + 1) hdecor+ vpres = presence (length (head cells) + 1) vdecor+ columnCount = maximum $ map length cells+ ecells = map (extend columnCount T.empty) cells+ ealigns = extend columnCount AlignLeft aligns
+ src/Text/Tabl/Alignment.hs view
@@ -0,0 +1,24 @@+{- |+Module : Text.Tabl.Alignment+Description : Column alignments+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Definition of column alignment options.+-}++module Text.Tabl.Alignment+( Alignment(..)+) where++-- | Presentation style that is used to define the alignment of each+-- column of the table.+data Alignment+ = AlignLeft -- ^ left alignment+ | AlignCentre -- ^ centre+ | AlignRight -- ^ right alignment+ deriving (Show)
+ src/Text/Tabl/Ascii.hs view
@@ -0,0 +1,94 @@+{- |+Module : Text.Tabl.Ascii+Description : ASCII-art table rendering engine+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Implementation of the ASCII-art environment for table rendering.+-}++{-# LANGUAGE OverloadedStrings #-}++module Text.Tabl.Ascii+( ascii+) where++import Safe+import qualified Data.Text as T++import Text.Tabl.Alignment+import Text.Tabl.Util+++-- | Compute the greatest cell width of each column.+columnWidths :: [[T.Text]] -- ^ table cell data+ -> [Int] -- ^ column widths+columnWidths cells = foldr combine zeros cells+ where+ zeros = replicate (length $ head cells) 0+ combine = zipWith (\txt len -> max len (T.length txt))++-- | Convert decoration presence to actual decorator text.+verticalDecorators :: [Bool] -- ^ presence+ -> [T.Text] -- ^ decorators+verticalDecorators pres = [left $ head pres]+ ++ map mid (drop 1 $ init pres)+ ++ [right $ last pres]+ where+ left = bool "| " ""+ mid = bool " | " " "+ right = bool " |" ""++-- | Create the decorative horizontal line.+horizontalLine :: [T.Text] -- ^ first row+ -> [T.Text] -- ^ vertical decoration+ -> T.Text -- ^ horizontal line+horizontalLine frow vdecor = zipcat isects dashes+ where+ dashes = map (\cell -> T.replicate (T.length cell) "-") frow+ isects = map (T.map conv) vdecor+ conv c = lookupJustDef '?' c [(' ', '-'), ('|', '+')]++-- | Apply both vertical and horizontal decorations to the table.+applyDecoration :: [Bool] -- ^ horizontal decoration+ -> [Bool] -- ^ vertical decoration+ -> [[T.Text]] -- ^ table cell data+ -> [T.Text] -- ^ decorated rows+applyDecoration hpres vpres cells = intersperseOn rows hpres hline+ where+ vdecor = verticalDecorators vpres+ hline = horizontalLine (head cells) vdecor+ rows = map (zipcat vdecor) cells++-- | Align a cell content based on specified width and style.+alignCell :: Alignment -- ^ alignment style+ -> Int -- ^ width+ -> T.Text -- ^ text+ -> T.Text -- ^ aligned text+alignCell AlignLeft = flip T.justifyLeft ' '+alignCell AlignRight = flip T.justifyRight ' '+alignCell AlignCentre = flip T.center ' '++-- | Align each cell of the table based on the width and alignment of+-- the column it is in.+alignCells :: [[T.Text]] -- ^ table cell data+ -> [Int] -- ^ column widths+ -> [Alignment] -- ^ column alignments+ -> [[T.Text]] -- ^ aligned table cell data+alignCells cells widths aligns = map (zipWith3 alignCell aligns widths) cells++-- | Create a table layout using elements of ASCII art, thus making the table+-- suitable for the command line environment.+ascii :: [Bool] -- ^ horizontal decoration+ -> [Bool] -- ^ vertical decoration+ -> [Alignment] -- ^ column alignments+ -> [[T.Text]] -- ^ table cell data+ -> T.Text -- ^ table+ascii hpres vpres aligns cells = T.intercalate "\n" drows+ where+ drows = applyDecoration hpres vpres acells+ acells = alignCells cells (columnWidths cells) aligns
+ src/Text/Tabl/Decoration.hs view
@@ -0,0 +1,56 @@+{- |+Module : Text.Tabl.Decoration+Description : Horizontal and vertical decoration+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Definition of type combinators that are used to describe both horizontal+and vertical table decoration.+-}++module Text.Tabl.Decoration+( Decoration(..)+, presence+) where++-- | Decoration style that defines which lines (horizontal or vertical)+-- will be visible in the resulting table.+data Decoration+ = DecorNone -- ^ no lines+ | DecorAll -- ^ all lines+ | DecorInner -- ^ inner lines+ | DecorOuter -- ^ outer lines+ | DecorOnly [Int] -- ^ only certain lines+ | DecorExcept [Int] -- ^ all but certain lines+ | DecorUnion [Decoration] -- ^ union of more decorations+ | DecorIsect [Decoration] -- ^ intersection of more decorations+ deriving (Show)++-- | Convert a decoration to a list of presence information.+presence :: Int -- ^ width+ -> Decoration -- ^ decoration+ -> [Bool] -- ^ presence+presence n DecorNone = replicate n False+presence n DecorAll = replicate n True+presence n DecorInner = [False] ++ replicate (n-2) True ++ [False]+presence n DecorOuter = [True] ++ replicate (n-2) False ++ [True]+presence n (DecorOnly is) = map (`elem` is) [0..(n-1)]+presence n (DecorExcept is) = map not (presence n (DecorOnly is))+presence n (DecorUnion ds) = combine (||) False n ds+presence n (DecorIsect ds) = combine (&&) True n ds++-- | Combine multiple decorations into one based on a selected function.+combine :: (Bool -> Bool -> Bool) -- ^ combination function+ -> Bool -- ^ default value+ -> Int -- ^ width+ -> [Decoration] -- ^ decorations+ -> [Bool] -- ^ presence+combine fn def n ds = foldr step first presences+ where+ first = replicate n def+ step = zipWith fn+ presences = map (presence n) ds
+ src/Text/Tabl/Environment.hs view
@@ -0,0 +1,23 @@+{- |+Module : Text.Tabl.Environment+Description : Table environments+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Definition of various environments for table rendering.+-}++module Text.Tabl.Environment+( Environment(..)+) where++-- | Output environment that declares the way that the table will be+-- rendered.+data Environment+ = EnvAscii -- ^ ASCII-art suitable for the command-line+ | EnvLatex -- ^ LaTeX source code+ deriving (Show)
+ src/Text/Tabl/Latex.hs view
@@ -0,0 +1,56 @@+{- |+Module : Text.Tabl.Latex+Description : LaTeX table rendering engine+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Implementation of the LaTeX environment for table rendering.+-}++{-# LANGUAGE OverloadedStrings #-}++module Text.Tabl.Latex+( latex+) where++import qualified Data.Text as T++import Text.Tabl.Alignment+import Text.Tabl.Util+++-- | Convert the table cell data to LaTeX-compatible form.+createTable :: [[T.Text]] -- ^ table cells+ -> [T.Text] -- ^ latexified rows+createTable = map (flip T.append " \\\\" . T.intercalate " & ")++-- | Create the table header with vertical decoration and column+-- alignments.+alignSpecifier :: [Bool] -- ^ vertical decoration+ -> [Alignment] -- ^ column alignments+ -> T.Text -- ^ header+alignSpecifier vpres aligns = T.concat ["{ ", info, "}"]+ where+ info = T.concat $ intersperseOn letters vpres "| "+ letters = map letter aligns+ letter AlignLeft = "l "+ letter AlignRight = "r "+ letter AlignCentre = "c "++-- | Create a LaTeX-compatible source code that represents the requested+-- table layout.+latex :: [Bool] -- ^ horizontal decoration+ -> [Bool] -- ^ vertical decoration+ -> [Alignment] -- ^ column alignments+ -> [[T.Text]] -- ^ table cell data+ -> T.Text -- ^ final layout+latex hpres vpres aligns cells = T.concat+ [ "\\begin{tabular}"+ , alignSpecifier vpres aligns+ , "\n"+ , T.unlines $ intersperseOn (createTable cells) hpres "\\hline"+ , "\\end{tabular}" ]
+ src/Text/Tabl/Util.hs view
@@ -0,0 +1,55 @@+{- |+Module : Text.Tabl.Util+Description : Various utilities+Copyright : (c) Daniel Lovasko, 2016+License : BSD3++Maintainer : Daniel Lovasko <daniel.lovasko@gmail.com>+Stability : stable+Portability : portable++Set of general utilities that are used across the whole project.+-}++module Text.Tabl.Util+( bool+, extend+, intersperseOn+, zipcat+) where++-- | Extend a list to a defined length with one repeated element. This+-- function assumes that the list is shorter than the provided length.+extend :: Int -- ^ expected length+ -> a -- ^ element to pad with+ -> [a] -- ^ original list+ -> [a] -- ^ extended list+extend n x xs = xs ++ replicate (n - length xs) x++-- | Insert an element in front of the i-th position, if the i-th element+-- is True.+intersperseOn :: (Monoid a)+ => [a] -- ^ list+ -> [Bool] -- ^ insert rules+ -> a -- ^ element to insert+ -> [a] -- ^ new list+intersperseOn xs bs x = init $ concat $ zipWith glue bs (xs ++ [mempty])+ where+ glue True i = [x, i]+ glue False i = [i]++-- | Functional implementation of the if/then/else concept.+bool :: a -- ^ True option+ -> a -- ^ False option+ -> Bool -- ^ condition+ -> a -- ^ result+bool x _ True = x+bool _ y False = y++-- | Create an object by zipping two lists together. The second list is+-- expected to be one element shorter.+zipcat :: (Monoid a)+ => [a] -- ^ first list+ -> [a] -- ^ second list+ -> a -- ^ result+zipcat xs ys = mconcat $ zipWith mappend xs (mappend ys [mempty])
+ tabl.cabal view
@@ -0,0 +1,33 @@+name: tabl+version: 0.1.0.0+synopsis: Table layout+description: Text.Tabl arranges multiple Text instances into a+ table layout while providing means of alignment+ visual decoration both horizontally and vertically.+homepage: https://github.com/lovasko/tabl+license: BSD3+license-file: LICENSE+author: Daniel Lovasko <daniel.lovasko@gmail.com>+maintainer: Daniel Lovasko <daniel.lovasko@gmail.com>+copyright: 2016 Daniel Lovasko+category: Text+build-type: Simple+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Text.Tabl + other-modules: Text.Tabl.Alignment+ , Text.Tabl.Ascii+ , Text.Tabl.Decoration+ , Text.Tabl.Environment+ , Text.Tabl.Latex+ , Text.Tabl.Util+ build-depends: base >= 4.7 && < 5+ , safe+ , text+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/lovasko/tabl