@@ -9,6 +9,10 @@ import ProjectM36.Attribute hiding (null)
99import qualified Data.List as L
1010import qualified Data.Text as T
1111import Control.Arrow hiding (left)
12+import Data.Monoid
13+import Data.Char.WCWidth --guess the width that the character will appear as in the terminal
14+
15+import Debug.Trace
1216
1317boxV :: StringType
1418boxV = "│"
@@ -77,7 +81,7 @@ cellSizes (header, body) = map (map maxRowWidth &&& map (length . breakLines)) a
7781 0
7882 else
7983 L.maximum (lengths row)
80− lengths row = map T.length (breakLines row)
84+ lengths row = map stringDisplayLength (breakLines row)
8185 allRows = header : body
8286
8387relationAsTable :: Relation -> Table
@@ -102,6 +106,7 @@ showParens predicate f = if predicate then
102106showAtom :: Int -> Atom -> StringType
103107showAtom _ (RelationAtom rel) = renderTable $ relationAsTable rel
104108showAtom level (ConstructedAtom dConsName _ atoms) = showParens (level >= 1 && not (null atoms)) $ T.concat (L.intersperse " " (dConsName : map (showAtom 1) atoms))
109+showAtom _ (TextAtom t) = "\"" <> t <> "\""
105110showAtom _ atom = atomToText atom
106111
107112renderTable :: Table -> StringType
@@ -120,13 +125,14 @@ renderHeader (header, body) columnLocations = renderTopBar `T.append` renderHead
120125renderHBar :: StringType -> StringType -> StringType -> [Int] -> StringType
121126renderHBar left middle end columnLocations = left `T.append` T.concat (L.intersperse middle (map (`repeatString` boxH) columnLocations)) `T.append` end
122127
128+--pad a block of potentially multi-lined text
123129leftPaddedString :: Int -> Int -> StringType -> StringType
124130leftPaddedString lineNum size str = if lineNum > length paddedLines -1 then
125131 repeatString size " "
126132 else
127133 paddedLines !! lineNum
128134 where
129− paddedLines = map (\line -> line `T.append` repeatString (size - T.length line) " ") (breakLines str)
135+ paddedLines = map (\line -> line `T.append` repeatString (size - stringDisplayLength line) " ") (breakLines str)
130136
131137renderRow :: [Cell] -> [Int] -> Int -> StringType -> StringType
132138renderRow cells columnLocations rowHeight interspersed = T.unlines $ map renderOneLine [0..rowHeight-1]
@@ -147,3 +153,14 @@ repeatString c s = T.concat (replicate c s)
147153
148154showRelation :: Relation -> StringType
149155showRelation rel = renderTable (relationAsTable rel)
156+
157+--use wcwidth to guess the string width in the terminal- many CJK characters can take multiple columns in a fixed width font
158+stringDisplayLength :: StringType -> Int
159+stringDisplayLength = T.foldr charSize 0
160+ where
161+ charSize char accum = let w = wcwidth char in
162+ accum + if w < 0 then
163+ 1
164+ else
165+ w
166+