@@ -36,12 +36,23 @@ type Table = ([Cell], [[Cell]]) --header, body
3636addRow :: [Cell] -> Table -> Table
3737addRow cells (header,body) = (header, body ++ [cells])
3838
39−columnLocations :: Table -> [Int]
40−columnLocations (header, body) = foldl sizeFolder (head cellSizes) cellSizes
39+--calculate maximum per-row and per-column sizes
40+
41+cellLocations :: Table -> ([Int],[Int]) --column size, row size
42+cellLocations tab@(header, body) = (maxWidths, maxHeights)
43+ where
44+ cellSizeMatrix = cellSizes tab
45+ maxWidths = foldl mergeMax (baseSize (length cellSizeMatrix)) (map fst cellSizeMatrix)
46+ baseSize num = take num (repeat 0)
47+ rowHeights = map snd cellSizeMatrix
48+ maxHeights = map (L.maximumBy compare) rowHeights
49+ mergeMax a b = map (\(a,b) -> max a b) (zip a b)
50+
51+cellSizes :: Table -> [([Int], [Int])]
52+cellSizes (header, body) = map (\row -> (map maxRowWidth row, map (length . lines) row)) allRows
4153 where
42− cellSizes = map (\row -> map length row) (body ++ [header]) --bar padding
43− sizeFolder acc row = mergeMax row acc
44− mergeMax a b = map (\(x,y) -> if x > y then x else y) (zip a b)
54+ maxRowWidth row = L.maximumBy compare (map length (lines row))
55+ allRows = [header] ++ body
4556
4657relationAsTable :: Relation -> Table
4758relationAsTable rel@(Relation attributes tupleSet) = (header, body)
@@ -58,31 +69,38 @@ showAtom (IntAtom i) = show i
5869showAtom (RelationAtom rel) = renderTable $ relationAsTable rel
5970
6071renderTable :: Table -> String
61−renderTable table = renderHeader table colLocations ++ renderBody (snd table) colLocations
72+renderTable table = renderHeader table (fst cellLocs) ++ renderBody (snd table) cellLocs
6273 where
63− colLocations = columnLocations table
74+ cellLocs = cellLocations table
6475
6576renderHeader :: Table -> [Int] -> String
6677renderHeader (header, body) columnLocations = renderTopBar ++ renderHeaderNames ++ renderBottomBar ++ "\n"
6778 where
6879 renderTopBar = boxTL ++ concat (L.intersperse boxTB (map (\x -> repeatString x boxH) columnLocations)) ++ boxTR ++ "\n"
69− renderHeaderNames = renderRow header columnLocations boxV
80+ renderHeaderNames = renderRow header columnLocations 1 boxV
7081 renderBottomBar = if length body == 0 then ""
7182 else renderHBar boxLB boxC boxRB columnLocations
7283
7384renderHBar :: String -> String -> String -> [Int] -> String
7485renderHBar left middle end columnLocations = left ++ concat (L.intersperse middle (map (\x -> repeatString x boxH) columnLocations)) ++ end
7586
76−leftPaddedString :: Int -> String -> String
77−leftPaddedString size str = str ++ repeatString (size - length str) " "
87+leftPaddedString :: Int -> Int -> String -> String
88+leftPaddedString lineNum size str = paddedLines !! lineNum
89+ where
90+ paddedLines = map (\s -> s ++ repeatString (size - length s) " ") (lines str ++ repeat "")
7891
79−renderRow :: [Cell] -> [Int] -> String -> String
80−renderRow cells columnLocations interspersed = boxV ++ concat (L.intersperse interspersed (map (\(size, value) -> leftPaddedString size value) (zip columnLocations cells))) ++ boxV ++ "\n"
92+renderRow :: [Cell] -> [Int] -> Int -> String -> String
93+renderRow cells columnLocations rowHeight interspersed = unlines $ map renderOneLine [0..rowHeight-1]
94+ where
95+ renderOneLine lineNum = boxV ++ concat (L.intersperse interspersed (map (\(size, value) -> leftPaddedString lineNum size value) (zip columnLocations cells))) ++ boxV
8196
82−renderBody :: [[Cell]] -> [Int] -> String
83−renderBody cellMatrix columnLocations = renderRows ++ renderBottomBar
97+renderBody :: [[Cell]] -> ([Int],[Int]) -> String
98+renderBody cellMatrix cellLocations = renderRows ++ renderBottomBar
8499 where
85− renderRows = concat (map (\r-> renderRow r columnLocations boxV) cellMatrix)
100+ columnLocations = fst cellLocations
101+ rowLocations = snd cellLocations
102+ renderRows = concat (map (\(row, rowHeight)-> renderRow row columnLocations rowHeight boxV) rowHeightMatrix)
103+ rowHeightMatrix = zip cellMatrix (tail rowLocations)
86104 renderBottomBar = renderHBar boxBL boxBB boxBR columnLocations
87105
88106orderedAttributeNames :: Relation -> [AttributeName]
@@ -97,6 +115,7 @@ showRelation rel
97115 | rel == relationFalse = "false"
98116 | otherwise = renderTable (relationAsTable rel)
99117
100−
101118
119+simpleExample = s
120+groupedExample = case group (S.fromList ["CITY"]) "CITYREL" s of {Right rel -> rel}
102121