diff --git a/src/Text/Layout/Table.hs b/src/Text/Layout/Table.hs index d10e7d1..2d3b036 100644 --- a/src/Text/Layout/Table.hs +++ b/src/Text/Layout/Table.hs @@ -232,7 +232,7 @@ tableLines :: Cell a -> [RowGroup a] -- ^ Rows which form a cell together -> [String] tableLines specs TableStyle { .. } header rowGroups = - topLine : addHeaderLines (rowGroupLines ++ [bottomLine]) + maybe id (:) optTopLine . addHeaderLines $ maybe id (\b -> (++[b])) optBottomLine rowGroupLines where -- Helpers for horizontal lines that will put layout characters arround and -- in between a row of the pre-formatted grid. @@ -246,27 +246,28 @@ tableLines specs TableStyle { .. } header rowGroups = (sym', l) = let l' = length sym in if l' == 0 then (" ", 1) else (sym, l') -- Horizontal seperator lines that occur in a table. - topLine = hLineDetail realTopH realTopL realTopC realTopR $ fakeColumns realTopH - bottomLine = hLineDetail groupBottomH groupBottomL groupBottomC groupBottomR $ fakeColumns groupBottomH - groupSepLine = hLineDetail groupSepH groupSepLC groupSepC groupSepRC $ fakeColumns groupSepH - headerSepLine = hLineDetail headerSepH headerSepLC headerSepC headerSepRC $ fakeColumns headerSepH + optTopLine = optHorizontalDetailLine realTopH realTopL realTopC realTopR $ fakeColumns realTopH + optBottomLine = optHorizontalDetailLine groupBottomH groupBottomL groupBottomC groupBottomR $ fakeColumns groupBottomH + optGroupSepLine = optHorizontalDetailLine groupSepH groupSepLC groupSepC groupSepRC $ fakeColumns groupSepH + optHeaderSepLine = optHorizontalDetailLine headerSepH headerSepLC headerSepC headerSepRC $ fakeColumns headerSepH -- Vertical content lines - rowGroupLines = - intercalate [groupSepLine] $ map (map (hLineContent groupV) . applyRowMods . rows) rowGroups + rowGroupLines = maybe concat (\seps -> intercalate [seps]) optGroupSepLine linesPerRowGroup + linesPerRowGroup = map rowGroupToLines rowGroups + rowGroupToLines = map (horizontalContentLine groupV) . applyRowMods . rows -- Optional values for the header (addHeaderLines, fitHeaderIntoCMIs, realTopH, realTopL, realTopC, realTopR) = case header of HeaderHS headerColSpecs hTitles -> - let headerLine = hLineContent headerV (zipWith ($) headerRowMods hTitles) + let headerLine = horizontalContentLine headerV (zipWith ($) headerRowMods hTitles) headerRowMods = zipWith3 headerCellModifier headerColSpecs cMSs cMIs in - ( (headerLine :) . (headerSepLine :) + ( (headerLine :) . maybe id (:) optHeaderSepLine , fitTitlesCMI hTitles posSpecs , headerTopH , headerTopL diff --git a/src/Text/Layout/Table/Primitives/Table.hs b/src/Text/Layout/Table/Primitives/Table.hs index 2f37a3e..d91046b 100644 --- a/src/Text/Layout/Table/Primitives/Table.hs +++ b/src/Text/Layout/Table/Primitives/Table.hs @@ -1,7 +1,11 @@ -- | This module provides primitives for generating tables. Tables are generated -- line by line thus the functions in this module produce 'StringBuilder's that -- contain a line. -module Text.Layout.Table.Primitives.Table where +module Text.Layout.Table.Primitives.Table + ( horizontalDetailLine + , optHorizontalDetailLine + , horizontalContentLine + ) where import Data.List @@ -9,18 +13,33 @@ import Text.Layout.Table.StringBuilder import Text.Layout.Table.Spec.Util --- | Draw a horizontal line that will use the delimiters around the --- appropriately and visually separate by 'hSpace'. -hLineDetail +-- | Draw a horizontal line that will use the provided delimiters around +-- the content appropriately and visually separate by 'hSpace'. +-- +-- Return 'Nothing' if all delimiters are empty, and 'Just' otherwise. +optHorizontalDetailLine :: StringBuilder b => String -- ^ The space characters that are used as padding. -> String -- ^ The delimiter that is used on the left side. -> String -- ^ The delimiter that is used in between cells. - -> String -- ^ The delimiter that is sued on the right side. + -> String -- ^ The delimiter that is used on the right side. + -> Row b -- ^ A row of builders. + -> Maybe b -- ^ The formatted line as a 'StringBuilder', or Nothing if all delimiters are null. +optHorizontalDetailLine "" "" "" "" = const Nothing +optHorizontalDetailLine hSpace delimL delimM delimR = Just . horizontalDetailLine hSpace delimL delimM delimR + +-- | Draw a horizontal line that will use the provided delimiters around +-- the content appropriately and visually separate by 'hSpace'. +horizontalDetailLine + :: StringBuilder b + => String -- ^ The space characters that are used as padding. + -> String -- ^ The delimiter that is used on the left side. + -> String -- ^ The delimiter that is used in between cells. + -> String -- ^ The delimiter that is used on the right side. -> Row b -- ^ A row of builders. -> b -- ^ The formatted line as a 'StringBuilder'. -hLineDetail hSpace delimL delimM delimR cells = - mconcat $ intersperse (stringB hSpace) $ stringB delimL : intersperse (stringB delimM) cells ++ [stringB delimR] +horizontalDetailLine hSpace delimL delimM delimR cells = mconcat . intersperse (stringB hSpace) $ + stringB delimL : intersperse (stringB delimM) cells ++ [stringB delimR] -- | A simplified version of 'hLineDetail' that will use the same delimiter -- for everything. @@ -30,12 +49,12 @@ hLine -> String -- ^ The delimiter that is used for everything. -> Row b -- ^ A row of builders. -> b -- ^ The formatted line as a 'StringBuilder'. -hLine hSpace delim = hLineDetail hSpace delim delim delim +hLine hSpace delim = horizontalDetailLine hSpace delim delim delim -- | Render a line with actual content. -hLineContent +horizontalContentLine :: StringBuilder b => String -- ^ The delimiter that is used for everything. -> Row b -- ^ A row of builders. -> b -hLineContent = hLine " " +horizontalContentLine = hLine " "