{-# LANGUAGE MultiParamTypeClasses #-}
module Simulation.Aivika.Experiment.Base.TableView
(TableView(..),
defaultTableView) where
import Control.Monad
import Control.Monad.Trans
import qualified Data.Map as M
import Data.IORef
import Data.Maybe
import Data.Monoid
import System.IO
import System.FilePath
import Simulation.Aivika
import Simulation.Aivika.Experiment.Types
import Simulation.Aivika.Experiment.Base.WebPageRenderer
import Simulation.Aivika.Experiment.Base.FileRenderer
import Simulation.Aivika.Experiment.Base.ExperimentWriter
import Simulation.Aivika.Experiment.Base.HtmlWriter
import Simulation.Aivika.Experiment.Utils (replace)
data TableView =
TableView { TableView -> String
tableTitle :: String,
TableView -> String
tableDescription :: String,
TableView -> String
tableLinkText :: String,
TableView -> String
tableRunLinkText :: String,
TableView -> ExperimentFilePath
tableFileName :: ExperimentFilePath,
TableView -> String
tableSeparator :: String,
TableView -> ShowS
tableFormatter :: ShowS,
TableView -> Event Bool
tablePredicate :: Event Bool,
TableView -> ResultTransform
tableTransform :: ResultTransform,
TableView -> ResultTransform
tableSeries :: ResultTransform,
TableView -> Maybe Int
tableSeriesGridSize :: Maybe Int
}
defaultTableView :: TableView
defaultTableView :: TableView
defaultTableView =
TableView :: String
-> String
-> String
-> String
-> ExperimentFilePath
-> String
-> ShowS
-> Event Bool
-> ResultTransform
-> ResultTransform
-> Maybe Int
-> TableView
TableView { tableTitle :: String
tableTitle = String
"Table",
tableDescription :: String
tableDescription = String
"This section contains the CSV file(s) with the simulation results.",
tableLinkText :: String
tableLinkText = String
"Download the CSV file",
tableRunLinkText :: String
tableRunLinkText = String
"$LINK / Run $RUN_INDEX of $RUN_COUNT",
tableFileName :: ExperimentFilePath
tableFileName = String -> ExperimentFilePath
UniqueFilePath String
"Table($RUN_INDEX).csv",
tableSeparator :: String
tableSeparator = String
",",
tableFormatter :: ShowS
tableFormatter = ShowS
forall a. a -> a
id,
tablePredicate :: Event Bool
tablePredicate = Bool -> Event Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True,
tableTransform :: ResultTransform
tableTransform = ResultTransform
expandResults,
tableSeries :: ResultTransform
tableSeries = ResultTransform
forall a. a -> a
id,
tableSeriesGridSize :: Maybe Int
tableSeriesGridSize = Maybe Int
forall a. Maybe a
Nothing }
instance ExperimentView TableView (WebPageRenderer a) where
outputView :: TableView -> ExperimentGenerator (WebPageRenderer a)
outputView TableView
v =
let reporter :: Experiment
-> p
-> String
-> ExperimentWriter (ExperimentReporter (WebPageRenderer a))
reporter Experiment
exp p
renderer String
dir =
do TableViewState
st <- TableView
-> Experiment -> String -> ExperimentWriter TableViewState
newTable TableView
v Experiment
exp String
dir
let context :: ExperimentContext (WebPageRenderer a)
context =
WebPageWriter -> ExperimentContext (WebPageRenderer a)
forall a. WebPageWriter -> ExperimentContext (WebPageRenderer a)
WebPageContext (WebPageWriter -> ExperimentContext (WebPageRenderer a))
-> WebPageWriter -> ExperimentContext (WebPageRenderer a)
forall a b. (a -> b) -> a -> b
$
WebPageWriter :: (Int -> HtmlWriter ()) -> (Int -> HtmlWriter ()) -> WebPageWriter
WebPageWriter { reporterWriteTOCHtml :: Int -> HtmlWriter ()
reporterWriteTOCHtml = TableViewState -> Int -> HtmlWriter ()
tableTOCHtml TableViewState
st,
reporterWriteHtml :: Int -> HtmlWriter ()
reporterWriteHtml = TableViewState -> Int -> HtmlWriter ()
tableHtml TableViewState
st }
ExperimentReporter (WebPageRenderer a)
-> ExperimentWriter (ExperimentReporter (WebPageRenderer a))
forall (m :: * -> *) a. Monad m => a -> m a
return ExperimentReporter :: forall r.
ExperimentMonad r ()
-> ExperimentMonad r ()
-> (ExperimentData -> Composite ())
-> ExperimentContext r
-> ExperimentReporter r
ExperimentReporter { reporterInitialise :: ExperimentMonad (WebPageRenderer a) ()
reporterInitialise = () -> ExperimentWriter ()
forall (m :: * -> *) a. Monad m => a -> m a
return (),
reporterFinalise :: ExperimentMonad (WebPageRenderer a) ()
reporterFinalise = () -> ExperimentWriter ()
forall (m :: * -> *) a. Monad m => a -> m a
return (),
reporterSimulate :: ExperimentData -> Composite ()
reporterSimulate = TableViewState -> ExperimentData -> Composite ()
simulateTable TableViewState
st,
reporterContext :: ExperimentContext (WebPageRenderer a)
reporterContext = ExperimentContext (WebPageRenderer a)
forall a. ExperimentContext (WebPageRenderer a)
context }
in ExperimentGenerator :: forall r.
(Experiment
-> r
-> ExperimentEnvironment r
-> ExperimentMonad r (ExperimentReporter r))
-> ExperimentGenerator r
ExperimentGenerator { generateReporter :: Experiment
-> WebPageRenderer a
-> ExperimentEnvironment (WebPageRenderer a)
-> ExperimentMonad
(WebPageRenderer a) (ExperimentReporter (WebPageRenderer a))
generateReporter = Experiment
-> WebPageRenderer a
-> ExperimentEnvironment (WebPageRenderer a)
-> ExperimentMonad
(WebPageRenderer a) (ExperimentReporter (WebPageRenderer a))
forall p a.
Experiment
-> p
-> String
-> ExperimentWriter (ExperimentReporter (WebPageRenderer a))
reporter }
instance ExperimentView TableView (FileRenderer a) where
outputView :: TableView -> ExperimentGenerator (FileRenderer a)
outputView TableView
v =
let reporter :: Experiment
-> p
-> String
-> ExperimentWriter (ExperimentReporter (FileRenderer a))
reporter Experiment
exp p
renderer String
dir =
do TableViewState
st <- TableView
-> Experiment -> String -> ExperimentWriter TableViewState
newTable TableView
v Experiment
exp String
dir
ExperimentReporter (FileRenderer a)
-> ExperimentWriter (ExperimentReporter (FileRenderer a))
forall (m :: * -> *) a. Monad m => a -> m a
return ExperimentReporter :: forall r.
ExperimentMonad r ()
-> ExperimentMonad r ()
-> (ExperimentData -> Composite ())
-> ExperimentContext r
-> ExperimentReporter r
ExperimentReporter { reporterInitialise :: ExperimentMonad (FileRenderer a) ()
reporterInitialise = () -> ExperimentWriter ()
forall (m :: * -> *) a. Monad m => a -> m a
return (),
reporterFinalise :: ExperimentMonad (FileRenderer a) ()
reporterFinalise = () -> ExperimentWriter ()
forall (m :: * -> *) a. Monad m => a -> m a
return (),
reporterSimulate :: ExperimentData -> Composite ()
reporterSimulate = TableViewState -> ExperimentData -> Composite ()
simulateTable TableViewState
st,
reporterContext :: ExperimentContext (FileRenderer a)
reporterContext = ExperimentContext (FileRenderer a)
forall a. ExperimentContext (FileRenderer a)
FileContext }
in ExperimentGenerator :: forall r.
(Experiment
-> r
-> ExperimentEnvironment r
-> ExperimentMonad r (ExperimentReporter r))
-> ExperimentGenerator r
ExperimentGenerator { generateReporter :: Experiment
-> FileRenderer a
-> ExperimentEnvironment (FileRenderer a)
-> ExperimentMonad
(FileRenderer a) (ExperimentReporter (FileRenderer a))
generateReporter = Experiment
-> FileRenderer a
-> ExperimentEnvironment (FileRenderer a)
-> ExperimentMonad
(FileRenderer a) (ExperimentReporter (FileRenderer a))
forall p a.
Experiment
-> p
-> String
-> ExperimentWriter (ExperimentReporter (FileRenderer a))
reporter }
data TableViewState =
TableViewState { TableViewState -> TableView
tableView :: TableView,
TableViewState -> Experiment
tableExperiment :: Experiment,
TableViewState -> String
tableDir :: FilePath,
TableViewState -> Map Int String
tableMap :: M.Map Int FilePath }
newTable :: TableView -> Experiment -> FilePath -> ExperimentWriter TableViewState
newTable :: TableView
-> Experiment -> String -> ExperimentWriter TableViewState
newTable TableView
view Experiment
exp String
dir =
do let n :: Int
n = Experiment -> Int
experimentRunCount Experiment
exp
[String]
fs <- [Int]
-> (Int -> ExperimentWriter String) -> ExperimentWriter [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
0..(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)] ((Int -> ExperimentWriter String) -> ExperimentWriter [String])
-> (Int -> ExperimentWriter String) -> ExperimentWriter [String]
forall a b. (a -> b) -> a -> b
$ \Int
i ->
String -> ExperimentFilePath -> ExperimentWriter String
resolveFilePath String
dir (ExperimentFilePath -> ExperimentWriter String)
-> ExperimentFilePath -> ExperimentWriter String
forall a b. (a -> b) -> a -> b
$
ShowS -> ExperimentFilePath -> ExperimentFilePath
mapFilePath ((String -> ShowS) -> String -> ShowS
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
replaceExtension String
".csv") (ExperimentFilePath -> ExperimentFilePath)
-> ExperimentFilePath -> ExperimentFilePath
forall a b. (a -> b) -> a -> b
$
ExperimentFilePath -> Map String String -> ExperimentFilePath
expandFilePath (TableView -> ExperimentFilePath
tableFileName TableView
view) (Map String String -> ExperimentFilePath)
-> Map String String -> ExperimentFilePath
forall a b. (a -> b) -> a -> b
$
[(String, String)] -> Map String String
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(String
"$TITLE", TableView -> String
tableTitle TableView
view),
(String
"$RUN_INDEX", Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1),
(String
"$RUN_COUNT", Int -> String
forall a. Show a => a -> String
show Int
n)]
IO () -> ExperimentWriter ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExperimentWriter ()) -> IO () -> ExperimentWriter ()
forall a b. (a -> b) -> a -> b
$ [String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
fs ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ (String -> String -> IO ()) -> String -> String -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> String -> IO ()
writeFile []
let m :: Map Int String
m = [(Int, String)] -> Map Int String
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Int, String)] -> Map Int String)
-> [(Int, String)] -> Map Int String
forall a b. (a -> b) -> a -> b
$ [Int] -> [String] -> [(Int, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)] [String]
fs
TableViewState -> ExperimentWriter TableViewState
forall (m :: * -> *) a. Monad m => a -> m a
return TableViewState :: TableView
-> Experiment -> String -> Map Int String -> TableViewState
TableViewState { tableView :: TableView
tableView = TableView
view,
tableExperiment :: Experiment
tableExperiment = Experiment
exp,
tableDir :: String
tableDir = String
dir,
tableMap :: Map Int String
tableMap = Map Int String
m }
simulateTable :: TableViewState -> ExperimentData -> Composite ()
simulateTable :: TableViewState -> ExperimentData -> Composite ()
simulateTable TableViewState
st ExperimentData
expdata =
do let view :: TableView
view = TableViewState -> TableView
tableView TableViewState
st
rs :: Results
rs = TableView -> ResultTransform
tableSeries TableView
view ResultTransform -> ResultTransform
forall a b. (a -> b) -> a -> b
$
TableView -> ResultTransform
tableTransform TableView
view ResultTransform -> ResultTransform
forall a b. (a -> b) -> a -> b
$
ExperimentData -> Results
experimentResults ExperimentData
expdata
loc :: [ResultId] -> String
loc = ResultLocalisation -> [ResultId] -> String
localisePathResultTitle (ResultLocalisation -> [ResultId] -> String)
-> ResultLocalisation -> [ResultId] -> String
forall a b. (a -> b) -> a -> b
$
Experiment -> ResultLocalisation
experimentLocalisation (Experiment -> ResultLocalisation)
-> Experiment -> ResultLocalisation
forall a b. (a -> b) -> a -> b
$
TableViewState -> Experiment
tableExperiment TableViewState
st
exts :: [ResultValue String]
exts = Results -> [ResultValue String]
resultsToStringValues Results
rs
signals :: ResultPredefinedSignals
signals = ExperimentData -> ResultPredefinedSignals
experimentPredefinedSignals ExperimentData
expdata
separator :: String
separator = TableView -> String
tableSeparator TableView
view
formatter :: ShowS
formatter = TableView -> ShowS
tableFormatter TableView
view
predicate :: Event Bool
predicate = TableView -> Event Bool
tablePredicate TableView
view
Int
i <- Parameter Int -> Composite Int
forall (m :: * -> *) a. ParameterLift m => Parameter a -> m a
liftParameter Parameter Int
simulationIndex
Signal ()
signal <-
case TableView -> Maybe Int
tableSeriesGridSize TableView
view of
Just Int
m ->
Event (Signal ()) -> Composite (Signal ())
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event (Signal ()) -> Composite (Signal ()))
-> Event (Signal ()) -> Composite (Signal ())
forall a b. (a -> b) -> a -> b
$
(Signal Int -> Signal ())
-> Event (Signal Int) -> Event (Signal ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Int -> ()) -> Signal Int -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal ((Int -> ()) -> Signal Int -> Signal ())
-> (Int -> ()) -> Signal Int -> Signal ()
forall a b. (a -> b) -> a -> b
$ () -> Int -> ()
forall a b. a -> b -> a
const ()) (Event (Signal Int) -> Event (Signal ()))
-> Event (Signal Int) -> Event (Signal ())
forall a b. (a -> b) -> a -> b
$
Int -> Event (Signal Int)
newSignalInTimeGrid Int
m
Maybe Int
Nothing ->
Signal () -> Composite (Signal ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Signal () -> Composite (Signal ()))
-> Signal () -> Composite (Signal ())
forall a b. (a -> b) -> a -> b
$
ResultPredefinedSignals -> ResultSignal -> Signal ()
pureResultSignal ResultPredefinedSignals
signals (ResultSignal -> Signal ()) -> ResultSignal -> Signal ()
forall a b. (a -> b) -> a -> b
$
Results -> ResultSignal
resultSignal Results
rs
let f :: String
f = Maybe String -> String
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Int -> Map Int String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (TableViewState -> Map Int String
tableMap TableViewState
st)
Handle
h <- IO Handle -> Composite Handle
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Handle -> Composite Handle) -> IO Handle -> Composite Handle
forall a b. (a -> b) -> a -> b
$ String -> IOMode -> IO Handle
openFile String
f IOMode
WriteMode
IO () -> Composite ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Composite ()) -> IO () -> Composite ()
forall a b. (a -> b) -> a -> b
$
do [(Integer, ResultValue String)]
-> ((Integer, ResultValue String) -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Integer]
-> [ResultValue String] -> [(Integer, ResultValue String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] [ResultValue String]
exts) (((Integer, ResultValue String) -> IO ()) -> IO ())
-> ((Integer, ResultValue String) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Integer
column, ResultValue String
ext) ->
do Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
column Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Handle -> String -> IO ()
hPutStr Handle
h String
separator
Handle -> String -> IO ()
hPutStr Handle
h (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ ShowS
forall a. Show a => a -> String
show ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [ResultId] -> String
loc ([ResultId] -> String) -> [ResultId] -> String
forall a b. (a -> b) -> a -> b
$ ResultValue String -> [ResultId]
forall e. ResultValue e -> [ResultId]
resultValueIdPath ResultValue String
ext
Handle -> String -> IO ()
hPutStrLn Handle
h String
""
Signal () -> (() -> Event ()) -> Composite ()
forall a. Signal a -> (a -> Event ()) -> Composite ()
handleSignalComposite Signal ()
signal ((() -> Event ()) -> Composite ())
-> (() -> Event ()) -> Composite ()
forall a b. (a -> b) -> a -> b
$ \()
t ->
do Bool
p <- Event Bool
predicate
Bool -> Event () -> Event ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
p (Event () -> Event ()) -> Event () -> Event ()
forall a b. (a -> b) -> a -> b
$
do [(Integer, ResultValue String)]
-> ((Integer, ResultValue String) -> Event ()) -> Event ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Integer]
-> [ResultValue String] -> [(Integer, ResultValue String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] [ResultValue String]
exts) (((Integer, ResultValue String) -> Event ()) -> Event ())
-> ((Integer, ResultValue String) -> Event ()) -> Event ()
forall a b. (a -> b) -> a -> b
$ \(Integer
column, ResultValue String
ext) ->
do String
x <- ResultValue String -> ResultData String
forall e. ResultValue e -> ResultData e
resultValueData ResultValue String
ext
IO () -> Event ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$
do Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
column Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Handle -> String -> IO ()
hPutStr Handle
h String
separator
Handle -> String -> IO ()
hPutStr Handle
h (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ ShowS
formatter String
x
IO () -> Event ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
h String
""
DisposableEvent -> Composite ()
disposableComposite (DisposableEvent -> Composite ())
-> DisposableEvent -> Composite ()
forall a b. (a -> b) -> a -> b
$
Event () -> DisposableEvent
DisposableEvent (Event () -> DisposableEvent) -> Event () -> DisposableEvent
forall a b. (a -> b) -> a -> b
$
IO () -> Event ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$
do Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Experiment -> Bool
experimentVerbose (Experiment -> Bool) -> Experiment -> Bool
forall a b. (a -> b) -> a -> b
$ TableViewState -> Experiment
tableExperiment TableViewState
st) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
String -> IO ()
putStr String
"Generated file " IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> IO ()
putStrLn String
f
Handle -> IO ()
hClose Handle
h
tableHtml :: TableViewState -> Int -> HtmlWriter ()
tableHtml :: TableViewState -> Int -> HtmlWriter ()
tableHtml TableViewState
st Int
index =
let n :: Int
n = Experiment -> Int
experimentRunCount (Experiment -> Int) -> Experiment -> Int
forall a b. (a -> b) -> a -> b
$ TableViewState -> Experiment
tableExperiment TableViewState
st
in if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
then TableViewState -> Int -> HtmlWriter ()
tableHtmlSingle TableViewState
st Int
index
else TableViewState -> Int -> HtmlWriter ()
tableHtmlMultiple TableViewState
st Int
index
tableHtmlSingle :: TableViewState -> Int -> HtmlWriter ()
tableHtmlSingle :: TableViewState -> Int -> HtmlWriter ()
tableHtmlSingle TableViewState
st Int
index =
do TableViewState -> Int -> HtmlWriter ()
header TableViewState
st Int
index
let f :: String
f = Maybe String -> String
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Int -> Map Int String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Int
0 (TableViewState -> Map Int String
tableMap TableViewState
st)
HtmlWriter () -> HtmlWriter ()
writeHtmlParagraph (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter () -> HtmlWriter ()
writeHtmlLink (String -> ShowS
makeRelative (TableViewState -> String
tableDir TableViewState
st) String
f) (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter ()
writeHtmlText (TableView -> String
tableLinkText (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st)
tableHtmlMultiple :: TableViewState -> Int -> HtmlWriter ()
tableHtmlMultiple :: TableViewState -> Int -> HtmlWriter ()
tableHtmlMultiple TableViewState
st Int
index =
do TableViewState -> Int -> HtmlWriter ()
header TableViewState
st Int
index
let n :: Int
n = Experiment -> Int
experimentRunCount (Experiment -> Int) -> Experiment -> Int
forall a b. (a -> b) -> a -> b
$ TableViewState -> Experiment
tableExperiment TableViewState
st
[Int] -> (Int -> HtmlWriter ()) -> HtmlWriter ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..(Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)] ((Int -> HtmlWriter ()) -> HtmlWriter ())
-> (Int -> HtmlWriter ()) -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
do let f :: String
f = Maybe String -> String
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Int -> Map Int String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Int
i (TableViewState -> Map Int String
tableMap TableViewState
st)
sublink :: String
sublink =
String -> String -> ShowS
replace String
"$RUN_INDEX" (Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> String -> ShowS
replace String
"$RUN_COUNT" (Int -> String
forall a. Show a => a -> String
show Int
n) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> String -> ShowS
replace String
"$LINK" (TableView -> String
tableLinkText (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st)
(TableView -> String
tableRunLinkText (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st)
HtmlWriter () -> HtmlWriter ()
writeHtmlParagraph (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter () -> HtmlWriter ()
writeHtmlLink (String -> ShowS
makeRelative (TableViewState -> String
tableDir TableViewState
st) String
f) (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter ()
writeHtmlText String
sublink
header :: TableViewState -> Int -> HtmlWriter ()
TableViewState
st Int
index =
do String -> HtmlWriter () -> HtmlWriter ()
writeHtmlHeader3WithId (String
"id" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
index) (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter ()
writeHtmlText (TableView -> String
tableTitle (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st)
let description :: String
description = TableView -> String
tableDescription (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st
Bool -> HtmlWriter () -> HtmlWriter ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
description) (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
HtmlWriter () -> HtmlWriter ()
writeHtmlParagraph (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter ()
writeHtmlText String
description
tableTOCHtml :: TableViewState -> Int -> HtmlWriter ()
tableTOCHtml :: TableViewState -> Int -> HtmlWriter ()
tableTOCHtml TableViewState
st Int
index =
HtmlWriter () -> HtmlWriter ()
writeHtmlListItem (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter () -> HtmlWriter ()
writeHtmlLink (String
"#id" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
index) (HtmlWriter () -> HtmlWriter ()) -> HtmlWriter () -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$
String -> HtmlWriter ()
writeHtmlText (TableView -> String
tableTitle (TableView -> String) -> TableView -> String
forall a b. (a -> b) -> a -> b
$ TableViewState -> TableView
tableView TableViewState
st)