{-# LANGUAGE NoImplicitPrelude #-}
module Data.Aviation.Casa.AbbreviationsAndAcronyms.Render.Spacing(
Spacing
, HasSpacing(..)
, nameHeader
, meaningHeader
, sourceHeader
, scoreHeader
, standardSpacing
, mkSpacing
, (<->)
, exactWidthSpacing
) where
import Control.Category((.), id)
import Control.Lens(Lens', set, (^.))
import Data.Aviation.Casa.AbbreviationsAndAcronyms.Acronym(HasAcronym(name, meaning, source))
import Data.Aviation.Casa.AbbreviationsAndAcronyms.Render.Score(HasShowScore(showScore))
import Data.Eq(Eq)
import Data.Foldable(length, foldMap)
import Data.Function(($))
import Data.Functor(fmap)
import Data.Int(Int)
import Data.Monoid(Monoid(mappend, mempty))
import Data.Ord(Ord, max, min)
import Data.Semigroup(Semigroup((<>)))
import Data.String(String)
import Prelude(Show)
data Spacing =
Spacing
Int
Int
Int
Int
Int
deriving (Eq, Ord, Show)
mkSpacing ::
Int
-> Int
-> Int
-> Int
-> Int
-> Spacing
mkSpacing sep n m s r =
let b = max 1
in Spacing (b sep) (b n) (b m) (b s) (b r)
instance Semigroup Spacing where
Spacing a1 b1 c1 d1 e1 <> Spacing a2 b2 c2 d2 e2 =
Spacing (a1 `max` a2) (b1 `max` b2) (c1 `max` c2) (d1 `max` d2) (e1 `max` e2)
instance Monoid Spacing where
mappend =
(<>)
mempty =
mkSpacing 1 1 1 1 1
class HasSpacing a where
spacing ::
Lens'
a
Spacing
separatorSpacing ::
Lens'
a
Int
{-# INLINE separatorSpacing #-}
separatorSpacing =
spacing . separatorSpacing
nameSpacing ::
Lens'
a
Int
{-# INLINE nameSpacing #-}
nameSpacing =
spacing . nameSpacing
meaningSpacing ::
Lens'
a
Int
{-# INLINE meaningSpacing #-}
meaningSpacing =
spacing . meaningSpacing
sourceSpacing ::
Lens'
a
Int
{-# INLINE sourceSpacing #-}
sourceSpacing =
spacing . sourceSpacing
scoreSpacing ::
Lens'
a
Int
{-# INLINE scoreSpacing #-}
scoreSpacing =
spacing . scoreSpacing
instance HasSpacing Spacing where
spacing =
id
separatorSpacing
f (Spacing a b c d e) =
fmap (\x -> mkSpacing x b c d e) (f a)
nameSpacing
f (Spacing a b c d e) =
fmap (\x -> mkSpacing a x c d e) (f b)
meaningSpacing
f (Spacing a b c d e) =
fmap (\x -> mkSpacing a b x d e) (f c)
sourceSpacing
f (Spacing a b c d e) =
fmap (\x -> mkSpacing a b c x e) (f d)
scoreSpacing
f (Spacing a b c d e) =
fmap (\x -> mkSpacing a b c d x) (f e)
nameHeader ::
String
nameHeader =
"NAME"
meaningHeader ::
String
meaningHeader =
"MEANING"
sourceHeader ::
String
sourceHeader =
"SOURCE"
scoreHeader ::
String
scoreHeader =
"SCORE"
standardSpacing ::
Spacing
standardSpacing =
Spacing
1
(length nameHeader)
(length meaningHeader)
(length sourceHeader)
(length scoreHeader)
exactWidthSpacing ::
(HasShowScore a, HasAcronym a) =>
[a]
-> Spacing
exactWidthSpacing x =
standardSpacing <>
foldMap
(
\a ->
set nameSpacing (length (a ^. name)) .
set meaningSpacing (length (a ^. meaning)) .
set sourceSpacing (length (a ^. source)) .
set scoreSpacing (length (a ^. showScore))
$ mempty
) x
(<->) ::
Spacing
-> Spacing
-> Spacing
Spacing a1 b1 c1 d1 e1 <-> Spacing a2 b2 c2 d2 e2 =
Spacing (a1 `min` a2) (b1 `min` b2) (c1 `min` c2) (d1 `min` d2) (e1 `min` e2)