packages feed

gridtables 0.0.1.0 → 0.0.2.0

raw patch · 4 files changed

+142/−31 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Text.GridTable.Trace: instance GHC.Classes.Eq Text.GridTable.Trace.GChar

Files

CHANGELOG.md view
@@ -2,9 +2,17 @@  `gridtables` uses [PVP Versioning][]. -## gridtables-0.0.1+## gridtables-0.0.2.0 -Release pending.+Released 2022-07-30.++-   Treat "combining" Unicode characters, such as the zero-width+    space or the word joiner, as having no width.+++## gridtables-0.0.1.0++Released 2022-07-29.  -   Boldly going where no Haskell library has gone before. 
gridtables.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                gridtables-version:             0.0.1.0+version:             0.0.2.0 synopsis:            Parser for reStructuredText-style grid tables. description:         Provides a parser for plain-text representations of                      tables. This package supports table headers, cells
src/Text/GridTable/Trace.hs view
@@ -26,7 +26,7 @@ import Data.Array.MArray import Data.Array.ST import Data.Function (on)-import Data.Maybe (fromMaybe, mapMaybe)+import Data.Maybe (fromMaybe) import Data.Set (Set) import Data.Text (Text) import Text.DocLayout (charWidth)@@ -49,7 +49,7 @@      else return $ tableFromTraceInfo traceInfo partSeps specs1  -- | Type used to represent the 2D layout of table characters-type CharGrid = Array (CharRow, CharCol) (Maybe Char)+type CharGrid = Array (CharRow, CharCol) GChar  -- | Index of a half-width character in the character-wise -- representation.@@ -65,19 +65,31 @@   deriving stock (Eq, Show)   deriving newtype (Enum, Ix, Num, Ord) --- | Converts a list of lines into an char array.+data GChar+  = C Char           -- ^ half- or full-width character+  | CZ [Char] Char   -- ^ character preceded by zero-width chars+  | WP               -- ^ padding for wide characters+  | Missing          -- ^ padding for short lines+  deriving stock (Eq)++-- | Converts a list of lines into a char array. toCharGrid :: [Text] -> CharGrid toCharGrid lines =-  let chars = foldr (\t m -> max m (T.length t)) 0 lines+  let chars = foldr (\t m -> max m (T.length t)) 0 lines -- potential overcount       gbounds = ( (CharRow 1, CharCol 1)                 , (CharRow (length lines), CharCol chars)                 )-      charList c = case charWidth c of-                     2 -> [Just c, Nothing]-                     _ -> [Just c]-      extendedLines = map ((\line -> take chars (line ++ repeat Nothing))-                            . concatMap charList . T.unpack)-                          lines+      toGChars []     = repeat Missing+      toGChars (c:cs) = case charWidth c of+        2 -> C c : WP : toGChars cs+        1 -> C c : toGChars cs+        _ -> case span ((== 0) . charWidth) cs of+               (zw, [])     -> [CZ (c:zw) '\0']+               (zw, c':cs') -> CZ (c:zw) c' :+                               case charWidth c' of+                                 2 -> WP : toGChars cs'+                                 _ -> toGChars cs'+      extendedLines = map (take chars . toGChars . T.unpack) lines   in listArray gbounds (mconcat extendedLines)  -- | Information on, and extracted from, a body separator line. This is a line@@ -111,8 +123,8 @@                -> CharGrid -> CharRow -> Maybe [ColSpec] colSpecsInLine c charGrid i =   case charGrid ! (i, firstCol) of-    Just '+' -> loop [] (firstCol + 1)-    _        -> Nothing+    C '+' -> loop [] (firstCol + 1)+    _     -> Nothing   where     loop acc j = case colSpecAt j of                    Nothing      -> Nothing@@ -128,7 +140,7 @@       | otherwise = case findEnd (j + 1) of           Nothing               -> Nothing           Just (end, rightMark) ->-            let leftMark = charGrid ! (i, j) == Just ':'+            let leftMark = charGrid ! (i, j) == C ':'                 align = case (leftMark, rightMark) of                   (False , False) -> AlignDefault                   (True  , False) -> AlignLeft@@ -141,11 +153,11 @@                   }             in pure (pure colspec)     findEnd j = case charGrid ! (i, j) of-      Just '+' -> pure (j, False)-      Just ':' -> if charGrid ! (i, j + 1) == Just '+'+      C '+' -> pure (j, False)+      C ':' -> if charGrid ! (i, j + 1) == C '+'                   then pure (j + 1, True)                   else Nothing-      Just c'+      C c'         | c' == c -> findEnd (j + 1)       _           -> Nothing @@ -162,8 +174,8 @@       c <- readArray mutGrid idx       -- convert `=` to `-` and remove alignment markers       case c of-        Just '=' -> writeArray mutGrid idx (Just '-')-        Just ':' -> writeArray mutGrid idx (Just '-')+        C '=' -> writeArray mutGrid idx (C '-')+        C ':' -> writeArray mutGrid idx (C '-')         _        -> pure ()   return mutGrid @@ -240,8 +252,8 @@     loop colseps j       | not (bounds charGrid `inRange` (top, j)) = Nothing       | otherwise = case charGrid ! (top, j) of-          Just '-' -> loop colseps (j + 1)-          Just '+' ->+          C '-' -> loop colseps (j + 1)+          C '+' ->             let colseps' = Set.insert j colseps             in case scanDown charGrid start j of                  Nothing -> loop colseps' (j + 1)@@ -265,7 +277,7 @@       if not (bounds charGrid `inRange` (i, right))       then Nothing       else case charGrid ! (i, right) of-             Just '+' ->+             C '+' ->                let rowseps' = Set.insert i rowseps                in case scanLeft charGrid start (i, right) of                     Nothing -> loop rowseps' (i + 1)@@ -274,7 +286,7 @@                            , rowseps' `Set.union` newrowseps                            , colseps                            )-             Just '|' -> loop rowseps (i + 1)+             C '|' -> loop rowseps (i + 1)              _ -> -- all but the final column must be terminated                if right == snd (snd (bounds charGrid))                then loop rowseps (i + 1)@@ -288,11 +300,11 @@   let  go :: CharCol -> Maybe ColSeps -> Maybe ColSeps        go _ Nothing = Nothing        go j (Just colseps) = case charGrid ! (bottom, j) of-                               Just '+' -> Just (Set.insert j colseps)-                               Just '-' -> Just colseps+                               C '+' -> Just (Set.insert j colseps)+                               C '-' -> Just colseps                                _        -> Nothing -  in if charGrid ! (bottom, left) /= Just '+'+  in if charGrid ! (bottom, left) /= C '+'      then Nothing      else        case foldr go (Just Set.empty) [(right - 1), right - 2 .. (left + 1)] of@@ -309,8 +321,8 @@   let go :: CharRow -> Maybe RowSeps -> Maybe RowSeps       go _ Nothing = Nothing       go i (Just rowseps) = case charGrid ! (i, left) of-                              Just '+' -> Just (Set.insert i rowseps)-                              Just '|' -> Just rowseps+                              C '+' -> Just (Set.insert i rowseps)+                              C '|' -> Just rowseps                               _        -> Nothing   in foldr go (Just Set.empty) [bottom - 1, bottom - 2 .. top + 1] @@ -319,7 +331,11 @@ getLines charGrid (top, left) (bottom, right) =   let rowIdxs = [top + 1 .. bottom - 1]       colIdxs = [left + 1 .. right - 1]-  in map (\ir -> T.pack $ mapMaybe (\ic -> charGrid ! (ir, ic)) colIdxs)+      toChars rowIdx colIdx = case charGrid ! (rowIdx, colIdx) of+        C c     -> [c]+        CZ zw c -> zw ++ [c]+        _       -> []+  in map (\ir -> T.pack $ concatMap (toChars ir) colIdxs)          rowIdxs  -- | Traced cell with raw contents and border positions.
test/test-gridtables.hs view
@@ -222,6 +222,93 @@                                      ]               }) +  , testGroup "Char widths"+    [ testCase "wide character" $+      let gt = T.unlines+               [ "+--+---+"+               , "|魚| x |"+               , "+--+---+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["魚"] , ContentCell 1 1 [" x "]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [2, 3]+                })++    , testCase "zero-width space" $+      let gt = T.unlines+               [ "+--+---+"+               , "|x\8203y| z |"+               , "+--+---+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["x\8203y"] , ContentCell 1 1 [" z "]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [2, 3]+                })++    , testCase "zero-width space after wide character" $+      let gt = T.unlines+               [ "+---+---+"+               , "|魚\8203y| z |"+               , "+---+---+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["魚\8203y"] , ContentCell 1 1 [" z "]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [3, 3]+                })++    , testCase "wide character after zero-width space" $+      let gt = T.unlines+               [ "+---+---+"+               , "|y\8203魚| z |"+               , "+---+---+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["y\8203魚"] , ContentCell 1 1 [" z "]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [3, 3]+                })++    , testCase "multiple zero-width characters" $+      let gt = T.unlines+               [ "+--+---+"+               , "|a\8204\8205b| c |"+               , "+--+---+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["a\8204\8205b"] , ContentCell 1 1 [" c "]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [2, 3]+                })++    , testCase "many wide chars" $+      let gt = T.unlines+               [ "+----------+-+"+               , "|12345|a|"+               , "+----------+-+"+               ]+      in parse' gridTable gt @?=+         Right (ArrayTable+                { arrayTableCells = listArray ((1,1), (1, 2))+                  [ ContentCell 1 1 ["12345"] , ContentCell 1 1 ["a"]]+                , arrayTableHead = Nothing+                , arrayTableColSpecs = defaultAlign [10, 1]+                })++    ]+   , testCase "unterminated row" $     let gt = T.unlines              [ "+-----+"