{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Data.KVITable.Render.ASCII
(
render
, RenderConfig(..)
, defaultRenderConfig
)
where
import qualified Data.List as L
import Data.Maybe ( fromMaybe, isNothing )
import Data.Text ( Text )
import qualified Data.Text as T
import Lens.Micro ( (^.) )
import qualified Prettyprinter as PP
import Data.KVITable
import Data.KVITable.Render
import Prelude hiding ( lookup )
render :: PP.Pretty v => RenderConfig -> KVITable v -> Text
render :: forall v. Pretty v => RenderConfig -> KVITable v -> Text
render RenderConfig
cfg KVITable v
t =
let kseq :: [Text]
kseq = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> KVITable v
t forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
(FmtLine
fmt, [Text]
hdr) = forall v.
Pretty v =>
RenderConfig -> KVITable v -> [Text] -> (FmtLine, [Text])
renderHdrs RenderConfig
cfg KVITable v
t [Text]
kseq
bdy :: [Text]
bdy = forall v.
Pretty v =>
RenderConfig -> FmtLine -> [Text] -> KVITable v -> [Text]
renderSeq RenderConfig
cfg FmtLine
fmt [Text]
kseq KVITable v
t
in [Text] -> Text
T.unlines forall a b. (a -> b) -> a -> b
$ [Text]
hdr forall a. Semigroup a => a -> a -> a
<> [Text]
bdy
data FmtLine = FmtLine [Int] Sigils Sigils
data Sigils = Sigils { Sigils -> Text
sep :: Text, Sigils -> Text
pad :: Text, Sigils -> Text
cap :: Text }
fmtLine :: [Int] -> FmtLine
fmtLine :: [Int] -> FmtLine
fmtLine [Int]
cols = [Int] -> Sigils -> Sigils -> FmtLine
FmtLine [Int]
cols
Sigils { sep :: Text
sep = Text
"|", pad :: Text
pad = Text
" ", cap :: Text
cap = Text
"_" }
Sigils { sep :: Text
sep = Text
"+", pad :: Text
pad = Text
"-", cap :: Text
cap = Text
"_" }
fmtColCnt :: FmtLine -> Int
fmtColCnt :: FmtLine -> Int
fmtColCnt (FmtLine [Int]
cols Sigils
_ Sigils
_) = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
cols
perColOvhd :: Int
perColOvhd :: Int
perColOvhd = Int
2
fmtWidth :: FmtLine -> Int
fmtWidth :: FmtLine -> Int
fmtWidth (FmtLine [Int]
cols Sigils
_ Sigils
_) =
let cols' :: [Int]
cols' = forall a. (a -> Bool) -> [a] -> [a]
L.filter (forall a. Eq a => a -> a -> Bool
/= Int
0) [Int]
cols
in forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
cols' forall a. Num a => a -> a -> a
+ ((Int
perColOvhd forall a. Num a => a -> a -> a
+ Int
1) forall a. Num a => a -> a -> a
* (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
cols' forall a. Num a => a -> a -> a
- Int
1))
fmtEmptyCols :: FmtLine -> Bool
fmtEmptyCols :: FmtLine -> Bool
fmtEmptyCols (FmtLine [Int]
cols Sigils
_ Sigils
_) = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
cols forall a. Eq a => a -> a -> Bool
== Int
0
fmtAddColLeft :: Int -> FmtLine -> FmtLine
fmtAddColLeft :: Int -> FmtLine -> FmtLine
fmtAddColLeft Int
leftCol (FmtLine [Int]
cols Sigils
s Sigils
s') = [Int] -> Sigils -> Sigils -> FmtLine
FmtLine (Int
leftCol forall a. a -> [a] -> [a]
: [Int]
cols) Sigils
s Sigils
s'
data FmtVal = Separator | TxtVal Text | CenterVal Text
fmtRender :: FmtLine -> [FmtVal] -> Text
fmtRender :: FmtLine -> [FmtVal] -> Text
fmtRender (FmtLine [] Sigils
_sigils Sigils
_sepsigils) [] = Text
""
fmtRender (FmtLine [Int]
cols Sigils
sigils Sigils
sepsigils) [FmtVal]
vals =
if forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
cols forall a. Eq a => a -> a -> Bool
== forall (t :: * -> *) a. Foldable t => t a -> Int
length [FmtVal]
vals
then let sig :: (Sigils -> t) -> FmtVal -> t
sig Sigils -> t
f FmtVal
o = case FmtVal
o of
FmtVal
Separator -> Sigils -> t
f Sigils
sepsigils
TxtVal Text
_ -> Sigils -> t
f Sigils
sigils
CenterVal Text
_ -> Sigils -> t
f Sigils
sigils
l :: Text
l = forall {t}. (Sigils -> t) -> FmtVal -> t
sig Sigils -> Text
sep forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [FmtVal]
vals
in Text
l forall a. Semigroup a => a -> a -> a
<>
[Text] -> Text
T.concat
[ forall {t}. (Sigils -> t) -> FmtVal -> t
sig Sigils -> Text
pad FmtVal
fld forall a. Semigroup a => a -> a -> a
<>
(case FmtVal
fld of
FmtVal
Separator -> [Char] -> Text
T.pack (forall a. Int -> a -> [a]
replicate Int
sz Char
'-')
TxtVal Text
v -> [Char] -> Text
T.pack (forall a. Int -> a -> [a]
replicate (Int
sz forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
v) Char
' ') forall a. Semigroup a => a -> a -> a
<> Text
v
CenterVal Text
t -> let (Int
w,Int
e) = (Int
sz forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
t forall a. Num a => a -> a -> a
- Int
2) forall a. Integral a => a -> a -> (a, a)
`divMod` Int
2
m :: Text
m = Sigils -> Text
cap Sigils
sigils
ls :: Text
ls = Int -> Text -> Text
T.replicate (Int
w forall a. Num a => a -> a -> a
+ Int
0) Text
m
rs :: Text
rs = Int -> Text -> Text
T.replicate (Int
w forall a. Num a => a -> a -> a
+ Int
e) Text
m
in if Text -> Int
T.length Text
t forall a. Num a => a -> a -> a
+ Int
2 forall a. Ord a => a -> a -> Bool
>= Int
sz
then (Int -> Text -> Text
T.replicate (Int
sz forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
t) Text
" ") forall a. Semigroup a => a -> a -> a
<> Text
t
else Text
ls forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
t forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
rs
) forall a. Semigroup a => a -> a -> a
<>
forall {t}. (Sigils -> t) -> FmtVal -> t
sig Sigils -> Text
pad FmtVal
fld forall a. Semigroup a => a -> a -> a
<>
forall {t}. (Sigils -> t) -> FmtVal -> t
sig Sigils -> Text
sep FmtVal
fld
| (Int
sz,FmtVal
fld) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
cols [FmtVal]
vals, Int
sz forall a. Eq a => a -> a -> Bool
/= Int
0
]
else forall a. HasCallStack => [Char] -> a
error ([Char]
"Insufficient arguments (" forall a. Semigroup a => a -> a -> a
<>
forall a. Show a => a -> [Char]
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [FmtVal]
vals) forall a. Semigroup a => a -> a -> a
<> [Char]
")" forall a. Semigroup a => a -> a -> a
<>
[Char]
" for FmtLine " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
cols))
data = HdrLine FmtLine HdrVals Trailer
type HdrVals = [FmtVal]
type Trailer = Text
hdrFmt :: HeaderLine -> FmtLine
hdrFmt :: HeaderLine -> FmtLine
hdrFmt (HdrLine FmtLine
fmt [FmtVal]
_ Text
_) = FmtLine
fmt
renderHdrs :: PP.Pretty v => RenderConfig -> KVITable v -> [Key] -> (FmtLine, [Text])
renderHdrs :: forall v.
Pretty v =>
RenderConfig -> KVITable v -> [Text] -> (FmtLine, [Text])
renderHdrs RenderConfig
cfg KVITable v
t [Text]
keys =
( FmtLine
lastFmt
, [ FmtLine -> [FmtVal] -> Text
fmtRender FmtLine
fmt [FmtVal]
hdrvals
forall a. Semigroup a => a -> a -> a
<> (if Text -> Bool
T.null Text
trailer then Text
"" else (Text
" <- " forall a. Semigroup a => a -> a -> a
<> Text
trailer))
| (HdrLine FmtLine
fmt [FmtVal]
hdrvals Text
trailer) <- [HeaderLine]
hrows
] forall a. Semigroup a => a -> a -> a
<>
[ FmtLine -> [FmtVal] -> Text
fmtRender FmtLine
lastFmt (forall a. Int -> a -> [a]
replicate (FmtLine -> Int
fmtColCnt FmtLine
lastFmt) FmtVal
Separator) ])
where
hrows :: [HeaderLine]
hrows = forall v.
Pretty v =>
RenderConfig -> KVITable v -> [Text] -> [HeaderLine]
hdrstep RenderConfig
cfg KVITable v
t [Text]
keys
lastFmt :: FmtLine
lastFmt = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HeaderLine]
hrows then [Int] -> FmtLine
fmtLine [] else HeaderLine -> FmtLine
hdrFmt forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [HeaderLine]
hrows
hdrstep :: PP.Pretty v => RenderConfig -> KVITable v -> [Key] -> [HeaderLine]
hdrstep :: forall v.
Pretty v =>
RenderConfig -> KVITable v -> [Text] -> [HeaderLine]
hdrstep RenderConfig
_cfg KVITable v
t [] =
let valcoltxt :: Text
valcoltxt = KVITable v
t forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) Text
valueColName
valcoltsz :: Int
valcoltsz = Text -> Int
T.length Text
valcoltxt
valsizes :: [Int]
valsizes = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
PP.pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall v. KVITable v -> [Item (KVITable v)]
toList KVITable v
t
valwidth :: Int
valwidth = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ Int
valcoltsz forall a. a -> [a] -> [a]
: [Int]
valsizes
in [ FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> FmtLine
fmtLine [Int
valwidth]) [Text -> FmtVal
TxtVal Text
valcoltxt] Text
"" ]
hdrstep RenderConfig
cfg KVITable v
t (Text
key:[Text]
keys) =
if RenderConfig -> Maybe Text
colStackAt RenderConfig
cfg forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just Text
key
then forall v.
Pretty v =>
RenderConfig -> KVITable v -> KeySpec -> [Text] -> [HeaderLine]
hdrvalstep RenderConfig
cfg KVITable v
t [] (Text
keyforall a. a -> [a] -> [a]
:[Text]
keys)
else
let keyw :: Int
keyw = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ( Text -> Int
T.length Text
key forall a. a -> [a] -> [a]
:
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Int
T.length (forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
t forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals) )
mkhdr :: ([HeaderLine], Text) -> HeaderLine -> ([HeaderLine], b)
mkhdr ([HeaderLine]
hs, Text
v) (HdrLine FmtLine
fmt [FmtVal]
hdrvals Text
trailer) =
( FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine (Int -> FmtLine -> FmtLine
fmtAddColLeft Int
keyw FmtLine
fmt) (Text -> FmtVal
TxtVal Text
v forall a. a -> [a] -> [a]
: [FmtVal]
hdrvals) Text
trailer forall a. a -> [a] -> [a]
: [HeaderLine]
hs , b
"")
in forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall {b}.
IsString b =>
([HeaderLine], Text) -> HeaderLine -> ([HeaderLine], b)
mkhdr ([], Text
key) forall a b. (a -> b) -> a -> b
$ forall v.
Pretty v =>
RenderConfig -> KVITable v -> [Text] -> [HeaderLine]
hdrstep RenderConfig
cfg KVITable v
t [Text]
keys
hdrvalstep :: PP.Pretty v => RenderConfig -> KVITable v -> KeySpec -> [Key] -> [HeaderLine]
hdrvalstep :: forall v.
Pretty v =>
RenderConfig -> KVITable v -> KeySpec -> [Text] -> [HeaderLine]
hdrvalstep RenderConfig
_ KVITable v
_ KeySpec
_ [] = forall a. HasCallStack => [Char] -> a
error [Char]
"ASCII hdrvalstep with empty keys after matching colStackAt -- impossible"
hdrvalstep RenderConfig
cfg KVITable v
t KeySpec
steppath (Text
key:[]) =
let titles :: [Text]
titles = [Text] -> [Text]
ordering forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
t forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
ordering :: [Text] -> [Text]
ordering = if RenderConfig -> Bool
sortKeyVals RenderConfig
cfg then [Text] -> [Text]
sortWithNums else forall a. a -> a
id
cvalWidths :: Text -> [Int]
cvalWidths Text
kv = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
PP.pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$
forall a. (a -> Bool) -> [a] -> [a]
L.filter ((forall a. Eq a => [a] -> [a] -> Bool
L.isSuffixOf (KeySpec
steppath forall a. Semigroup a => a -> a -> a
<> [(Text
key, Text
kv)])) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall a b. (a -> b) -> a -> b
$
forall v. KVITable v -> [Item (KVITable v)]
toList KVITable v
t
colWidth :: Text -> Int
colWidth Text
kv = let cvw :: [Int]
cvw = Text -> [Int]
cvalWidths Text
kv
in if forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ RenderConfig -> Bool
hideBlankCols RenderConfig
cfg, forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
cvw forall a. Eq a => a -> a -> Bool
== Int
0 ]
then Int
0
else forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
kv forall a. a -> [a] -> [a]
: [Int]
cvw
cwidths :: [Int]
cwidths = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Int
colWidth [Text]
titles
fmtcols :: [Int]
fmtcols = if RenderConfig -> Bool
equisizedCols RenderConfig
cfg
then (forall a. Int -> a -> [a]
replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
cwidths) (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Int]
cwidths))
else [Int]
cwidths
in [ FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> FmtLine
fmtLine forall a b. (a -> b) -> a -> b
$ [Int]
fmtcols) (Text -> FmtVal
TxtVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
titles) Text
key ]
hdrvalstep RenderConfig
cfg KVITable v
t KeySpec
steppath (Text
key:[Text]
keys) =
let vals :: [Text]
vals = [Text] -> [Text]
ordering forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
t forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
ordering :: [Text] -> [Text]
ordering = if RenderConfig -> Bool
sortKeyVals RenderConfig
cfg then [Text] -> [Text]
sortWithNums else forall a. a -> a
id
subhdrsV :: Text -> [HeaderLine]
subhdrsV Text
v = forall v.
Pretty v =>
RenderConfig -> KVITable v -> KeySpec -> [Text] -> [HeaderLine]
hdrvalstep RenderConfig
cfg KVITable v
t (KeySpec
steppath forall a. Semigroup a => a -> a -> a
<> [(Text
key,Text
v)]) [Text]
keys
subTtlHdrs :: [(Int, [HeaderLine])]
subTtlHdrs = let subAtVal :: Text -> (Int, [HeaderLine])
subAtVal Text
v = (Text -> Int
T.length Text
v, Text -> [HeaderLine]
subhdrsV Text
v)
in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> (Int, [HeaderLine])
subAtVal [Text]
vals
szexts :: [Int]
szexts = let subVW :: [HeaderLine] -> Int
subVW = FmtLine -> Int
fmtWidth forall b c a. (b -> c) -> (a -> b) -> a -> c
. HeaderLine -> FmtLine
hdrFmt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> a
head
subW :: (a, [HeaderLine]) -> (a, Int)
subW (a
hl,[HeaderLine]
sh) = let sv :: Int
sv = [HeaderLine] -> Int
subVW [HeaderLine]
sh
in if forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ RenderConfig -> Bool
hideBlankCols RenderConfig
cfg,
FmtLine -> Bool
fmtEmptyCols forall a b. (a -> b) -> a -> b
$ HeaderLine -> FmtLine
hdrFmt forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [HeaderLine]
sh
]
then (a
0, Int
0)
else (a
hl, Int
sv)
in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Ord a => a -> a -> a
max forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. Num a => (a, [HeaderLine]) -> (a, Int)
subW) [(Int, [HeaderLine])]
subTtlHdrs
rsz_extsubhdrs :: [HeaderLine]
rsz_extsubhdrs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {t :: * -> *}. Foldable t => t HeaderLine -> HeaderLine
hdrJoin forall a b. (a -> b) -> a -> b
$
forall a. [[a]] -> [[a]]
L.transpose forall a b. (a -> b) -> a -> b
$
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall {f :: * -> *}.
Functor f =>
Int -> f HeaderLine -> f HeaderLine
rsz_hdrstack) forall a b. (a -> b) -> a -> b
$
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
szhdrs forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(Int, [HeaderLine])]
subTtlHdrs
largest :: Int
largest = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Int]
szexts
szhdrs :: [Int]
szhdrs = if RenderConfig -> Bool
equisizedCols RenderConfig
cfg Bool -> Bool -> Bool
&& Bool -> Bool
not (RenderConfig -> Bool
hideBlankCols RenderConfig
cfg)
then forall a. Int -> a -> [a]
replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
vals) Int
largest
else [Int]
szexts
rsz_hdrstack :: Int -> f HeaderLine -> f HeaderLine
rsz_hdrstack Int
s f HeaderLine
vhs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> HeaderLine -> HeaderLine
rsz_hdrs Int
s) f HeaderLine
vhs
rsz_hdrs :: Int -> HeaderLine -> HeaderLine
rsz_hdrs Int
hw (HdrLine (FmtLine [Int]
c Sigils
s Sigils
j) [FmtVal]
v Text
r) =
let nzCols :: [Int]
nzCols = forall a. (a -> Bool) -> [a] -> [a]
L.filter (forall a. Eq a => a -> a -> Bool
/= Int
0) [Int]
c
pcw :: Int
pcw = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
nzCols forall a. Num a => a -> a -> a
+ ((Int
perColOvhd forall a. Num a => a -> a -> a
+ Int
1) forall a. Num a => a -> a -> a
* (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
nzCols forall a. Num a => a -> a -> a
- Int
1))
(Int
ew,Int
w0) = let l :: Int
l = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
nzCols
in if Int
l forall a. Eq a => a -> a -> Bool
== Int
0 then (Int
0,Int
0)
else forall a. Ord a => a -> a -> a
max Int
0 (Int
hw forall a. Num a => a -> a -> a
- Int
pcw) forall a. Integral a => a -> a -> (a, a)
`divMod` forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
nzCols
c' :: [Int]
c' = forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\([Int]
c'',Int
n) Int
w -> ([Int]
c''forall a. Semigroup a => a -> a -> a
<>[Int
nforall a. Num a => a -> a -> a
+Int
w],Int
ew)) ([],Int
ewforall a. Num a => a -> a -> a
+Int
w0) [Int]
c
in FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> Sigils -> Sigils -> FmtLine
FmtLine [Int]
c' Sigils
s Sigils
j) [FmtVal]
v Text
r
hdrJoin :: t HeaderLine -> HeaderLine
hdrJoin t HeaderLine
hl = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl HeaderLine -> HeaderLine -> HeaderLine
hlJoin (FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> FmtLine
fmtLine []) [] Text
"") t HeaderLine
hl
hlJoin :: HeaderLine -> HeaderLine -> HeaderLine
hlJoin (HdrLine (FmtLine [Int]
c Sigils
s Sigils
j) [FmtVal]
v Text
_) (HdrLine (FmtLine [Int]
c' Sigils
_ Sigils
_) [FmtVal]
v' Text
r) =
FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> Sigils -> Sigils -> FmtLine
FmtLine ([Int]
cforall a. Semigroup a => a -> a -> a
<>[Int]
c') Sigils
s Sigils
j) ([FmtVal]
vforall a. Semigroup a => a -> a -> a
<>[FmtVal]
v') Text
r
tvals :: [FmtVal]
tvals = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> FmtVal
CenterVal [Text]
vals
in FmtLine -> [FmtVal] -> Text -> HeaderLine
HdrLine ([Int] -> FmtLine
fmtLine [Int]
szhdrs) [FmtVal]
tvals Text
key forall a. a -> [a] -> [a]
: [HeaderLine]
rsz_extsubhdrs
renderSeq :: PP.Pretty v => RenderConfig -> FmtLine -> [Key] -> KVITable v -> [Text]
renderSeq :: forall v.
Pretty v =>
RenderConfig -> FmtLine -> [Text] -> KVITable v -> [Text]
renderSeq RenderConfig
cfg FmtLine
fmt [Text]
keys KVITable v
kvitbl = FmtLine -> [FmtVal] -> Text
fmtRender FmtLine
fmt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text] -> KeySpec -> [(Bool, [FmtVal])]
asciiRows [Text]
keys []
where
asciiRows :: [Key] -> KeySpec -> [ (Bool, [FmtVal]) ]
asciiRows :: [Text] -> KeySpec -> [(Bool, [FmtVal])]
asciiRows [] KeySpec
path =
let v :: Maybe v
v = forall v. KeySpec -> KVITable v -> Maybe v
lookup KeySpec
path KVITable v
kvitbl
skip :: Bool
skip = case Maybe v
v of
Maybe v
Nothing -> RenderConfig -> Bool
hideBlankRows RenderConfig
cfg
Just v
_ -> Bool
False
in if Bool
skip then []
else [ (Bool
False, [ forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> FmtVal
TxtVal Text
"") Text -> FmtVal
TxtVal ([Char] -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
PP.pretty forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe v
v) ]) ]
asciiRows (Text
key:[Text]
kseq) KeySpec
path
| RenderConfig -> Maybe Text
colStackAt RenderConfig
cfg forall a. Eq a => a -> a -> Bool
== forall a. a -> Maybe a
Just Text
key =
let filterOrDefaultBlankRows :: [(a, [Maybe Text])] -> [(a, [FmtVal])]
filterOrDefaultBlankRows =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe Text] -> [FmtVal]
defaultBlanks) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
if RenderConfig -> Bool
hideBlankRows RenderConfig
cfg
then forall a. (a -> Bool) -> [a] -> [a]
L.filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall a. Maybe a -> Bool
isNothing forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd)
else forall a. a -> a
id
defaultBlanks :: [Maybe Text] -> [FmtVal]
defaultBlanks = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Text
v -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> FmtVal
TxtVal Text
"") Text -> FmtVal
TxtVal Maybe Text
v)
in forall {a}. [(a, [Maybe Text])] -> [(a, [FmtVal])]
filterOrDefaultBlankRows forall a b. (a -> b) -> a -> b
$ [ (Bool
False, [Text] -> KeySpec -> [Maybe Text]
multivalRows (Text
keyforall a. a -> [a] -> [a]
:[Text]
kseq) KeySpec
path) ]
| Bool
otherwise =
let subrows :: Text -> [(Bool, [FmtVal])]
subrows Text
keyval = [Text] -> KeySpec -> [(Bool, [FmtVal])]
asciiRows [Text]
kseq forall a b. (a -> b) -> a -> b
$ KeySpec
path forall a. Semigroup a => a -> a -> a
<> [ (Text
key, Text
keyval) ]
grprow :: [(Bool, [FmtVal])] -> [(Bool, [FmtVal])]
grprow [(Bool, [FmtVal])]
subs = if Text
key forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` RenderConfig -> [Text]
rowGroup RenderConfig
cfg Bool -> Bool -> Bool
&& Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Bool, [FmtVal])]
subs)
then let subl :: [(Bool, [FmtVal])]
subl = [ (Bool
True, forall a. Int -> a -> [a]
replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [(Bool, [FmtVal])]
subs) FmtVal
Separator) ]
in if forall a b. (a, b) -> a
fst (forall a. [a] -> a
last [(Bool, [FmtVal])]
subs)
then forall a. [a] -> [a]
init [(Bool, [FmtVal])]
subs forall a. Semigroup a => a -> a -> a
<> [(Bool, [FmtVal])]
subl
else [(Bool, [FmtVal])]
subs forall a. Semigroup a => a -> a -> a
<> [(Bool, [FmtVal])]
subl
else [(Bool, [FmtVal])]
subs
addSubrows :: [(Bool, [FmtVal])] -> Text -> [(Bool, [FmtVal])]
addSubrows [(Bool, [FmtVal])]
ret Text
keyval = [(Bool, [FmtVal])]
ret forall a. Semigroup a => a -> a -> a
<> ([(Bool, [FmtVal])] -> [(Bool, [FmtVal])]
grprow forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall {a}.
([(a, [FmtVal])], Text) -> (a, [FmtVal]) -> ([(a, [FmtVal])], Text)
leftAdd ([],Text
keyval) forall a b. (a -> b) -> a -> b
$ Text -> [(Bool, [FmtVal])]
subrows Text
keyval)
leftAdd :: ([(a, [FmtVal])], Text) -> (a, [FmtVal]) -> ([(a, [FmtVal])], Text)
leftAdd ([(a, [FmtVal])]
acc,Text
kv) (a
b,[FmtVal]
subrow) = ([(a, [FmtVal])]
acc forall a. Semigroup a => a -> a -> a
<> [ (a
b, Text -> FmtVal
TxtVal Text
kv forall a. a -> [a] -> [a]
: [FmtVal]
subrow) ],
if RenderConfig -> Bool
rowRepeat RenderConfig
cfg then Text
kv else Text
"")
ordering :: [Text] -> [Text]
ordering = if RenderConfig -> Bool
sortKeyVals RenderConfig
cfg then [Text] -> [Text]
sortWithNums else forall a. a -> a
id
in forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [(Bool, [FmtVal])] -> Text -> [(Bool, [FmtVal])]
addSubrows [] forall a b. (a -> b) -> a -> b
$ [Text] -> [Text]
ordering forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
kvitbl forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
multivalRows :: [Key] -> KeySpec -> [ Maybe Text ]
multivalRows :: [Text] -> KeySpec -> [Maybe Text]
multivalRows (Text
key:[]) KeySpec
path =
let ordering :: [Text] -> [Text]
ordering = if RenderConfig -> Bool
sortKeyVals RenderConfig
cfg then [Text] -> [Text]
sortWithNums else forall a. a -> a
id
keyvals :: [Text]
keyvals = [Text] -> [Text]
ordering forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
kvitbl forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
showEnt :: v -> Text
showEnt = [Char] -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
PP.pretty
in (\Text
v -> (v -> Text
showEnt forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall v. KeySpec -> KVITable v -> Maybe v
lookup (KeySpec
path forall a. Semigroup a => a -> a -> a
<> [(Text
key,Text
v)]) KVITable v
kvitbl))) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
keyvals
multivalRows (Text
key:[Text]
kseq) KeySpec
path =
let ordering :: [Text] -> [Text]
ordering = if RenderConfig -> Bool
sortKeyVals RenderConfig
cfg then [Text] -> [Text]
sortWithNums else forall a. a -> a
id
keyvals :: [Text]
keyvals = [Text] -> [Text]
ordering forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> Maybe b
L.lookup Text
key forall a b. (a -> b) -> a -> b
$ KVITable v
kvitbl forall s a. s -> Getting a s a -> a
^. forall v. Lens' (KVITable v) [(Text, [Text])]
keyVals
in forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Text
v -> [Text] -> KeySpec -> [Maybe Text]
multivalRows [Text]
kseq (KeySpec
path forall a. Semigroup a => a -> a -> a
<> [(Text
key,Text
v)])) [Text]
keyvals
multivalRows [] KeySpec
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"multivalRows cannot be called with no keys!"