{-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-| Module : Knit.Report.Other.Lucid Description : freer-simple random effect Copyright : (c) Adam Conner-Sax 2019 License : BSD-3-Clause Maintainer : adam_conner_sax@yahoo.com Stability : experimental Functions to support some simple reports using Lucid. Particularly to support adding latex and hvega charts. -} module Knit.Report.Other.Lucid ( -- * Setup, headers, scripts, etc. makeReportHtml -- * add specific report bits , placeVisualization , placeTextSection , latexToHtml -- * helpers , latex_ ) where import qualified Data.Aeson.Encode.Pretty as A import qualified Data.ByteString.Lazy.Char8 as BS import Data.Monoid ((<>)) import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Graphics.Vega.VegaLite as GV import qualified Lucid as H import qualified Text.Pandoc as P -- | Convert Latex to Lucid Html latexToHtml :: T.Text -> H.Html () latexToHtml lText = do let latexReadOptions = P.def htmlWriteOptions = P.def { P.writerHTMLMathMethod = P.MathJax "" } asHtml = P.readLaTeX latexReadOptions lText >>= P.writeHtml5String htmlWriteOptions case P.runPure asHtml of Left err -> H.span_ (H.toHtml $ show err) Right htmlText -> H.span_ (H.toHtmlRaw htmlText) -- | Convert Latex to Lucid Html latex_ :: T.Text -> H.Html () latex_ = latexToHtml -- | Add headers for MathJax mathJaxScript :: H.Html () mathJaxScript = H.script_ [H.src_ "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML", H.async_ ""] ("" :: String) -- | Add headers to use vega-lite (v2) vegaScripts2 :: H.Html () vegaScripts2 = do H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega@4.4.0"] ("" :: String) H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega-lite@3.0.0-rc11"] ("" :: String) H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega-embed@3.28.0"] ("" :: String) -- | Add headers to use vega-lite (v3) vegaScripts3 :: H.Html () vegaScripts3 = do H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega@4.4.0/build/vega.js"] ("" :: String) H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega-lite@3.0.0-rc12/build/vega-lite.js"] ("" :: String) H.script_ [H.src_ "https://cdn.jsdelivr.net/npm/vega-embed@3.29.1/build/vega-embed.js"] ("" :: String) -- | Add headers to use Tufte css tufteSetup :: H.Html () tufteSetup = do H.link_ [H.rel_ "stylesheet", H.href_ "https://cdnjs.cloudflare.com/ajax/libs/tufte-css/1.4/tufte.min.css"] H.meta_ [H.name_ "viewport", H.content_"width=device-width, initial-scale=1"] -- | -- | wrap given html in appropriate headers for the hvega and latex functions to work makeReportHtml :: T.Text -> H.Html a -> H.Html a makeReportHtml title reportHtml = H.html_ $ htmlHead >> H.body_ (H.article_ reportHtml) where htmlHead :: H.Html () = H.head_ (do H.title_ (H.toHtmlRaw title) tufteSetup mathJaxScript vegaScripts2 return () ) -- | add an hvega visualization with the given id placeVisualization :: T.Text -> GV.VegaLite -> H.Html () placeVisualization idText vl = let vegaScript :: T.Text = T.decodeUtf8 $ BS.toStrict $ A.encodePretty $ GV.fromVL vl script = "var vlSpec=\n" <> vegaScript <> ";\n" <> "vegaEmbed(\'#" <> idText <> "\',vlSpec);" in H.figure_ [H.id_ idText] (H.script_ [H.type_ "text/javascript"] (H.toHtmlRaw script)) -- | add the given Html as a new section placeTextSection :: H.Html () -> H.Html () placeTextSection = H.section_ [{- attributes/styles here -}]