{-# LANGUAGE OverloadedStrings #-}
module Language.Ltml.HTML
(
renderSectionHtmlCss
, renderHtmlCss
, renderHtmlCssWith
, renderHtmlCssExport
, renderHtmlCssBS
, renderTocList
) where
import Clay (Css)
import Control.Monad.Reader
import Control.Monad.State
import Data.Bifunctor (bimap)
import Data.ByteString.Lazy (ByteString)
import Data.DList (toList)
import qualified Data.Map as Map
import Data.Text (Text, pack)
import Language.Ltml.AST.DocumentContainer
( DocumentContainer (..)
)
import Language.Ltml.AST.Footnote (Footnote (..))
import Language.Ltml.AST.Label (Label (..))
import Language.Ltml.AST.Section
import Language.Ltml.Common (Flagged')
import Language.Ltml.HTML.CSS (mainStylesheet)
import qualified Language.Ltml.HTML.CSS.Classes as Class
import Language.Ltml.HTML.CSS.Util
import Language.Ltml.HTML.Common
import Language.Ltml.HTML.ToHtmlM (toHtmlM)
import Lucid
renderSectionHtmlCss
:: FormattedSection -> Map.Map Label Footnote -> (Html (), Css)
renderSectionHtmlCss :: FormattedSection -> Map Label Footnote -> (Html (), Css)
renderSectionHtmlCss FormattedSection
section Map Label Footnote
fnMap =
let readerState :: ReaderState
readerState = ReaderState
initReaderState {footnoteMap = fnMap}
(Delayed (Html ())
delayedHtml, GlobalState
finalState) = ReaderStateMonad (Delayed (Html ()))
-> ReaderState -> GlobalState -> (Delayed (Html ()), GlobalState)
forall a.
ReaderStateMonad a
-> ReaderState -> GlobalState -> (a, GlobalState)
runReaderState (FormattedSection -> ReaderStateMonad (Delayed (Html ()))
forall a. ToHtmlM a => a -> ReaderStateMonad (Delayed (Html ()))
toHtmlM FormattedSection
section) ReaderState
readerState GlobalState
initGlobalState
in (GlobalState -> Delayed (Html ()) -> Html ()
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalState Delayed (Html ())
delayedHtml, EnumStyleMap -> Css
mainStylesheet (GlobalState -> EnumStyleMap
enumStyles GlobalState
finalState))
renderHtmlCss :: Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCss :: Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCss = ReaderState
-> GlobalState -> Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCssWith ReaderState
initReaderState GlobalState
initGlobalState
renderHtmlCssWith
:: ReaderState -> GlobalState -> Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCssWith :: ReaderState
-> GlobalState -> Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCssWith ReaderState
readerState GlobalState
globalState Flagged' DocumentContainer
docContainer =
let (Delayed (Html ())
delayedHtml, GlobalState
finalState) = ReaderStateMonad (Delayed (Html ()))
-> ReaderState -> GlobalState -> (Delayed (Html ()), GlobalState)
forall a.
ReaderStateMonad a
-> ReaderState -> GlobalState -> (a, GlobalState)
runReaderState (Flagged' DocumentContainer -> ReaderStateMonad (Delayed (Html ()))
forall a. ToHtmlM a => a -> ReaderStateMonad (Delayed (Html ()))
toHtmlM Flagged' DocumentContainer
docContainer) ReaderState
readerState GlobalState
globalState
in (GlobalState -> Delayed (Html ()) -> Html ()
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalState Delayed (Html ())
delayedHtml, EnumStyleMap -> Css
mainStylesheet (GlobalState -> EnumStyleMap
enumStyles GlobalState
finalState))
renderHtmlCssExport
:: FilePath
-> ReaderState
-> GlobalState
-> ReaderState
-> Flagged' DocumentContainer
-> Maybe
( Html ()
,
Css
,
[(Text, Text, Html ())]
,
Text
)
renderHtmlCssExport :: FilePath
-> ReaderState
-> GlobalState
-> ReaderState
-> Flagged' DocumentContainer
-> Maybe (Html (), Css, [(Text, Text, Html ())], Text)
renderHtmlCssExport FilePath
backPath ReaderState
readerState GlobalState
globalState ReaderState
exportReaderState Flagged' DocumentContainer
docCon =
let (Delayed (Html ())
delayedHtml, GlobalState
finalState) = State GlobalState (Delayed (Html ()))
-> GlobalState -> (Delayed (Html ()), GlobalState)
forall s a. State s a -> s -> (a, s)
runState (ReaderStateMonad (Delayed (Html ()))
-> ReaderState -> State GlobalState (Delayed (Html ()))
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (Flagged' DocumentContainer -> ReaderStateMonad (Delayed (Html ()))
forall a. ToHtmlM a => a -> ReaderStateMonad (Delayed (Html ()))
toHtmlM Flagged' DocumentContainer
docCon) ReaderState
readerState) GlobalState
globalState
mainHtml :: Html ()
mainHtml = GlobalState -> Delayed (Html ()) -> Html ()
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalState Delayed (Html ())
delayedHtml
css :: Css
css = EnumStyleMap -> Css
mainStylesheet (GlobalState -> EnumStyleMap
enumStyles GlobalState
finalState)
mainDocTitleHtml :: Delayed (Html ())
mainDocTitleHtml = GlobalState -> Delayed (Html ())
mainDocumentTitleHtml GlobalState
finalState
rawMainDocTitle :: Text
rawMainDocTitle = GlobalState -> Delayed Text -> Text
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalState (Delayed Text -> Text) -> Delayed Text -> Text
forall a b. (a -> b) -> a -> b
$ GlobalState -> Delayed Text
mainDocumentTitle GlobalState
finalState
(Delayed (Html ())
_, GlobalState
finalExportState) = ReaderStateMonad (Delayed (Html ()))
-> ReaderState -> GlobalState -> (Delayed (Html ()), GlobalState)
forall a.
ReaderStateMonad a
-> ReaderState -> GlobalState -> (a, GlobalState)
runReaderState (Flagged' DocumentContainer -> ReaderStateMonad (Delayed (Html ()))
forall a. ToHtmlM a => a -> ReaderStateMonad (Delayed (Html ()))
toHtmlM Flagged' DocumentContainer
docCon) ReaderState
exportReaderState GlobalState
globalState
backButton :: Html ()
backButton =
Html () -> Html ()
forall arg result. Term arg result => arg -> result
div_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$
[Attributes] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
a_ [Class -> Attributes
cssClass_ Class
Class.ButtonLink, Text -> Attributes
href_ (Text -> Attributes) -> Text -> Attributes
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
pack FilePath
backPath] (Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
forall (m :: * -> *). Monad m => Text -> HtmlT m ()
toHtml (Text
"←" :: Text))
sections :: [(Text, Text, Html ())]
sections =
((Text, Delayed Text, Delayed (Html ())) -> (Text, Text, Html ()))
-> [(Text, Delayed Text, Delayed (Html ()))]
-> [(Text, Text, Html ())]
forall a b. (a -> b) -> [a] -> [b]
map
( \(Text
htmlId, Delayed Text
dTitle, Delayed (Html ())
dHtml) ->
( Text
htmlId
, GlobalState -> Delayed Text -> Text
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalExportState Delayed Text
dTitle
, GlobalState -> Delayed (Html ()) -> Html ()
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalExportState
(Delayed (Html ()) -> Html ())
-> (Delayed (Html ()) -> Delayed (Html ()))
-> Delayed (Html ())
-> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( (Html () -> Html ()) -> Delayed (Html ()) -> Delayed (Html ())
forall a b. (a -> b) -> Delayed a -> Delayed b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Html () -> Html () -> Html ()
forall a. a -> Html () -> a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Html ()
backButton (Html () -> Html ()) -> (Html () -> Html ()) -> Html () -> Html ()
forall a. Semigroup a => a -> a -> a
<> [Attributes] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
div_ ([Attributes] -> Html () -> Html ()) -> Class -> Html () -> Html ()
forall a. ([Attributes] -> a) -> Class -> a
<#> Class
Class.Document)
(Delayed (Html ()) -> Delayed (Html ()))
-> (Delayed (Html ()) -> Delayed (Html ()))
-> Delayed (Html ())
-> Delayed (Html ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Delayed (Html ())
mainDocTitleHtml Delayed (Html ()) -> Delayed (Html ()) -> Delayed (Html ())
forall a. Semigroup a => a -> a -> a
<>)
)
(Delayed (Html ()) -> Html ()) -> Delayed (Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ Delayed (Html ())
dHtml
)
)
(GlobalState -> [(Text, Delayed Text, Delayed (Html ()))]
exportSections GlobalState
finalExportState)
in if GlobalState -> Bool
hasErrors GlobalState
finalState
then Maybe (Html (), Css, [(Text, Text, Html ())], Text)
forall a. Maybe a
Nothing
else (Html (), Css, [(Text, Text, Html ())], Text)
-> Maybe (Html (), Css, [(Text, Text, Html ())], Text)
forall a. a -> Maybe a
Just (Html ()
mainHtml, Css
css, [(Text, Text, Html ())]
sections, Text
rawMainDocTitle)
renderHtmlCssBS :: Flagged' DocumentContainer -> ByteString
renderHtmlCssBS :: Flagged' DocumentContainer -> ByteString
renderHtmlCssBS Flagged' DocumentContainer
docCon =
let (Html ()
body, Css
css) = Flagged' DocumentContainer -> (Html (), Css)
renderHtmlCss Flagged' DocumentContainer
docCon
in Html () -> ByteString
forall a. Html a -> ByteString
renderBS (Html () -> ByteString) -> Html () -> ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> Css -> Html () -> Html ()
addInlineCssHeader FilePath
"Generated Document Preview" Css
css Html ()
body
renderTocList
:: Flagged' DocumentContainer -> [RenderedTocEntry]
renderTocList :: Flagged' DocumentContainer -> [RenderedTocEntry]
renderTocList Flagged' DocumentContainer
docContainer =
let (Delayed (Html ())
_, GlobalState
finalState) =
State GlobalState (Delayed (Html ()))
-> GlobalState -> (Delayed (Html ()), GlobalState)
forall s a. State s a -> s -> (a, s)
runState
( ReaderStateMonad (Delayed (Html ()))
-> ReaderState -> State GlobalState (Delayed (Html ()))
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT
(Flagged' DocumentContainer -> ReaderStateMonad (Delayed (Html ()))
forall a. ToHtmlM a => a -> ReaderStateMonad (Delayed (Html ()))
toHtmlM Flagged' DocumentContainer
docContainer)
(ReaderState
initReaderState {appendixHasGlobalToC = True})
)
GlobalState
initGlobalState
tocList :: [Either PhantomTocEntry TocEntry]
tocList = DList (Either PhantomTocEntry TocEntry)
-> [Either PhantomTocEntry TocEntry]
forall a. DList a -> [a]
toList (DList (Either PhantomTocEntry TocEntry)
-> [Either PhantomTocEntry TocEntry])
-> DList (Either PhantomTocEntry TocEntry)
-> [Either PhantomTocEntry TocEntry]
forall a b. (a -> b) -> a -> b
$ GlobalState -> DList (Either PhantomTocEntry TocEntry)
tableOfContents GlobalState
finalState
htmlTitleList :: [PhantomTocEntry]
htmlTitleList =
(Either PhantomTocEntry TocEntry -> PhantomTocEntry)
-> [Either PhantomTocEntry TocEntry] -> [PhantomTocEntry]
forall a b. (a -> b) -> [a] -> [b]
map
( (PhantomTocEntry -> PhantomTocEntry)
-> (TocEntry -> PhantomTocEntry)
-> Either PhantomTocEntry TocEntry
-> PhantomTocEntry
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
((Maybe (Html ()) -> Maybe (Html ()))
-> (Result (Html ()) -> Result (Html ()))
-> PhantomTocEntry
-> PhantomTocEntry
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (Html () -> Html ()
forall arg result. Term arg result => arg -> result
span_ (Html () -> Html ()) -> Maybe (Html ()) -> Maybe (Html ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Html () -> Html ()
forall arg result. Term arg result => arg -> result
span_ (Html () -> Html ()) -> Result (Html ()) -> Result (Html ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>))
( \(Maybe (Html ())
mId, Result (Delayed (Html ()))
rDt, Text
_, TocCategory
_) -> (Html () -> Html ()
forall arg result. Term arg result => arg -> result
span_ (Html () -> Html ()) -> Maybe (Html ()) -> Maybe (Html ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Html ())
mId, Html () -> Html ()
forall arg result. Term arg result => arg -> result
span_ (Html () -> Html ())
-> (Delayed (Html ()) -> Html ()) -> Delayed (Html ()) -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalState -> Delayed (Html ()) -> Html ()
forall a. GlobalState -> Delayed a -> a
evalDelayed GlobalState
finalState (Delayed (Html ()) -> Html ())
-> Result (Delayed (Html ())) -> Result (Html ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Result (Delayed (Html ()))
rDt)
)
)
[Either PhantomTocEntry TocEntry]
tocList
in
(PhantomTocEntry -> RenderedTocEntry)
-> [PhantomTocEntry] -> [RenderedTocEntry]
forall a b. (a -> b) -> [a] -> [b]
map ((Maybe (Html ()) -> Maybe ByteString)
-> (Result (Html ()) -> Result ByteString)
-> PhantomTocEntry
-> RenderedTocEntry
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((Html () -> ByteString) -> Maybe (Html ()) -> Maybe ByteString
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Html () -> ByteString
forall a. Html a -> ByteString
renderBS) ((Html () -> ByteString) -> Result (Html ()) -> Result ByteString
forall a b. (a -> b) -> Result a -> Result b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Html () -> ByteString
forall a. Html a -> ByteString
renderBS)) [PhantomTocEntry]
htmlTitleList