{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}
module IntervalAlgebra.IntervalDiagram
(
parseIntervalDiagram
, simpleIntervalDiagram
, standardExampleDiagram
, IntervalDiagramOptions(..)
, defaultIntervalDiagramOptions
, AxisPlacement(..)
, IntervalText
, IntervalDiagram
, IntervalTextLineParseError(..)
, AxisParseError(..)
, IntervalDiagramOptionsError(..)
, IntervalDiagramParseError(..)
, Prettyprinter.Pretty(..)
) where
import Data.Foldable (Foldable (toList))
import qualified Data.List.NonEmpty as NE hiding (toList)
import Data.Maybe (fromMaybe, isNothing)
import Data.Text (Text, pack)
import IntervalAlgebra.Core
import IntervalAlgebra.IntervalUtilities (rangeInterval)
import IntervalAlgebra.PairedInterval (PairedInterval, getPairData,
makePairedInterval)
import Prettyprinter
newtype IntervalText a = MkIntervalText (PairedInterval Char a) deriving (IntervalText a -> IntervalText a -> Bool
(IntervalText a -> IntervalText a -> Bool)
-> (IntervalText a -> IntervalText a -> Bool)
-> Eq (IntervalText a)
forall a. Eq a => IntervalText a -> IntervalText a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalText a -> IntervalText a -> Bool
$c/= :: forall a. Eq a => IntervalText a -> IntervalText a -> Bool
== :: IntervalText a -> IntervalText a -> Bool
$c== :: forall a. Eq a => IntervalText a -> IntervalText a -> Bool
Eq, Int -> IntervalText a -> ShowS
[IntervalText a] -> ShowS
IntervalText a -> String
(Int -> IntervalText a -> ShowS)
-> (IntervalText a -> String)
-> ([IntervalText a] -> ShowS)
-> Show (IntervalText a)
forall a. (Show a, Ord a) => Int -> IntervalText a -> ShowS
forall a. (Show a, Ord a) => [IntervalText a] -> ShowS
forall a. (Show a, Ord a) => IntervalText a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalText a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [IntervalText a] -> ShowS
show :: IntervalText a -> String
$cshow :: forall a. (Show a, Ord a) => IntervalText a -> String
showsPrec :: Int -> IntervalText a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> IntervalText a -> ShowS
Show)
makeIntervalText :: Char -> Interval a -> IntervalText a
makeIntervalText :: Char -> Interval a -> IntervalText a
makeIntervalText Char
c = PairedInterval Char a -> IntervalText a
forall a. PairedInterval Char a -> IntervalText a
MkIntervalText (PairedInterval Char a -> IntervalText a)
-> (Interval a -> PairedInterval Char a)
-> Interval a
-> IntervalText a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Interval a -> PairedInterval Char a
forall b a. b -> Interval a -> PairedInterval b a
makePairedInterval Char
c
instance Intervallic IntervalText where
getInterval :: IntervalText a -> Interval a
getInterval (MkIntervalText PairedInterval Char a
x) = PairedInterval Char a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval PairedInterval Char a
x
setInterval :: IntervalText a -> Interval b -> IntervalText b
setInterval (MkIntervalText PairedInterval Char a
x) Interval b
i = PairedInterval Char b -> IntervalText b
forall a. PairedInterval Char a -> IntervalText a
MkIntervalText (PairedInterval Char b -> IntervalText b)
-> PairedInterval Char b -> IntervalText b
forall a b. (a -> b) -> a -> b
$ PairedInterval Char a -> Interval b -> PairedInterval Char b
forall (i :: * -> *) a b. Intervallic i => i a -> Interval b -> i b
setInterval PairedInterval Char a
x Interval b
i
instance (Enum (Moment (Interval a)), SizedIv (Interval a)) => Pretty (IntervalText a) where
pretty :: IntervalText a -> Doc ann
pretty (MkIntervalText PairedInterval Char a
x) = String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Moment (Interval a) -> Int
forall a. Enum a => a -> Int
fromEnum (Interval a -> Moment (Interval a)
forall iv. SizedIv iv => iv -> Moment iv
duration Interval a
i)) Char
c
where
c :: Char
c = PairedInterval Char a -> Char
forall b a. PairedInterval b a -> b
getPairData PairedInterval Char a
x
i :: Interval a
i = PairedInterval Char a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval PairedInterval Char a
x
data IntervalTextLine a = MkIntervalTextLine [IntervalText a] [Text]
deriving Int -> IntervalTextLine a -> ShowS
[IntervalTextLine a] -> ShowS
IntervalTextLine a -> String
(Int -> IntervalTextLine a -> ShowS)
-> (IntervalTextLine a -> String)
-> ([IntervalTextLine a] -> ShowS)
-> Show (IntervalTextLine a)
forall a. (Show a, Ord a) => Int -> IntervalTextLine a -> ShowS
forall a. (Show a, Ord a) => [IntervalTextLine a] -> ShowS
forall a. (Show a, Ord a) => IntervalTextLine a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalTextLine a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [IntervalTextLine a] -> ShowS
show :: IntervalTextLine a -> String
$cshow :: forall a. (Show a, Ord a) => IntervalTextLine a -> String
showsPrec :: Int -> IntervalTextLine a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> IntervalTextLine a -> ShowS
Show
instance Pretty (IntervalTextLine Int) where
pretty :: IntervalTextLine Int -> Doc ann
pretty (MkIntervalTextLine [IntervalText Int]
ivs [Text]
_) =
(Doc ann -> Doc ann -> Doc ann) -> [Doc ann] -> Doc ann
forall (t :: * -> *) ann.
Foldable t =>
(Doc ann -> Doc ann -> Doc ann) -> t (Doc ann) -> Doc ann
concatWith Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
(<>) ((IntervalText Int -> Doc ann) -> [IntervalText Int] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\IntervalText Int
x -> Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent (IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin IntervalText Int
x) (IntervalText Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalText Int
x)) [IntervalText Int]
ivs)
instance Pretty (Either IntervalTextLineParseError (IntervalTextLine Int)) where
pretty :: Either IntervalTextLineParseError (IntervalTextLine Int) -> Doc ann
pretty (Left IntervalTextLineParseError
e) = String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ IntervalTextLineParseError -> String
forall a. Show a => a -> String
show IntervalTextLineParseError
e
pretty (Right IntervalTextLine Int
l) = IntervalTextLine Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalTextLine Int
l
data IntervalTextLineParseError =
ConcurringIntervals
| UnsortedIntervals
| BeginsLessThanZero
deriving (IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
(IntervalTextLineParseError -> IntervalTextLineParseError -> Bool)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Bool)
-> Eq IntervalTextLineParseError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c/= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
== :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c== :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
Eq, Int -> IntervalTextLineParseError -> ShowS
[IntervalTextLineParseError] -> ShowS
IntervalTextLineParseError -> String
(Int -> IntervalTextLineParseError -> ShowS)
-> (IntervalTextLineParseError -> String)
-> ([IntervalTextLineParseError] -> ShowS)
-> Show IntervalTextLineParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalTextLineParseError] -> ShowS
$cshowList :: [IntervalTextLineParseError] -> ShowS
show :: IntervalTextLineParseError -> String
$cshow :: IntervalTextLineParseError -> String
showsPrec :: Int -> IntervalTextLineParseError -> ShowS
$cshowsPrec :: Int -> IntervalTextLineParseError -> ShowS
Show, Eq IntervalTextLineParseError
Eq IntervalTextLineParseError
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Ordering)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Bool)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Bool)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Bool)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> Bool)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError)
-> (IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError)
-> Ord IntervalTextLineParseError
IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
IntervalTextLineParseError
-> IntervalTextLineParseError -> Ordering
IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError
$cmin :: IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError
max :: IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError
$cmax :: IntervalTextLineParseError
-> IntervalTextLineParseError -> IntervalTextLineParseError
>= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c>= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
> :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c> :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
<= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c<= :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
< :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
$c< :: IntervalTextLineParseError -> IntervalTextLineParseError -> Bool
compare :: IntervalTextLineParseError
-> IntervalTextLineParseError -> Ordering
$ccompare :: IntervalTextLineParseError
-> IntervalTextLineParseError -> Ordering
$cp1Ord :: Eq IntervalTextLineParseError
Ord)
parseIntervalTextLine
:: [Text]
-> [IntervalText Int]
-> Either IntervalTextLineParseError (IntervalTextLine Int)
parseIntervalTextLine :: [Text]
-> [IntervalText Int]
-> Either IntervalTextLineParseError (IntervalTextLine Int)
parseIntervalTextLine [Text]
labs [IntervalText Int]
l =
let vals :: Maybe (NonEmpty (IntervalText Int))
vals = [IntervalText Int] -> Maybe (NonEmpty (IntervalText Int))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [IntervalText Int]
l
in if
| ((IntervalText Int, IntervalText Int) -> Bool)
-> [(IntervalText Int, IntervalText Int)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((IntervalText Int -> IntervalText Int -> Bool)
-> (IntervalText Int, IntervalText Int) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry IntervalText Int -> IntervalText Int -> Bool
forall a (i0 :: * -> *) (i1 :: * -> *).
(SizedIv (Interval a), Ord a, Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
concur) ([IntervalText Int] -> [(IntervalText Int, IntervalText Int)]
forall t. [t] -> [(t, t)]
pairs [IntervalText Int]
l) -> IntervalTextLineParseError
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. a -> Either a b
Left IntervalTextLineParseError
ConcurringIntervals
| (Bool -> Bool
not (Bool -> Bool)
-> ([IntervalText Int] -> Bool) -> [IntervalText Int] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Interval Int] -> Bool
forall a. Ord a => [a] -> Bool
isSorted ([Interval Int] -> Bool)
-> ([IntervalText Int] -> [Interval Int])
-> [IntervalText Int]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IntervalText Int -> Interval Int)
-> [IntervalText Int] -> [Interval Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntervalText Int -> Interval Int
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval) [IntervalText Int]
l -> IntervalTextLineParseError
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. a -> Either a b
Left IntervalTextLineParseError
UnsortedIntervals
| (IntervalText Int -> Bool) -> [IntervalText Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (Int -> Bool)
-> (IntervalText Int -> Int) -> IntervalText Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin) [IntervalText Int]
l -> IntervalTextLineParseError
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. a -> Either a b
Left IntervalTextLineParseError
BeginsLessThanZero
| Bool
otherwise -> case Maybe (NonEmpty (IntervalText Int))
vals of
Maybe (NonEmpty (IntervalText Int))
Nothing -> IntervalTextLine Int
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. b -> Either a b
Right ([IntervalText Int] -> [Text] -> IntervalTextLine Int
forall a. [IntervalText a] -> [Text] -> IntervalTextLine a
MkIntervalTextLine [] [])
Just NonEmpty (IntervalText Int)
v ->
IntervalTextLine Int
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. b -> Either a b
Right (IntervalTextLine Int
-> Either IntervalTextLineParseError (IntervalTextLine Int))
-> IntervalTextLine Int
-> Either IntervalTextLineParseError (IntervalTextLine Int)
forall a b. (a -> b) -> a -> b
$ [IntervalText Int] -> [Text] -> IntervalTextLine Int
forall a. [IntervalText a] -> [Text] -> IntervalTextLine a
MkIntervalTextLine (NonEmpty (IntervalText Int) -> [IntervalText Int]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty (IntervalText Int) -> NonEmpty (IntervalText Int)
makeIntervalLine NonEmpty (IntervalText Int)
v)) [Text]
labs
where
makeIntervalLine
:: NE.NonEmpty (IntervalText Int) -> NE.NonEmpty (IntervalText Int)
makeIntervalLine :: NonEmpty (IntervalText Int) -> NonEmpty (IntervalText Int)
makeIntervalLine NonEmpty (IntervalText Int)
x =
NonEmpty (IntervalText Int) -> IntervalText Int
forall a. NonEmpty a -> a
NE.head NonEmpty (IntervalText Int)
x IntervalText Int
-> [IntervalText Int] -> NonEmpty (IntervalText Int)
forall a. a -> [a] -> NonEmpty a
NE.:| (IntervalText Int -> IntervalText Int -> IntervalText Int)
-> [IntervalText Int] -> [IntervalText Int] -> [IntervalText Int]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith IntervalText Int -> IntervalText Int -> IntervalText Int
forall a (i1 :: * -> *) (i0 :: * -> *).
(Num a, SizedIv (Interval a), Intervallic i1, Intervallic i0) =>
i0 a -> i1 a -> i1 a
shiftFromEnd (NonEmpty (IntervalText Int) -> [IntervalText Int]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (IntervalText Int)
x) (NonEmpty (IntervalText Int) -> [IntervalText Int]
forall a. NonEmpty a -> [a]
NE.tail NonEmpty (IntervalText Int)
x)
pairs :: [t] -> [(t, t)]
pairs = [t] -> [(t, t)]
forall t. [t] -> [(t, t)]
go
where
go :: [t] -> [(t, t)]
go [] = []
go (t
x : [t]
xs) = (t -> (t, t)) -> [t] -> [(t, t)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t
x, ) [t]
xs [(t, t)] -> [(t, t)] -> [(t, t)]
forall a. Semigroup a => a -> a -> a
<> [t] -> [(t, t)]
go [t]
xs
isSorted :: [a] -> Bool
isSorted [a]
xs = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> [Bool] -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> a -> Bool) -> [a] -> [a] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(<=) [a]
xs ([a] -> [a]
forall a. [a] -> [a]
tail [a]
xs)
data AxisPlacement =
Top
| Bottom deriving (AxisPlacement -> AxisPlacement -> Bool
(AxisPlacement -> AxisPlacement -> Bool)
-> (AxisPlacement -> AxisPlacement -> Bool) -> Eq AxisPlacement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AxisPlacement -> AxisPlacement -> Bool
$c/= :: AxisPlacement -> AxisPlacement -> Bool
== :: AxisPlacement -> AxisPlacement -> Bool
$c== :: AxisPlacement -> AxisPlacement -> Bool
Eq, Int -> AxisPlacement -> ShowS
[AxisPlacement] -> ShowS
AxisPlacement -> String
(Int -> AxisPlacement -> ShowS)
-> (AxisPlacement -> String)
-> ([AxisPlacement] -> ShowS)
-> Show AxisPlacement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AxisPlacement] -> ShowS
$cshowList :: [AxisPlacement] -> ShowS
show :: AxisPlacement -> String
$cshow :: AxisPlacement -> String
showsPrec :: Int -> AxisPlacement -> ShowS
$cshowsPrec :: Int -> AxisPlacement -> ShowS
Show)
newtype AxisLabels = MkAxisLabels (NE.NonEmpty (Int, Char))
deriving (AxisLabels -> AxisLabels -> Bool
(AxisLabels -> AxisLabels -> Bool)
-> (AxisLabels -> AxisLabels -> Bool) -> Eq AxisLabels
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AxisLabels -> AxisLabels -> Bool
$c/= :: AxisLabels -> AxisLabels -> Bool
== :: AxisLabels -> AxisLabels -> Bool
$c== :: AxisLabels -> AxisLabels -> Bool
Eq, Int -> AxisLabels -> ShowS
[AxisLabels] -> ShowS
AxisLabels -> String
(Int -> AxisLabels -> ShowS)
-> (AxisLabels -> String)
-> ([AxisLabels] -> ShowS)
-> Show AxisLabels
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AxisLabels] -> ShowS
$cshowList :: [AxisLabels] -> ShowS
show :: AxisLabels -> String
$cshow :: AxisLabels -> String
showsPrec :: Int -> AxisLabels -> ShowS
$cshowsPrec :: Int -> AxisLabels -> ShowS
Show)
data AxisConfig = MkAxisConfig
{ AxisConfig -> Maybe AxisPlacement
placement :: Maybe AxisPlacement
, AxisConfig -> Maybe AxisLabels
labels :: Maybe AxisLabels
}
deriving (AxisConfig -> AxisConfig -> Bool
(AxisConfig -> AxisConfig -> Bool)
-> (AxisConfig -> AxisConfig -> Bool) -> Eq AxisConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AxisConfig -> AxisConfig -> Bool
$c/= :: AxisConfig -> AxisConfig -> Bool
== :: AxisConfig -> AxisConfig -> Bool
$c== :: AxisConfig -> AxisConfig -> Bool
Eq, Int -> AxisConfig -> ShowS
[AxisConfig] -> ShowS
AxisConfig -> String
(Int -> AxisConfig -> ShowS)
-> (AxisConfig -> String)
-> ([AxisConfig] -> ShowS)
-> Show AxisConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AxisConfig] -> ShowS
$cshowList :: [AxisConfig] -> ShowS
show :: AxisConfig -> String
$cshow :: AxisConfig -> String
showsPrec :: Int -> AxisConfig -> ShowS
$cshowsPrec :: Int -> AxisConfig -> ShowS
Show)
intMapList :: NE.NonEmpty (Int, a) -> NE.NonEmpty (Int, a)
intMapList :: NonEmpty (Int, a) -> NonEmpty (Int, a)
intMapList = ((Int, a) -> (Int, a) -> Ordering)
-> NonEmpty (Int, a) -> NonEmpty (Int, a)
forall a. (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a
NE.sortBy (\(Int
k, a
_) (Int
k', a
_) -> Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
k Int
k')
(NonEmpty (Int, a) -> NonEmpty (Int, a))
-> (NonEmpty (Int, a) -> NonEmpty (Int, a))
-> NonEmpty (Int, a)
-> NonEmpty (Int, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, a) -> (Int, a) -> Bool)
-> NonEmpty (Int, a) -> NonEmpty (Int, a)
forall a. (a -> a -> Bool) -> NonEmpty a -> NonEmpty a
NE.nubBy (\(Int
k, a
_) (Int
k', a
_) -> Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k')
prettyAxisLabels :: AxisPlacement -> AxisLabels -> [Doc ann]
prettyAxisLabels :: AxisPlacement -> AxisLabels -> [Doc ann]
prettyAxisLabels AxisPlacement
pos (MkAxisLabels NonEmpty (Int, Char)
labs) = do
let labssorted :: NonEmpty (Int, Char)
labssorted = NonEmpty (Int, Char) -> NonEmpty (Int, Char)
forall a. NonEmpty (Int, a) -> NonEmpty (Int, a)
intMapList NonEmpty (Int, Char)
labs
let ints :: NonEmpty Int
ints = ((Int, Char) -> Int) -> NonEmpty (Int, Char) -> NonEmpty Int
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NE.map (Int, Char) -> Int
forall a b. (a, b) -> a
fst NonEmpty (Int, Char)
labssorted
let marks :: String
marks = NonEmpty Char -> String
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Char -> String) -> NonEmpty Char -> String
forall a b. (a -> b) -> a -> b
$ ((Int, Char) -> Char) -> NonEmpty (Int, Char) -> NonEmpty Char
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NE.map (Int, Char) -> Char
forall a b. (a, b) -> b
snd NonEmpty (Int, Char)
labssorted
let labPos :: [Int]
labPos =
NonEmpty Int -> Int
forall a. NonEmpty a -> a
NE.head NonEmpty Int
ints Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (Int -> Int -> Int) -> [Int] -> [Int] -> [Int]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Int
x Int
y -> Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (NonEmpty Int -> [Int]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Int
ints) (NonEmpty Int -> [Int]
forall a. NonEmpty a -> [a]
NE.tail NonEmpty Int
ints)
let out :: [Doc ann]
out =
[ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
hcat ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (Int -> Doc ann) -> [Int] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Int
i -> Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent Int
i (Char -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Char
'|')) [Int]
labPos
, [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
hcat ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (Int -> Doc ann -> Doc ann) -> [Int] -> [Doc ann] -> [Doc ann]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent [Int]
labPos (Char -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Char -> Doc ann) -> String -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
marks)
]
case AxisPlacement
pos of
AxisPlacement
Top -> [Doc ann] -> [Doc ann]
forall a. [a] -> [a]
reverse [Doc ann]
out
AxisPlacement
Bottom -> [Doc ann]
out
data Axis = MkAxis
{ Axis -> IntervalText Int
refInterval :: IntervalText Int
, Axis -> AxisConfig
config :: AxisConfig
}
deriving (Axis -> Axis -> Bool
(Axis -> Axis -> Bool) -> (Axis -> Axis -> Bool) -> Eq Axis
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Axis -> Axis -> Bool
$c/= :: Axis -> Axis -> Bool
== :: Axis -> Axis -> Bool
$c== :: Axis -> Axis -> Bool
Eq, Int -> Axis -> ShowS
[Axis] -> ShowS
Axis -> String
(Int -> Axis -> ShowS)
-> (Axis -> String) -> ([Axis] -> ShowS) -> Show Axis
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Axis] -> ShowS
$cshowList :: [Axis] -> ShowS
show :: Axis -> String
$cshow :: Axis -> String
showsPrec :: Int -> Axis -> ShowS
$cshowsPrec :: Int -> Axis -> ShowS
Show)
instance Pretty Axis where
pretty :: Axis -> Doc ann
pretty (MkAxis IntervalText Int
ref (MkAxisConfig Maybe AxisPlacement
Nothing Maybe AxisLabels
_ )) = Doc ann
forall ann. Doc ann
emptyDoc
pretty (MkAxis IntervalText Int
ref (MkAxisConfig (Just AxisPlacement
_) Maybe AxisLabels
Nothing)) = IntervalText Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalText Int
ref
pretty (MkAxis IntervalText Int
ref (MkAxisConfig (Just AxisPlacement
Bottom) (Just AxisLabels
labels))) =
[Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vcat ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ IntervalText Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalText Int
ref Doc ann -> [Doc ann] -> [Doc ann]
forall a. a -> [a] -> [a]
: AxisPlacement -> AxisLabels -> [Doc ann]
forall ann. AxisPlacement -> AxisLabels -> [Doc ann]
prettyAxisLabels AxisPlacement
Bottom AxisLabels
labels
pretty (MkAxis IntervalText Int
ref (MkAxisConfig (Just AxisPlacement
Top) (Just AxisLabels
labels))) =
[Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vcat ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ AxisPlacement -> AxisLabels -> [Doc ann]
forall ann. AxisPlacement -> AxisLabels -> [Doc ann]
prettyAxisLabels AxisPlacement
Top AxisLabels
labels [Doc ann] -> [Doc ann] -> [Doc ann]
forall a. [a] -> [a] -> [a]
++ [IntervalText Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalText Int
ref]
instance Pretty ( Either AxisParseError Axis ) where
pretty :: Either AxisParseError Axis -> Doc ann
pretty (Left AxisParseError
e) = String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ AxisParseError -> String
forall a. Show a => a -> String
show AxisParseError
e
pretty (Right Axis
a) = Axis -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Axis
a
data AxisParseError =
LabelsBeyondReference
| MultipleLabelAtSamePosition
deriving (AxisParseError -> AxisParseError -> Bool
(AxisParseError -> AxisParseError -> Bool)
-> (AxisParseError -> AxisParseError -> Bool) -> Eq AxisParseError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AxisParseError -> AxisParseError -> Bool
$c/= :: AxisParseError -> AxisParseError -> Bool
== :: AxisParseError -> AxisParseError -> Bool
$c== :: AxisParseError -> AxisParseError -> Bool
Eq, Int -> AxisParseError -> ShowS
[AxisParseError] -> ShowS
AxisParseError -> String
(Int -> AxisParseError -> ShowS)
-> (AxisParseError -> String)
-> ([AxisParseError] -> ShowS)
-> Show AxisParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AxisParseError] -> ShowS
$cshowList :: [AxisParseError] -> ShowS
show :: AxisParseError -> String
$cshow :: AxisParseError -> String
showsPrec :: Int -> AxisParseError -> ShowS
$cshowsPrec :: Int -> AxisParseError -> ShowS
Show)
parseAxis
:: [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText Int
-> Either AxisParseError Axis
parseAxis :: [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText Int
-> Either AxisParseError Axis
parseAxis [(Int, Char)]
_ Maybe AxisPlacement
Nothing IntervalText Int
i = Axis -> Either AxisParseError Axis
forall a b. b -> Either a b
Right (Axis -> Either AxisParseError Axis)
-> Axis -> Either AxisParseError Axis
forall a b. (a -> b) -> a -> b
$ IntervalText Int -> AxisConfig -> Axis
MkAxis IntervalText Int
i (Maybe AxisPlacement -> Maybe AxisLabels -> AxisConfig
MkAxisConfig Maybe AxisPlacement
forall a. Maybe a
Nothing Maybe AxisLabels
forall a. Maybe a
Nothing)
parseAxis [(Int, Char)]
l (Just AxisPlacement
p) IntervalText Int
i = do
let labels :: Maybe (NonEmpty (Int, Char))
labels = NonEmpty (Int, Char) -> NonEmpty (Int, Char)
forall a. NonEmpty (Int, a) -> NonEmpty (Int, a)
intMapList (NonEmpty (Int, Char) -> NonEmpty (Int, Char))
-> Maybe (NonEmpty (Int, Char)) -> Maybe (NonEmpty (Int, Char))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, Char)] -> Maybe (NonEmpty (Int, Char))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [(Int, Char)]
l
let labPos :: Maybe (NonEmpty Int)
labPos = ((Int, Char) -> Int) -> NonEmpty (Int, Char) -> NonEmpty Int
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NE.map (Int, Char) -> Int
forall a b. (a, b) -> a
fst (NonEmpty (Int, Char) -> NonEmpty Int)
-> Maybe (NonEmpty (Int, Char)) -> Maybe (NonEmpty Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty (Int, Char))
labels
let inputLabelCount :: Int
inputLabelCount = [(Int, Char)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, Char)]
l
if
|
(Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Int
x -> Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin IntervalText Int
i Bool -> Bool -> Bool
|| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end IntervalText Int
i) (((Int, Char) -> Int) -> [(Int, Char)] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, Char) -> Int
forall a b. (a, b) -> a
fst [(Int, Char)]
l) -> AxisParseError -> Either AxisParseError Axis
forall a b. a -> Either a b
Left
AxisParseError
LabelsBeyondReference
|
Int
inputLabelCount Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& (NonEmpty (Int, Char) -> Int)
-> Maybe (NonEmpty (Int, Char)) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty (Int, Char) -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Maybe (NonEmpty (Int, Char))
labels Maybe Int -> Maybe Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int -> Maybe Int
forall a. a -> Maybe a
Just Int
inputLabelCount -> AxisParseError -> Either AxisParseError Axis
forall a b. a -> Either a b
Left
AxisParseError
MultipleLabelAtSamePosition
|
Bool
otherwise -> Axis -> Either AxisParseError Axis
forall a b. b -> Either a b
Right
(Axis -> Either AxisParseError Axis)
-> Axis -> Either AxisParseError Axis
forall a b. (a -> b) -> a -> b
$ IntervalText Int -> AxisConfig -> Axis
MkAxis IntervalText Int
i (Maybe AxisPlacement -> Maybe AxisLabels -> AxisConfig
MkAxisConfig (AxisPlacement -> Maybe AxisPlacement
forall a. a -> Maybe a
Just AxisPlacement
p) ((NonEmpty (Int, Char) -> AxisLabels)
-> Maybe (NonEmpty (Int, Char)) -> Maybe AxisLabels
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty (Int, Char) -> AxisLabels
MkAxisLabels Maybe (NonEmpty (Int, Char))
labels))
data IntervalDiagramOptions = MkIntervalDiagramOptions
{
IntervalDiagramOptions -> LayoutOptions
layout :: LayoutOptions
, IntervalDiagramOptions -> Int
leftPadding :: Int
}
deriving (IntervalDiagramOptions -> IntervalDiagramOptions -> Bool
(IntervalDiagramOptions -> IntervalDiagramOptions -> Bool)
-> (IntervalDiagramOptions -> IntervalDiagramOptions -> Bool)
-> Eq IntervalDiagramOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalDiagramOptions -> IntervalDiagramOptions -> Bool
$c/= :: IntervalDiagramOptions -> IntervalDiagramOptions -> Bool
== :: IntervalDiagramOptions -> IntervalDiagramOptions -> Bool
$c== :: IntervalDiagramOptions -> IntervalDiagramOptions -> Bool
Eq, Int -> IntervalDiagramOptions -> ShowS
[IntervalDiagramOptions] -> ShowS
IntervalDiagramOptions -> String
(Int -> IntervalDiagramOptions -> ShowS)
-> (IntervalDiagramOptions -> String)
-> ([IntervalDiagramOptions] -> ShowS)
-> Show IntervalDiagramOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDiagramOptions] -> ShowS
$cshowList :: [IntervalDiagramOptions] -> ShowS
show :: IntervalDiagramOptions -> String
$cshow :: IntervalDiagramOptions -> String
showsPrec :: Int -> IntervalDiagramOptions -> ShowS
$cshowsPrec :: Int -> IntervalDiagramOptions -> ShowS
Show)
data IntervalDiagramOptionsError =
UnboundedPageWidth
| LeftPaddingLessThan0
deriving (IntervalDiagramOptionsError -> IntervalDiagramOptionsError -> Bool
(IntervalDiagramOptionsError
-> IntervalDiagramOptionsError -> Bool)
-> (IntervalDiagramOptionsError
-> IntervalDiagramOptionsError -> Bool)
-> Eq IntervalDiagramOptionsError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalDiagramOptionsError -> IntervalDiagramOptionsError -> Bool
$c/= :: IntervalDiagramOptionsError -> IntervalDiagramOptionsError -> Bool
== :: IntervalDiagramOptionsError -> IntervalDiagramOptionsError -> Bool
$c== :: IntervalDiagramOptionsError -> IntervalDiagramOptionsError -> Bool
Eq, Int -> IntervalDiagramOptionsError -> ShowS
[IntervalDiagramOptionsError] -> ShowS
IntervalDiagramOptionsError -> String
(Int -> IntervalDiagramOptionsError -> ShowS)
-> (IntervalDiagramOptionsError -> String)
-> ([IntervalDiagramOptionsError] -> ShowS)
-> Show IntervalDiagramOptionsError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDiagramOptionsError] -> ShowS
$cshowList :: [IntervalDiagramOptionsError] -> ShowS
show :: IntervalDiagramOptionsError -> String
$cshow :: IntervalDiagramOptionsError -> String
showsPrec :: Int -> IntervalDiagramOptionsError -> ShowS
$cshowsPrec :: Int -> IntervalDiagramOptionsError -> ShowS
Show)
parseDiagramOptions
:: IntervalDiagramOptions
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
parseDiagramOptions :: IntervalDiagramOptions
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
parseDiagramOptions IntervalDiagramOptions
opts = if
| IntervalDiagramOptions -> Int
leftPadding IntervalDiagramOptions
opts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 -> IntervalDiagramOptionsError
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
forall a b. a -> Either a b
Left IntervalDiagramOptionsError
LeftPaddingLessThan0
| LayoutOptions -> PageWidth
layoutPageWidth (IntervalDiagramOptions -> LayoutOptions
layout IntervalDiagramOptions
opts) PageWidth -> PageWidth -> Bool
forall a. Eq a => a -> a -> Bool
== PageWidth
Unbounded -> IntervalDiagramOptionsError
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
forall a b. a -> Either a b
Left IntervalDiagramOptionsError
UnboundedPageWidth
| Bool
otherwise -> IntervalDiagramOptions
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
forall a b. b -> Either a b
Right IntervalDiagramOptions
opts
where isSorted :: [a] -> Bool
isSorted [a]
xs = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> [Bool] -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> a -> Bool) -> [a] -> [a] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(<=) [a]
xs ([a] -> [a]
forall a. [a] -> [a]
tail [a]
xs)
defaultIntervalDiagramOptions :: IntervalDiagramOptions
defaultIntervalDiagramOptions :: IntervalDiagramOptions
defaultIntervalDiagramOptions = LayoutOptions -> Int -> IntervalDiagramOptions
MkIntervalDiagramOptions LayoutOptions
defaultLayoutOptions Int
0
data IntervalDiagram a = MkIntervalDiagram
{
IntervalDiagram a -> Interval a
reference :: Interval a
, IntervalDiagram a -> Axis
axis :: Axis
, IntervalDiagram a -> [IntervalTextLine Int]
intervalValues :: [IntervalTextLine Int]
, IntervalDiagram a -> IntervalDiagramOptions
options :: IntervalDiagramOptions
}
deriving Int -> IntervalDiagram a -> ShowS
[IntervalDiagram a] -> ShowS
IntervalDiagram a -> String
(Int -> IntervalDiagram a -> ShowS)
-> (IntervalDiagram a -> String)
-> ([IntervalDiagram a] -> ShowS)
-> Show (IntervalDiagram a)
forall a. (Show a, Ord a) => Int -> IntervalDiagram a -> ShowS
forall a. (Show a, Ord a) => [IntervalDiagram a] -> ShowS
forall a. (Show a, Ord a) => IntervalDiagram a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDiagram a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [IntervalDiagram a] -> ShowS
show :: IntervalDiagram a -> String
$cshow :: forall a. (Show a, Ord a) => IntervalDiagram a -> String
showsPrec :: Int -> IntervalDiagram a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> IntervalDiagram a -> ShowS
Show
data IntervalDiagramParseError =
IntervalsExtendBeyondAxis
| AxisWiderThanAvailable
| PaddingWithNoAxis
| OptionsError IntervalDiagramOptionsError
| AxisError AxisParseError
| IntervalLineError IntervalTextLineParseError
deriving (IntervalDiagramParseError -> IntervalDiagramParseError -> Bool
(IntervalDiagramParseError -> IntervalDiagramParseError -> Bool)
-> (IntervalDiagramParseError -> IntervalDiagramParseError -> Bool)
-> Eq IntervalDiagramParseError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalDiagramParseError -> IntervalDiagramParseError -> Bool
$c/= :: IntervalDiagramParseError -> IntervalDiagramParseError -> Bool
== :: IntervalDiagramParseError -> IntervalDiagramParseError -> Bool
$c== :: IntervalDiagramParseError -> IntervalDiagramParseError -> Bool
Eq, Int -> IntervalDiagramParseError -> ShowS
[IntervalDiagramParseError] -> ShowS
IntervalDiagramParseError -> String
(Int -> IntervalDiagramParseError -> ShowS)
-> (IntervalDiagramParseError -> String)
-> ([IntervalDiagramParseError] -> ShowS)
-> Show IntervalDiagramParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDiagramParseError] -> ShowS
$cshowList :: [IntervalDiagramParseError] -> ShowS
show :: IntervalDiagramParseError -> String
$cshow :: IntervalDiagramParseError -> String
showsPrec :: Int -> IntervalDiagramParseError -> ShowS
$cshowsPrec :: Int -> IntervalDiagramParseError -> ShowS
Show)
instance (SizedIv (Interval a)) => Pretty (IntervalDiagram a) where
pretty :: IntervalDiagram a -> Doc ann
pretty (MkIntervalDiagram Interval a
_ Axis
axis [IntervalTextLine Int]
ivs IntervalDiagramOptions
opts) = do
let intervalLines :: [Doc ann]
intervalLines = (IntervalTextLine Int -> Doc ann)
-> [IntervalTextLine Int] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntervalTextLine Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [IntervalTextLine Int]
ivs
let refDur :: Int
refDur = IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end (Axis -> IntervalText Int
refInterval Axis
axis)
let labelIndents :: [Int]
labelIndents = (IntervalTextLine Int -> Int) -> [IntervalTextLine Int] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((-) Int
refDur (Int -> Int)
-> (IntervalTextLine Int -> Int) -> IntervalTextLine Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalTextLine Int -> Int
intervalLineEnd) [IntervalTextLine Int]
ivs
let labelLines :: [Doc ann]
labelLines =
(IntervalTextLine Int -> Int -> Doc ann)
-> [IntervalTextLine Int] -> [Int] -> [Doc ann]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\IntervalTextLine Int
i Int
l -> Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent Int
l (IntervalTextLine Int -> Doc ann
forall ann. IntervalTextLine Int -> Doc ann
prettyLineLabel IntervalTextLine Int
i)) [IntervalTextLine Int]
ivs [Int]
labelIndents
let intervalDiagram :: Doc ann
intervalDiagram = [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (Doc ann -> Doc ann -> Doc ann)
-> [Doc ann] -> [Doc ann] -> [Doc ann]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
(<>) [Doc ann]
intervalLines [Doc ann]
labelLines
let mainDiagram :: Doc ann
mainDiagram = case (AxisConfig -> Maybe AxisPlacement
placement (AxisConfig -> Maybe AxisPlacement)
-> (Axis -> AxisConfig) -> Axis -> Maybe AxisPlacement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Axis -> AxisConfig
config) Axis
axis of
Maybe AxisPlacement
Nothing -> Doc ann
intervalDiagram
Just AxisPlacement
Top -> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vcat [Axis -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Axis
axis, Doc ann
intervalDiagram]
Just AxisPlacement
Bottom -> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vcat [Doc ann
intervalDiagram, Axis -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Axis
axis]
Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
indent (IntervalDiagramOptions -> Int
leftPadding IntervalDiagramOptions
opts) Doc ann
mainDiagram
where
intervalLineEnd :: IntervalTextLine Int -> Int
intervalLineEnd :: IntervalTextLine Int -> Int
intervalLineEnd (MkIntervalTextLine [IntervalText Int]
x [Text]
_) = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (IntervalText Int -> Int) -> [IntervalText Int] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntervalText Int -> Int
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end [IntervalText Int]
x
prettyLineLabel :: IntervalTextLine Int -> Doc ann
prettyLineLabel :: IntervalTextLine Int -> Doc ann
prettyLineLabel (MkIntervalTextLine [IntervalText Int]
_ [Text]
t) = if [Text] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
t
then Doc ann
forall ann. Doc ann
emptyDoc
else Doc ann
forall ann. Doc ann
space Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Text
"<-" :: Text) Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
space Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> [Text] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [Text]
t
instance (SizedIv (Interval a)) =>
Pretty (Either IntervalDiagramParseError (IntervalDiagram a)) where
pretty :: Either IntervalDiagramParseError (IntervalDiagram a) -> Doc ann
pretty (Left IntervalDiagramParseError
e) = String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ IntervalDiagramParseError -> String
forall a. Show a => a -> String
show IntervalDiagramParseError
e
pretty (Right IntervalDiagram a
d) = IntervalDiagram a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty IntervalDiagram a
d
parseIntervalDiagram
:: (Ord a, SizedIv (Interval a), Enum a, Num a, Enum (Moment (Interval a)))
=> IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
parseIntervalDiagram :: IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
parseIntervalDiagram IntervalDiagramOptions
opts [(Int, Char)]
labels Maybe AxisPlacement
placement IntervalText a
ref [([IntervalText a], [Text])]
ivs =
case IntervalDiagramOptions
-> Either IntervalDiagramOptionsError IntervalDiagramOptions
parseDiagramOptions IntervalDiagramOptions
opts of
Left IntervalDiagramOptionsError
e -> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left (IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a))
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. (a -> b) -> a -> b
$ IntervalDiagramOptionsError -> IntervalDiagramParseError
OptionsError IntervalDiagramOptionsError
e
Right IntervalDiagramOptions
o -> if
|
PageWidth -> Bool
checkAvailableChar (LayoutOptions -> PageWidth
layoutPageWidth (LayoutOptions -> PageWidth) -> LayoutOptions -> PageWidth
forall a b. (a -> b) -> a -> b
$ IntervalDiagramOptions -> LayoutOptions
layout IntervalDiagramOptions
o)
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left IntervalDiagramParseError
AxisWiderThanAvailable
|
(IntervalText a -> Bool) -> [IntervalText a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (ComparativePredicateOf2 (IntervalText a) (IntervalText a)
extendsBeyond IntervalText a
ref) ((([IntervalText a], [Text]) -> [IntervalText a])
-> [([IntervalText a], [Text])] -> [IntervalText a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([IntervalText a], [Text]) -> [IntervalText a]
forall a b. (a, b) -> a
fst [([IntervalText a], [Text])]
ivs)
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left IntervalDiagramParseError
IntervalsExtendBeyondAxis
|
IntervalDiagramOptions -> Int
leftPadding IntervalDiagramOptions
o Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Maybe AxisPlacement -> Bool
forall a. Maybe a -> Bool
isNothing Maybe AxisPlacement
placement
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left IntervalDiagramParseError
PaddingWithNoAxis
| Bool
otherwise
-> let parsedReferencedIntervals :: Either IntervalTextLineParseError [IntervalTextLine Int]
parsedReferencedIntervals = (([IntervalText a], [Text])
-> Either IntervalTextLineParseError (IntervalTextLine Int))
-> [([IntervalText a], [Text])]
-> Either IntervalTextLineParseError [IntervalTextLine Int]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
(\([IntervalText a]
i, [Text]
t) -> [Text]
-> [IntervalText Int]
-> Either IntervalTextLineParseError (IntervalTextLine Int)
parseIntervalTextLine [Text]
t (IntervalText a -> [IntervalText a] -> [IntervalText Int]
forall (f :: * -> *) a (i :: * -> *) (i0 :: * -> *).
(Functor f, Enum a, Num a, SizedIv (Interval a), Intervallic i,
Intervallic i0) =>
i0 a -> f (i a) -> f (i Int)
rereferenceL IntervalText a
ref [IntervalText a]
i))
[([IntervalText a], [Text])]
ivs
in case Either IntervalTextLineParseError [IntervalTextLine Int]
parsedReferencedIntervals of
Left IntervalTextLineParseError
e -> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left (IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a))
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. (a -> b) -> a -> b
$ IntervalTextLineParseError -> IntervalDiagramParseError
IntervalLineError IntervalTextLineParseError
e
Right [IntervalTextLine Int]
vals ->
let parsedAxis :: Either AxisParseError Axis
parsedAxis =
[(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText Int
-> Either AxisParseError Axis
parseAxis [(Int, Char)]
labels Maybe AxisPlacement
placement (IntervalText a -> IntervalText a -> IntervalText Int
forall a (i :: * -> *) (i0 :: * -> *).
(Enum a, Num a, SizedIv (Interval a), Intervallic i,
Intervallic i0) =>
i0 a -> i a -> i Int
rereference IntervalText a
ref IntervalText a
ref)
in case Either AxisParseError Axis
parsedAxis of
Left AxisParseError
e -> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left (IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a))
-> IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. (a -> b) -> a -> b
$ AxisParseError -> IntervalDiagramParseError
AxisError AxisParseError
e
Right Axis
axis ->
IntervalDiagram a
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. b -> Either a b
Right (IntervalDiagram a
-> Either IntervalDiagramParseError (IntervalDiagram a))
-> IntervalDiagram a
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. (a -> b) -> a -> b
$ Interval a
-> Axis
-> [IntervalTextLine Int]
-> IntervalDiagramOptions
-> IntervalDiagram a
forall a.
Interval a
-> Axis
-> [IntervalTextLine Int]
-> IntervalDiagramOptions
-> IntervalDiagram a
MkIntervalDiagram (IntervalText a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval IntervalText a
ref) Axis
axis [IntervalTextLine Int]
vals IntervalDiagramOptions
o
where
extendsBeyond :: ComparativePredicateOf2 (IntervalText a) (IntervalText a)
extendsBeyond =
ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
before ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
meets ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
overlaps ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
overlappedBy ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
metBy ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
-> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (IntervalText a) (IntervalText a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
after
checkAvailableChar :: PageWidth -> Bool
checkAvailableChar (AvailablePerLine Int
i Double
_) = Moment (Interval a) -> Int
forall a. Enum a => a -> Int
fromEnum (Interval a -> Moment (Interval a)
forall iv. SizedIv iv => iv -> Moment iv
duration (Interval a -> Moment (Interval a))
-> Interval a -> Moment (Interval a)
forall a b. (a -> b) -> a -> b
$ IntervalText a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval IntervalText a
ref) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
i
checkAvailableChar PageWidth
Unbounded = Bool
True
rereference :: i0 a -> i a -> i Int
rereference i0 a
x = i a -> i Int
forall a (i :: * -> *). (Enum a, Intervallic i) => i a -> i Int
fromEnumInterval (i a -> i Int) -> (i a -> i a) -> i a -> i Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i0 a -> i a -> i a
forall a (i1 :: * -> *) (i0 :: * -> *).
(Num a, SizedIv (Interval a), Intervallic i1, Intervallic i0) =>
i0 a -> i1 a -> i1 a
shiftFromBegin i0 a
x
rereferenceL :: i0 a -> f (i a) -> f (i Int)
rereferenceL i0 a
x = (i a -> i Int) -> f (i a) -> f (i Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (i0 a -> i a -> i Int
forall a (i :: * -> *) (i0 :: * -> *).
(Enum a, Num a, SizedIv (Interval a), Intervallic i,
Intervallic i0) =>
i0 a -> i a -> i Int
rereference i0 a
x)
simpleIntervalDiagram
:: (Ord a, SizedIv (Interval a), Intervallic i, Enum a, Num a, Enum (Moment (Interval a)))
=> i a
-> [i a]
-> Either IntervalDiagramParseError (IntervalDiagram a)
simpleIntervalDiagram :: i a
-> [i a] -> Either IntervalDiagramParseError (IntervalDiagram a)
simpleIntervalDiagram i a
ref [i a]
ivs = IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a.
(Ord a, SizedIv (Interval a), Enum a, Num a,
Enum (Moment (Interval a))) =>
IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
parseIntervalDiagram
IntervalDiagramOptions
defaultIntervalDiagramOptions
[]
(AxisPlacement -> Maybe AxisPlacement
forall a. a -> Maybe a
Just AxisPlacement
Bottom)
(Char -> Interval a -> IntervalText a
forall a. Char -> Interval a -> IntervalText a
makeIntervalText Char
'=' (i a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i a
ref))
((i a -> ([IntervalText a], [Text]))
-> [i a] -> [([IntervalText a], [Text])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\i a
x -> (IntervalText a -> [IntervalText a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IntervalText a -> [IntervalText a])
-> IntervalText a -> [IntervalText a]
forall a b. (a -> b) -> a -> b
$ Char -> Interval a -> IntervalText a
forall a. Char -> Interval a -> IntervalText a
makeIntervalText Char
'-' (Interval a -> IntervalText a) -> Interval a -> IntervalText a
forall a b. (a -> b) -> a -> b
$ i a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i a
x, [])) [i a]
ivs)
standardExampleDiagram
:: (Num a, Enum a, Ord a, Enum (Moment (Interval a)), Ord (Moment (Interval a)), SizedIv (Interval a))
=> [(Interval a, String)]
-> [([Interval a], String)]
-> Either IntervalDiagramParseError (IntervalDiagram a)
standardExampleDiagram :: [(Interval a, String)]
-> [([Interval a], String)]
-> Either IntervalDiagramParseError (IntervalDiagram a)
standardExampleDiagram [(Interval a, String)]
ivs [([Interval a], String)]
livs = Maybe (IntervalText a)
-> Either IntervalDiagramParseError (IntervalDiagram a)
op Maybe (IntervalText a)
ref
where
op :: Maybe (IntervalText a)
-> Either IntervalDiagramParseError (IntervalDiagram a)
op Maybe (IntervalText a)
Nothing = IntervalDiagramParseError
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a b. a -> Either a b
Left IntervalDiagramParseError
IntervalsExtendBeyondAxis
op (Just IntervalText a
ref') = IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
forall a.
(Ord a, SizedIv (Interval a), Enum a, Num a,
Enum (Moment (Interval a))) =>
IntervalDiagramOptions
-> [(Int, Char)]
-> Maybe AxisPlacement
-> IntervalText a
-> [([IntervalText a], [Text])]
-> Either IntervalDiagramParseError (IntervalDiagram a)
parseIntervalDiagram IntervalDiagramOptions
defaultIntervalDiagramOptions
[]
(AxisPlacement -> Maybe AxisPlacement
forall a. a -> Maybe a
Just AxisPlacement
Bottom)
IntervalText a
ref'
[([IntervalText a], [Text])]
combIvs
range :: Maybe (Interval a)
range = [Interval a] -> Maybe (Interval a)
forall (t :: * -> *) a.
(Foldable t, Ord a, SizedIv (Interval a)) =>
t (Interval a) -> Maybe (Interval a)
rangeInterval ([Interval a] -> Maybe (Interval a))
-> [Interval a] -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ ((Interval a, String) -> Interval a)
-> [(Interval a, String)] -> [Interval a]
forall a b. (a -> b) -> [a] -> [b]
map (Interval a, String) -> Interval a
forall a b. (a, b) -> a
fst [(Interval a, String)]
ivs [Interval a] -> [Interval a] -> [Interval a]
forall a. [a] -> [a] -> [a]
++ (([Interval a], String) -> [Interval a])
-> [([Interval a], String)] -> [Interval a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Interval a], String) -> [Interval a]
forall a b. (a, b) -> a
fst [([Interval a], String)]
livs
anchoredRange :: Maybe (Interval a)
anchoredRange = case Maybe (Interval a)
range of
Maybe (Interval a)
Nothing -> Maybe (Interval a)
forall a. Maybe a
Nothing
(Just Interval a
x) -> Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (a -> a -> a
forall a. Ord a => a -> a -> a
min (Interval a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin Interval a
x) a
0, a -> a -> a
forall a. Ord a => a -> a -> a
max (Interval a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end Interval a
x) a
0)
ref :: Maybe (IntervalText a)
ref = (Interval a -> IntervalText a)
-> Maybe (Interval a) -> Maybe (IntervalText a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Char -> Interval a -> IntervalText a
forall a. Char -> Interval a -> IntervalText a
makeIntervalText Char
'=') Maybe (Interval a)
anchoredRange
f :: (a, b) -> ([a], b)
f (a
iv, b
s) = ([a
iv], b
s)
g :: ([Interval a], String) -> ([IntervalText a], [Text])
g ([Interval a]
ivs, String
s) = ((Interval a -> IntervalText a) -> [Interval a] -> [IntervalText a]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> Interval a -> IntervalText a
forall a. Char -> Interval a -> IntervalText a
makeIntervalText Char
'-') [Interval a]
ivs, [String -> Text
pack String
s])
combIvs :: [([IntervalText a], [Text])]
combIvs = ((Interval a, String) -> ([IntervalText a], [Text]))
-> [(Interval a, String)] -> [([IntervalText a], [Text])]
forall a b. (a -> b) -> [a] -> [b]
map (([Interval a], String) -> ([IntervalText a], [Text])
forall a. ([Interval a], String) -> ([IntervalText a], [Text])
g (([Interval a], String) -> ([IntervalText a], [Text]))
-> ((Interval a, String) -> ([Interval a], String))
-> (Interval a, String)
-> ([IntervalText a], [Text])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Interval a, String) -> ([Interval a], String)
forall a b. (a, b) -> ([a], b)
f) [(Interval a, String)]
ivs [([IntervalText a], [Text])]
-> [([IntervalText a], [Text])] -> [([IntervalText a], [Text])]
forall a. [a] -> [a] -> [a]
++ (([Interval a], String) -> ([IntervalText a], [Text]))
-> [([Interval a], String)] -> [([IntervalText a], [Text])]
forall a b. (a -> b) -> [a] -> [b]
map ([Interval a], String) -> ([IntervalText a], [Text])
forall a. ([Interval a], String) -> ([IntervalText a], [Text])
g [([Interval a], String)]
livs