module Numeric.LAPACK.Output (
   Output
      (text, above, beside, formatRow, formatColumn,
       formatAligned, formatSeparateTriangle),

   (/+/),
   (<+>),
   hyper,
   ) where

import qualified Hyper
import qualified Text.Blaze.Html4.Transitional as Html
import qualified Text.Blaze.Html4.Transitional.Attributes as Attr
import qualified Text.Blaze.Html.Renderer.Text as RenderHtml
import Text.Blaze.Html ((!))

import qualified Text.PrettyPrint.Boxes as TextBox
import Text.PrettyPrint.Boxes (Box)

import qualified Data.Text.Lazy as TextLazy
import qualified Data.Foldable as Fold
import qualified Data.List.HT as ListHT
import qualified Data.List as List
import Data.Foldable (Foldable)
import Data.String (fromString)
import Data.Maybe.HT (toMaybe)
import Data.Maybe (fromMaybe)


class Output out where
   text :: String -> out
   above :: out -> out -> out
   beside :: out -> out -> out
   formatRow, formatColumn :: [out] -> out
   formatAligned :: (Foldable f) => [[f out]] -> out
   formatSeparateTriangle :: (Foldable f) => [[f out]] -> out

(/+/) :: (Output out) => out -> out -> out
/+/ :: out -> out -> out
(/+/) = out -> out -> out
forall out. Output out => out -> out -> out
above

(<+>) :: (Output out) => out -> out -> out
<+> :: out -> out -> out
(<+>) = out -> out -> out
forall out. Output out => out -> out -> out
beside


newtype Html = Html {Html -> Html
unHtml :: Html.Html}

hyper :: Html -> Hyper.Graphic
hyper :: Html -> Graphic
hyper = Text -> Graphic
Hyper.html (Text -> Graphic) -> (Html -> Text) -> Html -> Graphic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
TextLazy.toStrict (Text -> Text) -> (Html -> Text) -> Html -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Text
RenderHtml.renderHtml (Html -> Text) -> (Html -> Html) -> Html -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
unHtml

instance Output Html where
   text :: String -> Html
text = Html -> Html
Html (Html -> Html) -> (String -> Html) -> String -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Html
forall a. ToMarkup a => a -> Html
Html.toHtml
   above :: Html -> Html -> Html
above (Html Html
a) (Html Html
b) = Html -> Html
Html (Html -> Html) -> Html -> Html
forall a b. (a -> b) -> a -> b
$ Html
a Html -> Html -> Html
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html
Html.br Html -> Html -> Html
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html
b
   beside :: Html -> Html -> Html
beside (Html Html
a) (Html Html
b) = Html -> Html
Html (Html -> Html) -> Html -> Html
forall a b. (a -> b) -> a -> b
$ Html
a Html -> Html -> Html
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> Html
Html.string String
" " Html -> Html -> Html
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html
b
   formatRow :: [Html] -> Html
formatRow = Html -> Html
Html (Html -> Html) -> ([Html] -> Html) -> [Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
Html.table (Html -> Html) -> ([Html] -> Html) -> [Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
Html.tr (Html -> Html) -> ([Html] -> Html) -> [Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Html -> Html) -> [Html] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Html -> Html
td (Html -> Html) -> (Html -> Html) -> Html -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
unHtml)
   formatColumn :: [Html] -> Html
formatColumn = Html -> Html
Html (Html -> Html) -> ([Html] -> Html) -> [Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
Html.table (Html -> Html) -> ([Html] -> Html) -> [Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Html -> Html) -> [Html] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Html -> Html
Html.tr (Html -> Html) -> (Html -> Html) -> Html -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
td (Html -> Html) -> (Html -> Html) -> Html -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
unHtml)
   formatAligned :: [[f Html]] -> Html
formatAligned =
      Html -> Html
Html (Html -> Html) -> ([[f Html]] -> Html) -> [[f Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
Html.table (Html -> Html) -> ([[f Html]] -> Html) -> [[f Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      ([f Html] -> Html) -> [[f Html]] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Html -> Html
Html.tr (Html -> Html) -> ([f Html] -> Html) -> [f Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Html -> Html) -> [Html] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Html -> Html
td (Html -> Html) -> (Html -> Html) -> Html -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
unHtml) ([Html] -> Html) -> ([f Html] -> [Html]) -> [f Html] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f Html -> [Html]) -> [f Html] -> [Html]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap f Html -> [Html]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList)
   formatSeparateTriangle :: [[f Html]] -> Html
formatSeparateTriangle =
      Html -> Html
Html (Html -> Html) -> ([[f Html]] -> Html) -> [[f Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
Html.table (Html -> Html) -> ([[f Html]] -> Html) -> [[f Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      ([[Html]] -> Html) -> [[[Html]]] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Html -> Html
Html.tr (Html -> Html) -> ([[Html]] -> Html) -> [[Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Html -> Html) -> [Html] -> Html
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Html -> Html
td ([Html] -> Html) -> ([[Html]] -> [Html]) -> [[Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Html]] -> [Html]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) ([[[Html]]] -> Html)
-> ([[f Html]] -> [[[Html]]]) -> [[f Html]] -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      ([Html -> Html] -> [f Html] -> [[Html]])
-> [[Html -> Html]] -> [[f Html]] -> [[[Html]]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
         (((Html -> Html) -> f Html -> [Html])
-> [Html -> Html] -> [f Html] -> [[Html]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (((Html -> Html) -> f Html -> [Html])
 -> [Html -> Html] -> [f Html] -> [[Html]])
-> ((Html -> Html) -> f Html -> [Html])
-> [Html -> Html]
-> [f Html]
-> [[Html]]
forall a b. (a -> b) -> a -> b
$ \Html -> Html
it -> (Html -> Html) -> [Html] -> [Html]
forall a b. (a -> b) -> [a] -> [b]
map (Html -> Html
it (Html -> Html) -> (Html -> Html) -> Html -> Html
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Html -> Html
unHtml) ([Html] -> [Html]) -> (f Html -> [Html]) -> f Html -> [Html]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f Html -> [Html]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList)
         (([Html -> Html] -> [Html -> Html])
-> [Html -> Html] -> [[Html -> Html]]
forall a. (a -> a) -> a -> [a]
iterate (Html -> Html
Html.i(Html -> Html) -> [Html -> Html] -> [Html -> Html]
forall a. a -> [a] -> [a]
:) ((Html -> Html) -> [Html -> Html]
forall a. a -> [a]
repeat Html -> Html
forall a. a -> a
id))

td :: Html.Html -> Html.Html
td :: Html -> Html
td = Html -> Html
Html.td (Html -> Html) -> Attribute -> Html -> Html
forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
Attr.align (String -> AttributeValue
forall a. IsString a => String -> a
fromString String
"right")


instance Output Box where
   text :: String -> Box
text = String -> Box
TextBox.text
   above :: Box -> Box -> Box
above = Box -> Box -> Box
(TextBox./+/)
   beside :: Box -> Box -> Box
beside = Box -> Box -> Box
(TextBox.<+>)
   formatRow :: [Box] -> Box
formatRow = Int -> Alignment -> [Box] -> Box
forall (f :: * -> *).
Foldable f =>
Int -> Alignment -> f Box -> Box
TextBox.hsep Int
1 Alignment
TextBox.right
   formatColumn :: [Box] -> Box
formatColumn = Int -> Alignment -> [Box] -> Box
forall (f :: * -> *).
Foldable f =>
Int -> Alignment -> f Box -> Box
TextBox.vsep Int
1 Alignment
TextBox.right
   formatAligned :: [[f Box]] -> Box
formatAligned = [[(Separator, Box)]] -> Box
alignSeparated ([[(Separator, Box)]] -> Box)
-> ([[f Box]] -> [[(Separator, Box)]]) -> [[f Box]] -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([f Box] -> [(Separator, Box)])
-> [[f Box]] -> [[(Separator, Box)]]
forall a b. (a -> b) -> [a] -> [b]
map ((f Box -> [(Separator, Box)]) -> [f Box] -> [(Separator, Box)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Separator -> f Box -> [(Separator, Box)]
forall (f :: * -> *) str.
Foldable f =>
Separator -> f str -> [(Separator, str)]
attachSeparators Separator
Space))
   formatSeparateTriangle :: [[f Box]] -> Box
formatSeparateTriangle =
      [[(Separator, Box)]] -> Box
alignSeparated ([[(Separator, Box)]] -> Box)
-> ([[f Box]] -> [[(Separator, Box)]]) -> [[f Box]] -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[(Separator, Box)]] -> [(Separator, Box)])
-> [[[(Separator, Box)]]] -> [[(Separator, Box)]]
forall a b. (a -> b) -> [a] -> [b]
map [[(Separator, Box)]] -> [(Separator, Box)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[(Separator, Box)]]] -> [[(Separator, Box)]])
-> ([[f Box]] -> [[[(Separator, Box)]]])
-> [[f Box]]
-> [[(Separator, Box)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      ([Separator] -> [f Box] -> [[(Separator, Box)]])
-> [[Separator]] -> [[f Box]] -> [[[(Separator, Box)]]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
         ((Separator -> f Box -> [(Separator, Box)])
-> [Separator] -> [f Box] -> [[(Separator, Box)]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Separator -> f Box -> [(Separator, Box)]
forall (f :: * -> *) str.
Foldable f =>
Separator -> f str -> [(Separator, str)]
attachSeparators)
         ((Int -> Int -> Separator) -> [Int] -> [Int] -> [[Separator]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [[c]]
ListHT.outerProduct
            (\Int
row Int
col -> if Int
rowInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
col then Separator
Bar else Separator
Space)
            [(Int
0::Int)..] [Int
0..])


data Separator = Empty | Space | Bar
   deriving (Separator -> Separator -> Bool
(Separator -> Separator -> Bool)
-> (Separator -> Separator -> Bool) -> Eq Separator
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Separator -> Separator -> Bool
$c/= :: Separator -> Separator -> Bool
== :: Separator -> Separator -> Bool
$c== :: Separator -> Separator -> Bool
Eq, Eq Separator
Eq Separator
-> (Separator -> Separator -> Ordering)
-> (Separator -> Separator -> Bool)
-> (Separator -> Separator -> Bool)
-> (Separator -> Separator -> Bool)
-> (Separator -> Separator -> Bool)
-> (Separator -> Separator -> Separator)
-> (Separator -> Separator -> Separator)
-> Ord Separator
Separator -> Separator -> Bool
Separator -> Separator -> Ordering
Separator -> Separator -> Separator
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 :: Separator -> Separator -> Separator
$cmin :: Separator -> Separator -> Separator
max :: Separator -> Separator -> Separator
$cmax :: Separator -> Separator -> Separator
>= :: Separator -> Separator -> Bool
$c>= :: Separator -> Separator -> Bool
> :: Separator -> Separator -> Bool
$c> :: Separator -> Separator -> Bool
<= :: Separator -> Separator -> Bool
$c<= :: Separator -> Separator -> Bool
< :: Separator -> Separator -> Bool
$c< :: Separator -> Separator -> Bool
compare :: Separator -> Separator -> Ordering
$ccompare :: Separator -> Separator -> Ordering
$cp1Ord :: Eq Separator
Ord, Int -> Separator -> ShowS
[Separator] -> ShowS
Separator -> String
(Int -> Separator -> ShowS)
-> (Separator -> String)
-> ([Separator] -> ShowS)
-> Show Separator
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Separator] -> ShowS
$cshowList :: [Separator] -> ShowS
show :: Separator -> String
$cshow :: Separator -> String
showsPrec :: Int -> Separator -> ShowS
$cshowsPrec :: Int -> Separator -> ShowS
Show)

alignSeparated :: [[(Separator, Box)]] -> Box
alignSeparated :: [[(Separator, Box)]] -> Box
alignSeparated =
   Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
TextBox.hcat Alignment
TextBox.top ([Box] -> Box)
-> ([[(Separator, Box)]] -> [Box]) -> [[(Separator, Box)]] -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   ([Box] -> Box) -> [[Box]] -> [Box]
forall a b. (a -> b) -> [a] -> [b]
map (Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
TextBox.vcat Alignment
TextBox.right) ([[Box]] -> [Box])
-> ([[(Separator, Box)]] -> [[Box]])
-> [[(Separator, Box)]]
-> [Box]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   ([(Separator, Box)] -> [[Box]]) -> [[(Separator, Box)]] -> [[Box]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
      ((\([Separator]
seps,[Box]
column) -> [(Separator -> Box) -> [Separator] -> [Box]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Box
TextBox.text (String -> Box) -> (Separator -> String) -> Separator -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Separator -> String
formatSeparator) [Separator]
seps, [Box]
column])
         (([Separator], [Box]) -> [[Box]])
-> ([(Separator, Box)] -> ([Separator], [Box]))
-> [(Separator, Box)]
-> [[Box]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Separator, Box)] -> ([Separator], [Box])
forall a b. [(a, b)] -> ([a], [b])
unzip) ([[(Separator, Box)]] -> [[Box]])
-> ([[(Separator, Box)]] -> [[(Separator, Box)]])
-> [[(Separator, Box)]]
-> [[Box]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   ([[(Separator, Box)]]
 -> Maybe ([(Separator, Box)], [[(Separator, Box)]]))
-> [[(Separator, Box)]] -> [[(Separator, Box)]]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr ((Separator, Box)
-> [[(Separator, Box)]]
-> Maybe ([(Separator, Box)], [[(Separator, Box)]])
forall a. a -> [[a]] -> Maybe ([a], [[a]])
viewLAll (Separator
Empty, String -> Box
TextBox.text String
""))

viewLAll :: a -> [[a]] -> Maybe ([a], [[a]])
viewLAll :: a -> [[a]] -> Maybe ([a], [[a]])
viewLAll a
x0 [[a]]
xs =
   Bool -> ([a], [[a]]) -> Maybe ([a], [[a]])
forall a. Bool -> a -> Maybe a
toMaybe (([a] -> Bool) -> [[a]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Bool
not(Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) [[a]]
xs)
      ([(a, [a])] -> ([a], [[a]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(a, [a])] -> ([a], [[a]])) -> [(a, [a])] -> ([a], [[a]])
forall a b. (a -> b) -> a -> b
$ ([a] -> (a, [a])) -> [[a]] -> [(a, [a])]
forall a b. (a -> b) -> [a] -> [b]
map ((a, [a]) -> Maybe (a, [a]) -> (a, [a])
forall a. a -> Maybe a -> a
fromMaybe (a
x0,[]) (Maybe (a, [a]) -> (a, [a]))
-> ([a] -> Maybe (a, [a])) -> [a] -> (a, [a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Maybe (a, [a])
forall a. [a] -> Maybe (a, [a])
ListHT.viewL) [[a]]
xs)

formatSeparator :: Separator -> String
formatSeparator :: Separator -> String
formatSeparator Separator
sep = case Separator
sep of Separator
Empty -> String
""; Separator
Space -> String
" "; Separator
Bar -> String
"|"

attachSeparators :: (Foldable f) => Separator -> f str -> [(Separator, str)]
attachSeparators :: Separator -> f str -> [(Separator, str)]
attachSeparators Separator
sep = [Separator] -> [str] -> [(Separator, str)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Separator
sepSeparator -> [Separator] -> [Separator]
forall a. a -> [a] -> [a]
:Separator -> [Separator]
forall a. a -> [a]
repeat Separator
Empty) ([str] -> [(Separator, str)])
-> (f str -> [str]) -> f str -> [(Separator, str)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f str -> [str]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Fold.toList