on master help sign in
add wcwidth module and detection of CJK multi-column characters (does it work on windows)

fix display of multibyte characters

commit8df53ba2bb7d0e9281953643ad39f2a7e8a2ac0d authorAgentM <agentm@themactionfaction.com> dateMon 9 Apr 2018, 12:47 (9 years ago) parent41d8517
3 files changed+21−3
project-m36.cabal+1 src/lib/ProjectM36/Atom.hs+1−1 src/lib/ProjectM36/Relation/Show/Term.hs+19−2
project-m36.cabal+1
@@ -57,6 +57,7 @@ Library
5757 ,time
5858 ,hashable-time
5959 ,old-locale
60+ ,wcwidth
6061 --used for CSV parsing
6162 ,attoparsec
6263 ,either
src/lib/ProjectM36/Atom.hs+1−1
@@ -15,7 +15,7 @@ atomToText :: Atom -> T.Text
1515atomToText (IntegerAtom i) = (T.pack . show) i
1616atomToText (IntAtom i) = (T.pack . show) i
1717atomToText (DoubleAtom i) = (T.pack . show) i
18−atomToText (TextAtom i) = (T.pack . show) i --does this break quoting in CSV export?
18+atomToText (TextAtom i) = i --does this break quoting in CSV export?
1919atomToText (DayAtom i) = (T.pack . show) i
2020atomToText (DateTimeAtom i) = (T.pack . show) i
2121atomToText (ByteStringAtom i) = (T.pack . show) i
src/lib/ProjectM36/Relation/Show/Term.hs+19−2
@@ -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+