visie-0.6.2.0: src/Visie.hs
{-# LANGUAGE OverloadedStrings #-}
module Visie (
visie,
custom,
defaultOptions,
Options(..),
ResourceDesc(..),
D3Version(..)
) where
import Browse (browseLinked, Asset(..))
import Paths_visie (getDataFileName)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Visie.Index
data D3Version = Version2 | Version3 | Version4 deriving Eq
-- resource description specified by the user, to be fetched from the
-- `data/` directory in the user package and transformed into a
-- Resource to be served
data ResourceDesc = ResourceDesc {
fetch :: FilePath,
serve :: String
}
data Options = Options {
d3Version :: D3Version,
index :: Index,
scriptDesc :: ResourceDesc,
styleDesc :: ResourceDesc,
additionalScripts :: [ResourceDesc]
}
defaultOptions = Options {
d3Version = Version4,
index = SVG,
scriptDesc = ResourceDesc "data/script.js" "script.js",
styleDesc = ResourceDesc "data/style.css" "style.css",
additionalScripts = []
}
getResource fileNameGetter (ResourceDesc { fetch = f, serve = s}) = do
fileName <- fileNameGetter f
content <- T.readFile fileName
return Asset { location = s, content = content }
-- common resources are included in the Visie package and can use the
-- local getter
getCommonResource = getResource getDataFileName
d3FileNameFromOptions o
| v == Version2 = "d3.v2.js"
| v == Version3 = "d3.v3.js"
| v == Version4 = "d3.v4.js"
where v = d3Version o
getCommonResources :: Options -> IO [Asset]
getCommonResources options = do
d3 <- getCommonResource d3ResourceDesc
pure [index', d3]
where d3FileName = d3FileNameFromOptions options
scriptsToAdd = (map serve . additionalScripts) options
index' = Asset {
location = "index.html",
content = makeIndex d3FileName (index options) scriptsToAdd
}
d3ResourceDesc = ResourceDesc {
fetch = "data/" ++ d3FileName,
serve = d3FileName
}
custom :: Options -> (FilePath -> IO FilePath) -> (a -> T.Text) -> a -> IO ()
custom options fileNameGetter transform d = do
common <- getCommonResources options
user <- sequence (map (getResource fileNameGetter) userDescriptors)
browseLinked (common <> user <> [dataRes])
return ()
where userDescriptors = [style, script] ++ additional
additional = additionalScripts options
style = styleDesc options
script = scriptDesc options
dataRes = Asset "data.js" . pad . transform $ d
pad s = T.concat ["visie(", s, ")"]
visie = custom defaultOptions