{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Provides a way to convert the AST into the intermediate structure PreLaTeX.
-- To this end a polymorphic typeclass ToPreLaTeXM that provides the function toPreLaTeXM is introduced
-- and instances for all datatypes of the AST are defined.
module Language.Ltml.ToLaTeX.ToPreLaTeXM (ToPreLaTeXM (..))
where

import Control.Lens (use, (%=), (.=))
import Control.Monad (foldM)
import Control.Monad.State (State)
import qualified Data.DList as DList
import qualified Data.Map as Map
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typography (Typography (Typography))
import Data.Void (Void, absurd)
import Language.Lsd.AST.Format
    ( EnumItemKeyFormat (EnumItemKeyFormat)
    , HeadingFormat (HeadingFormat)
    , ParagraphKeyFormat (ParagraphKeyFormat)
    , TocKeyFormat (TocKeyFormat)
    )
import Language.Lsd.AST.Type.AppendixSection
    ( AppendixElementFormat (AppendixElementFormat)
    , AppendixSectionFormat (AppendixSectionFormat)
    , AppendixSectionTitle (AppendixSectionTitle)
    )
import Language.Lsd.AST.Type.Document
    ( DocumentFormat (..)
    , TocFormat (TocFormat)
    , TocHeading (TocHeading)
    )
import Language.Lsd.AST.Type.DocumentContainer
    ( DocumentContainerFormat (DocumentContainerFormat)
    , MainDocumentFormat (MainDocumentFormat)
    )
import Language.Lsd.AST.Type.Enum
    ( EnumFormat (..)
    , EnumItemFormat (EnumItemFormat)
    )
import Language.Lsd.AST.Type.Paragraph (ParagraphFormat (ParagraphFormat))
import Language.Lsd.AST.Type.Section
    ( SectionFormat (SectionFormat)
    , SectionFormatted (SectionFormatted)
    )
import Language.Lsd.AST.Type.SimpleParagraph
    ( SimpleParagraphFormat (SimpleParagraphFormat)
    )
import Language.Lsd.AST.Type.SimpleSection
    ( SimpleSectionFormat (SimpleSectionFormat)
    )
import Language.Lsd.AST.Type.Table
    ( BGColor (Gray, White)
    , CellFormat (CellFormat)
    )
import Language.Ltml.AST.AppendixSection (AppendixSection (AppendixSection))
import Language.Ltml.AST.Document
    ( Document (..)
    , DocumentBody (..)
    , DocumentHeading (DocumentHeading)
    )
import Language.Ltml.AST.DocumentContainer
    ( DocumentContainer (DocumentContainer)
    , DocumentContainerHeader (DocumentContainerHeader)
    )
import Language.Ltml.AST.Footnote (Footnote (Footnote))
import Language.Ltml.AST.Label (Label (..))
import Language.Ltml.AST.Node (Node (..))
import Language.Ltml.AST.Paragraph (Paragraph (..))
import Language.Ltml.AST.Section
    ( Heading (..)
    , Section (..)
    , SectionBody (InnerSectionBody, LeafSectionBody, SimpleLeafSectionBody)
    )
import Language.Ltml.AST.SimpleBlock
    ( SimpleBlock (SimpleParagraphBlock, TableBlock)
    )
import Language.Ltml.AST.SimpleParagraph (SimpleParagraph (SimpleParagraph))
import Language.Ltml.AST.SimpleSection (SimpleSection (SimpleSection))
import Language.Ltml.AST.Table
    ( Cell (Cell, HSpannedCell, VSpannedCell)
    , Row (Row)
    , Table (Table)
    )
import Language.Ltml.AST.Text
    ( EnumItem (..)
    , Enumeration (..)
    , FootnoteReference (..)
    , HardLineBreak (..)
    , SentenceStart (..)
    , TextTree (..)
    )
import Language.Ltml.Common
    ( Flagged (Flagged)
    , Flagged'
    , NavTocHeaded (NavTocHeaded)
    , Parsed
    )
import Language.Ltml.ToLaTeX.Format
    ( Stylable (..)
    , formatHeading
    , getEnumStyle
    , getIdentifier
    )
import qualified Language.Ltml.ToLaTeX.GlobalState as GS
import Language.Ltml.ToLaTeX.PreLaTeXType
    ( PreLaTeX (IRaw, ISequence, IText, MissingRef)
    , bold
    , cellcolor
    , cline
    , enumerate
    , footnote
    , footref
    , hline
    , hrule
    , hyperlink
    , hypertarget
    , label
    , linebreak
    , makecell
    , multicolumn
    , multirow
    , newpage
    , resetfootnote
    , setpdftitle
    , tabular
    )
import Numeric (showFFloat)
import Text.Megaparsec (errorBundlePretty)

-- | class to convert AST objects into PreLaTeX. To be able to automatically generate
--   numbers and context for each object, the class function toPreLaTeXM works
--   in a State monad.
class ToPreLaTeXM a where
    toPreLaTeXM :: a -> State GS.GlobalState PreLaTeX

-- | helper class to pass labels from the AST object Node to its children
class Labelable a where
    attachLabel :: Maybe Label -> a -> State GS.GlobalState PreLaTeX

-------------------------------- Void -----------------------------------

instance ToPreLaTeXM Void where
    toPreLaTeXM :: Void -> State GlobalState PreLaTeX
toPreLaTeXM = Void -> State GlobalState PreLaTeX
forall a. Void -> a
absurd

-------------------------------- [] -----------------------------------

instance (ToPreLaTeXM a) => ToPreLaTeXM [a] where
    toPreLaTeXM :: [a] -> State GlobalState PreLaTeX
toPreLaTeXM [a]
content = do
        [PreLaTeX]
content' <- (a -> State GlobalState PreLaTeX)
-> [a] -> StateT GlobalState Identity [PreLaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM a -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [a]
content
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ [PreLaTeX] -> PreLaTeX
ISequence [PreLaTeX]
content'

-------------------------------- Maybe -----------------------------------

instance (ToPreLaTeXM a) => ToPreLaTeXM (Maybe a) where
    toPreLaTeXM :: Maybe a -> State GlobalState PreLaTeX
toPreLaTeXM Maybe a
Nothing = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty
    toPreLaTeXM (Just a
content) = do
        a -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM a
content

------------------------------- Flagged ----------------------------------

-- | This instance manages which part of the AST is actually translated into LaTeX;
--   Everything else is just used to build up the needed context (labels, etc.)
instance (ToPreLaTeXM a) => ToPreLaTeXM (Flagged' a) where
    toPreLaTeXM :: Flagged' a -> State GlobalState PreLaTeX
toPreLaTeXM (Flagged Bool
b a
content) = do
        -- \| first check whether the global render flag (flaggedParent) is set
        Bool
b0 <- Getting Bool GlobalState Bool -> StateT GlobalState Identity Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const Bool FlagState)
-> GlobalState -> Const Bool GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const Bool FlagState)
 -> GlobalState -> Const Bool GlobalState)
-> ((Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState)
-> Getting Bool GlobalState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState
Lens' FlagState Bool
GS.flaggedParent)
        -- \| set the scope for the content
        ((FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((Bool -> Identity Bool) -> FlagState -> Identity FlagState)
-> (Bool -> Identity Bool)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> FlagState -> Identity FlagState
Lens' FlagState Bool
GS.flaggedParent) ((Bool -> Identity Bool) -> GlobalState -> Identity GlobalState)
-> Bool -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= (Bool
b Bool -> Bool -> Bool
|| Bool
b0)
        ((FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((Bool -> Identity Bool) -> FlagState -> Identity FlagState)
-> (Bool -> Identity Bool)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> FlagState -> Identity FlagState
Lens' FlagState Bool
GS.flaggedChildren) ((Bool -> Identity Bool) -> GlobalState -> Identity GlobalState)
-> Bool -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
False
        -- \| run the state to build the globalstate and get the potential result
        PreLaTeX
res <- a -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM a
content
        -- \| reset the scope
        ((FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((Bool -> Identity Bool) -> FlagState -> Identity FlagState)
-> (Bool -> Identity Bool)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> FlagState -> Identity FlagState
Lens' FlagState Bool
GS.flaggedParent) ((Bool -> Identity Bool) -> GlobalState -> Identity GlobalState)
-> Bool -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
b0
        Bool
isParent <- Getting Bool GlobalState Bool -> StateT GlobalState Identity Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const Bool FlagState)
-> GlobalState -> Const Bool GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const Bool FlagState)
 -> GlobalState -> Const Bool GlobalState)
-> ((Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState)
-> Getting Bool GlobalState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState
Lens' FlagState Bool
GS.flaggedChildren)
        ((FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((Bool -> Identity Bool) -> FlagState -> Identity FlagState)
-> (Bool -> Identity Bool)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> FlagState -> Identity FlagState
Lens' FlagState Bool
GS.flaggedChildren) ((Bool -> Identity Bool) -> GlobalState -> Identity GlobalState)
-> Bool -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
True
        -- \| return the result if needed
        if Bool -> Bool
not Bool
isParent Bool -> Bool -> Bool
&& Bool -> Bool
not (Bool
b Bool -> Bool -> Bool
|| Bool
b0)
            then PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty
            else PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
res

-------------------------------- Node -----------------------------------

-- | the provided label is passed to the content of the node using
--   the helper class Labelable
instance (Labelable a) => ToPreLaTeXM (Node a) where
    toPreLaTeXM :: Node a -> State GlobalState PreLaTeX
toPreLaTeXM (Node Maybe Label
mLabel a
content) = Maybe Label -> a -> State GlobalState PreLaTeX
forall a.
Labelable a =>
Maybe Label -> a -> State GlobalState PreLaTeX
attachLabel Maybe Label
mLabel a
content

-------------------------------- Text -----------------------------------

instance
    ( Stylable style
    , ToPreLaTeXM lbrk
    , ToPreLaTeXM fnref
    , ToPreLaTeXM enum
    , ToPreLaTeXM special
    )
    => ToPreLaTeXM (TextTree lbrk fnref style enum special)
    where
    toPreLaTeXM :: TextTree lbrk fnref style enum special
-> State GlobalState PreLaTeX
toPreLaTeXM (Word Text
t) = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Text -> PreLaTeX
IText Text
t
    toPreLaTeXM TextTree lbrk fnref style enum special
Space = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Text -> PreLaTeX
IText Text
" "
    toPreLaTeXM TextTree lbrk fnref style enum special
NonBreakingSpace = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Text -> PreLaTeX
IRaw Text
"~"
    toPreLaTeXM (LineBreak lbrk
lbrk) = lbrk -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM lbrk
lbrk
    toPreLaTeXM (Special special
s) = special -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM special
s
    toPreLaTeXM (Reference Label
l) = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Label -> PreLaTeX
MissingRef Label
l
    toPreLaTeXM (Styled style
style [TextTree lbrk fnref style enum special]
tt) = do
        PreLaTeX
tt' <- [TextTree lbrk fnref style enum special]
-> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [TextTree lbrk fnref style enum special]
tt
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ style -> PreLaTeX -> PreLaTeX
forall a. Stylable a => a -> PreLaTeX -> PreLaTeX
applyTextStyle style
style PreLaTeX
tt'
    toPreLaTeXM (Enum enum
enum) = enum -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM enum
enum
    toPreLaTeXM (FootnoteRef fnref
fnref) = fnref -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM fnref
fnref

instance ToPreLaTeXM HardLineBreak where
    toPreLaTeXM :: HardLineBreak -> State GlobalState PreLaTeX
toPreLaTeXM HardLineBreak
HardLineBreak = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
linebreak

-- | Inserts footnotes depending on context
instance ToPreLaTeXM FootnoteReference where
    toPreLaTeXM :: FootnoteReference -> State GlobalState PreLaTeX
toPreLaTeXM (FootnoteReference l :: Label
l@(Label Text
lt)) = do
        Map Label Text
labelToRef <- Getting (Map Label Text) GlobalState (Map Label Text)
-> StateT GlobalState Identity (Map Label Text)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting (Map Label Text) GlobalState (Map Label Text)
Lens' GlobalState (Map Label Text)
GS.labelToRef
        -- \| first check whether a footnote has already been seen
        case Label -> Map Label Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Label
l Map Label Text
labelToRef of
            Maybe Text
Nothing -> do
                -- \| if the footnote has not been seen already then increase the counter,
                --                    insert the label into the map for normal refs and lookup the content
                --                    in the footnote map.
                --
                Int
n <- State GlobalState Int
GS.nextFootnote
                Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel (Label -> Maybe Label
forall a. a -> Maybe a
Just Label
l) (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
n)
                Map Label Footnote
labelToFootNote <- Getting (Map Label Footnote) GlobalState (Map Label Footnote)
-> StateT GlobalState Identity (Map Label Footnote)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting (Map Label Footnote) GlobalState (Map Label Footnote)
Lens' GlobalState (Map Label Footnote)
GS.labelToFootNote
                case Label -> Map Label Footnote -> Maybe Footnote
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Label
l Map Label Footnote
labelToFootNote of
                    -- \| TODO: maybe throw error if the footnote doesnt
                    --   actually exist? shouldnt happen in reality,
                    --   otherwise the parser is broken
                    Maybe Footnote
Nothing -> PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty
                    -- \| otherwise just get the content of the footnote
                    --   and add it to the output.
                    Just (Footnote FootnoteFormat
_ [FootnoteTextTree]
tt) -> do
                        PreLaTeX
tt' <- [FootnoteTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [FootnoteTextTree]
tt
                        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
                            PreLaTeX -> PreLaTeX
footnote (PreLaTeX -> PreLaTeX) -> PreLaTeX -> PreLaTeX
forall a b. (a -> b) -> a -> b
$
                                Label -> PreLaTeX -> PreLaTeX
hypertarget Label
l PreLaTeX
forall a. Monoid a => a
mempty
                                    PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> Text -> PreLaTeX
label Text
lt
                                    PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
tt'
            Just Text
_ -> PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Text -> PreLaTeX
footref Text
lt

-- \| if the footnote has been seen then just insert a
--                    superscript number, not the content again.
--

-- | creates an enumeration in latex. the format of the enumerations is passed
--   to the children via the state.
instance ToPreLaTeXM Enumeration where
    toPreLaTeXM :: Enumeration -> State GlobalState PreLaTeX
toPreLaTeXM
        ( Enumeration
                (EnumFormat (EnumItemFormat IdentifierFormat
ident (EnumItemKeyFormat KeyFormat
key)))
                [Node EnumItem]
enumItems
            ) = do
            IdentifierFormat
currentIdent <- Getting IdentifierFormat GlobalState IdentifierFormat
-> StateT GlobalState Identity IdentifierFormat
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FormatState -> Const IdentifierFormat FormatState)
-> GlobalState -> Const IdentifierFormat GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Const IdentifierFormat FormatState)
 -> GlobalState -> Const IdentifierFormat GlobalState)
-> ((IdentifierFormat -> Const IdentifierFormat IdentifierFormat)
    -> FormatState -> Const IdentifierFormat FormatState)
-> Getting IdentifierFormat GlobalState IdentifierFormat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IdentifierFormat -> Const IdentifierFormat IdentifierFormat)
-> FormatState -> Const IdentifierFormat FormatState
Lens' FormatState IdentifierFormat
GS.enumIdentifierFormat)
            ((FormatState -> Identity FormatState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Identity FormatState)
 -> GlobalState -> Identity GlobalState)
-> ((IdentifierFormat -> Identity IdentifierFormat)
    -> FormatState -> Identity FormatState)
-> (IdentifierFormat -> Identity IdentifierFormat)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IdentifierFormat -> Identity IdentifierFormat)
-> FormatState -> Identity FormatState
Lens' FormatState IdentifierFormat
GS.enumIdentifierFormat) ((IdentifierFormat -> Identity IdentifierFormat)
 -> GlobalState -> Identity GlobalState)
-> IdentifierFormat -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= IdentifierFormat
ident
            [PreLaTeX]
enumItems' <- (Node EnumItem -> State GlobalState PreLaTeX)
-> [Node EnumItem] -> StateT GlobalState Identity [PreLaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Node EnumItem -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Node EnumItem]
enumItems
            ((FormatState -> Identity FormatState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Identity FormatState)
 -> GlobalState -> Identity GlobalState)
-> ((IdentifierFormat -> Identity IdentifierFormat)
    -> FormatState -> Identity FormatState)
-> (IdentifierFormat -> Identity IdentifierFormat)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IdentifierFormat -> Identity IdentifierFormat)
-> FormatState -> Identity FormatState
Lens' FormatState IdentifierFormat
GS.enumIdentifierFormat) ((IdentifierFormat -> Identity IdentifierFormat)
 -> GlobalState -> Identity GlobalState)
-> IdentifierFormat -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= IdentifierFormat
currentIdent
            PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ [Text] -> [PreLaTeX] -> PreLaTeX
enumerate [IdentifierFormat -> KeyFormat -> Text
getEnumStyle IdentifierFormat
ident KeyFormat
key] [PreLaTeX]
enumItems'

instance ToPreLaTeXM EnumItem where
    toPreLaTeXM :: EnumItem -> State GlobalState PreLaTeX
toPreLaTeXM = Maybe Label -> EnumItem -> State GlobalState PreLaTeX
forall a.
Labelable a =>
Maybe Label -> a -> State GlobalState PreLaTeX
attachLabel Maybe Label
forall a. Maybe a
Nothing

-- | the current path to the item is saved in the enumPosition in the state.
--   this is mainly needed for the label though, as the format itself is managed
--   by the enumeration environment
instance Labelable EnumItem where
    attachLabel :: Maybe Label -> EnumItem -> State GlobalState PreLaTeX
attachLabel Maybe Label
mLabel (EnumItem [RichTextTree]
tt) = do
        [Int]
path <- State GlobalState [Int]
GS.nextEnumPosition
        IdentifierFormat
ident <- Getting IdentifierFormat GlobalState IdentifierFormat
-> StateT GlobalState Identity IdentifierFormat
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FormatState -> Const IdentifierFormat FormatState)
-> GlobalState -> Const IdentifierFormat GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Const IdentifierFormat FormatState)
 -> GlobalState -> Const IdentifierFormat GlobalState)
-> ((IdentifierFormat -> Const IdentifierFormat IdentifierFormat)
    -> FormatState -> Const IdentifierFormat FormatState)
-> Getting IdentifierFormat GlobalState IdentifierFormat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IdentifierFormat -> Const IdentifierFormat IdentifierFormat)
-> FormatState -> Const IdentifierFormat FormatState
Lens' FormatState IdentifierFormat
GS.enumIdentifierFormat)
        Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel Maybe Label
mLabel (IdentifierFormat -> Int -> Int -> Text
getIdentifier IdentifierFormat
ident ([Int] -> Int
forall a. HasCallStack => [a] -> a
last [Int]
path) Int
0)
        PreLaTeX
tt' <- State GlobalState PreLaTeX -> State GlobalState PreLaTeX
forall a. State GlobalState a -> State GlobalState a
GS.descendEnumTree (State GlobalState PreLaTeX -> State GlobalState PreLaTeX)
-> State GlobalState PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ [RichTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [RichTextTree]
tt
        let anchor :: PreLaTeX
anchor = PreLaTeX -> (Label -> PreLaTeX) -> Maybe Label -> PreLaTeX
forall b a. b -> (a -> b) -> Maybe a -> b
maybe PreLaTeX
forall a. Monoid a => a
mempty (Label -> PreLaTeX -> PreLaTeX
`hypertarget` PreLaTeX
forall a. Monoid a => a
mempty) Maybe Label
mLabel
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
anchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
tt'

-- | way to label a sentence
instance ToPreLaTeXM SentenceStart where
    toPreLaTeXM :: SentenceStart -> State GlobalState PreLaTeX
toPreLaTeXM (SentenceStart Maybe Label
mLabel) = do
        Int
n <- State GlobalState Int
GS.nextSentence
        Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel Maybe Label
mLabel (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
n))
        State GlobalState PreLaTeX
-> (Label -> State GlobalState PreLaTeX)
-> Maybe Label
-> State GlobalState PreLaTeX
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty) Label -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM Maybe Label
mLabel

-------------------------------- Label -----------------------------------

instance ToPreLaTeXM Label where
    toPreLaTeXM :: Label -> State GlobalState PreLaTeX
toPreLaTeXM Label
l = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Label -> PreLaTeX -> PreLaTeX
hyperlink Label
l PreLaTeX
forall a. Monoid a => a
mempty

-------------------------------- Paragraph -----------------------------------

instance ToPreLaTeXM SimpleParagraph where
    toPreLaTeXM :: SimpleParagraph -> State GlobalState PreLaTeX
toPreLaTeXM (SimpleParagraph (SimpleParagraphFormat Typography
t) [RichTextTree]
content) = do
        PreLaTeX
content' <- [RichTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [RichTextTree]
content
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Typography -> PreLaTeX -> PreLaTeX
forall a. Stylable a => a -> PreLaTeX -> PreLaTeX
applyTextStyle Typography
t PreLaTeX
content'

instance ToPreLaTeXM Paragraph where
    toPreLaTeXM :: Paragraph -> State GlobalState PreLaTeX
toPreLaTeXM = Maybe Label -> Paragraph -> State GlobalState PreLaTeX
forall a.
Labelable a =>
Maybe Label -> a -> State GlobalState PreLaTeX
attachLabel Maybe Label
forall a. Maybe a
Nothing

-- | paragraphs are rendered in an enumeration environment. therefor the current number is
--   set as a starting value. (there will not be more than one item)
--   could have been cleaner if the format of the paragraph was given to the LeafSectionBody.
instance Labelable Paragraph where
    attachLabel :: Maybe Label -> Paragraph -> State GlobalState PreLaTeX
attachLabel Maybe Label
mLabel (Paragraph (ParagraphFormat IdentifierFormat
ident (ParagraphKeyFormat KeyFormat
key)) [ParagraphTextTree]
content) = do
        Int
n <- State GlobalState Int
GS.nextParagraph
        let identifier :: Text
identifier = IdentifierFormat -> Int -> Int -> Text
getIdentifier IdentifierFormat
ident Int
n Int
0
        Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel Maybe Label
mLabel Text
identifier
        ([Int] -> Identity [Int]) -> GlobalState -> Identity GlobalState
Lens' GlobalState [Int]
GS.enumPosition (([Int] -> Identity [Int]) -> GlobalState -> Identity GlobalState)
-> [Int] -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= [Int
0]
        PreLaTeX
content' <- [ParagraphTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [ParagraphTextTree]
content
        let anchor :: PreLaTeX
anchor = PreLaTeX -> (Label -> PreLaTeX) -> Maybe Label -> PreLaTeX
forall b a. b -> (a -> b) -> Maybe a -> b
maybe PreLaTeX
forall a. Monoid a => a
mempty (Label -> PreLaTeX -> PreLaTeX
`hypertarget` PreLaTeX
forall a. Monoid a => a
mempty) Maybe Label
mLabel
        -- \^ attaches the label if it exists
        Bool
b <- Getting Bool GlobalState Bool -> StateT GlobalState Identity Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const Bool FlagState)
-> GlobalState -> Const Bool GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const Bool FlagState)
 -> GlobalState -> Const Bool GlobalState)
-> ((Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState)
-> Getting Bool GlobalState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState
Lens' FlagState Bool
GS.onlyOneParagraph)
        -- \^ not indented or numbered if there is only one paragraph
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
            PreLaTeX
anchor
                PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> if Bool
b
                    then PreLaTeX
content'
                    else
                        [Text] -> [PreLaTeX] -> PreLaTeX
enumerate
                            [ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ String
"start=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
n
                            , IdentifierFormat -> KeyFormat -> Text
getEnumStyle IdentifierFormat
ident KeyFormat
key
                            ]
                            [PreLaTeX
content']

-------------------------------- Section -----------------------------------

instance ToPreLaTeXM SimpleSection where
    toPreLaTeXM :: SimpleSection -> State GlobalState PreLaTeX
toPreLaTeXM (SimpleSection (SimpleSectionFormat Bool
hasHLine) [SimpleParagraph]
content) = do
        PreLaTeX
content' <- [SimpleParagraph] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [SimpleParagraph]
content
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ (if Bool
hasHLine then PreLaTeX
hrule else PreLaTeX
forall a. Monoid a => a
mempty) PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
content'

-- | there is no instance for the Headingtype, as it would be complicated to manage
--   regarding there are different situations in which a heading is used and moving
--   all the context via the state or a helper class or some other way would be tedious.
--   consequently we use a function that just builds the heading with the needed information.
createHeading
    :: HeadingFormat b -> PreLaTeX -> PreLaTeX -> State GS.GlobalState PreLaTeX
createHeading :: forall (b :: Bool).
HeadingFormat b
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
createHeading (HeadingFormat Typography
t FormatString (HeadingPlaceholderAtom b)
hfmt) PreLaTeX
tt PreLaTeX
ident = do
    PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
        Typography -> PreLaTeX -> PreLaTeX
forall a. Stylable a => a -> PreLaTeX -> PreLaTeX
applyTextStyle Typography
t (PreLaTeX -> PreLaTeX) -> PreLaTeX -> PreLaTeX
forall a b. (a -> b) -> a -> b
$
            FormatString (HeadingPlaceholderAtom b)
-> PreLaTeX -> PreLaTeX -> PreLaTeX
forall (b :: Bool).
FormatString (HeadingPlaceholderAtom b)
-> PreLaTeX -> PreLaTeX -> PreLaTeX
formatHeading FormatString (HeadingPlaceholderAtom b)
hfmt PreLaTeX
ident PreLaTeX
tt

instance (ToPreLaTeXM a) => ToPreLaTeXM (SectionFormatted (Parsed a)) where
    toPreLaTeXM :: SectionFormatted (Parsed a) -> State GlobalState PreLaTeX
toPreLaTeXM
        (SectionFormatted SectionFormat
fmt Parsed a
s) =
            case Parsed a
s of
                Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
                Right a
content -> do
                    ((FormatState -> Identity FormatState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Identity FormatState)
 -> GlobalState -> Identity GlobalState)
-> ((SectionFormat -> Identity SectionFormat)
    -> FormatState -> Identity FormatState)
-> (SectionFormat -> Identity SectionFormat)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SectionFormat -> Identity SectionFormat)
-> FormatState -> Identity FormatState
Lens' FormatState SectionFormat
GS.sectionFormat) ((SectionFormat -> Identity SectionFormat)
 -> GlobalState -> Identity GlobalState)
-> SectionFormat -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= SectionFormat
fmt
                    a -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM a
content

instance ToPreLaTeXM Section where
    toPreLaTeXM :: Section -> State GlobalState PreLaTeX
toPreLaTeXM = Maybe Label -> Section -> State GlobalState PreLaTeX
forall a.
Labelable a =>
Maybe Label -> a -> State GlobalState PreLaTeX
attachLabel Maybe Label
forall a. Maybe a
Nothing

-- | one of the trickier instances. since every part of the SectionBody needs the provided
--   context of the section it would be difficult to write a seperate SectionBody instance.
--   hence this instance got bloated a little
instance Labelable Section where
    attachLabel :: Maybe Label -> Section -> State GlobalState PreLaTeX
attachLabel Maybe Label
mLabel (Section Parsed Heading
h SectionBody
nodes) =
        case Parsed Heading
h of
            -- \^ if the parsing of the heading failed, we throw an error, otherwise proceed
            Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
            Right (Heading InnerHeadingFormat
fmt [HeadingTextTree]
tt) -> do
                (SectionFormat IdentifierFormat
ident (TocKeyFormat KeyFormat
keyident) Bool
isInserted) <-
                    Getting SectionFormat GlobalState SectionFormat
-> StateT GlobalState Identity SectionFormat
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FormatState -> Const SectionFormat FormatState)
-> GlobalState -> Const SectionFormat GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Const SectionFormat FormatState)
 -> GlobalState -> Const SectionFormat GlobalState)
-> ((SectionFormat -> Const SectionFormat SectionFormat)
    -> FormatState -> Const SectionFormat FormatState)
-> Getting SectionFormat GlobalState SectionFormat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SectionFormat -> Const SectionFormat SectionFormat)
-> FormatState -> Const SectionFormat FormatState
Lens' FormatState SectionFormat
GS.sectionFormat)
                PreLaTeX
tt' <- [HeadingTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [HeadingTextTree]
tt
                -- \| helper functions to reduce redundance
                let headingText :: PreLaTeX
headingText = PreLaTeX
tt'
                    buildHeading :: Int -> Int -> State GlobalState PreLaTeX
buildHeading Int
n Int
ni = do
                        InnerHeadingFormat
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
forall (b :: Bool).
HeadingFormat b
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
createHeading InnerHeadingFormat
fmt PreLaTeX
headingText (Text -> PreLaTeX
IText (Text -> PreLaTeX) -> Text -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ IdentifierFormat -> Int -> Int -> Text
getIdentifier IdentifierFormat
ident Int
n Int
ni)
                    setLabel :: a -> StateT GlobalState Identity ()
setLabel a
n = Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel Maybe Label
mLabel (String -> Text
T.pack (a -> String
forall a. Show a => a -> String
show a
n))
                    filterFN :: [TextTree lbrk fnref style enum special]
-> [TextTree lbrk fnref style enum special]
filterFN [TextTree lbrk fnref style enum special]
xs = [TextTree lbrk fnref style enum special
y | TextTree lbrk fnref style enum special
y <- [TextTree lbrk fnref style enum special]
xs, Bool -> Bool
not (TextTree lbrk fnref style enum special -> Bool
forall {lbrk} {fnref} {style} {enum} {special}.
TextTree lbrk fnref style enum special -> Bool
isFN TextTree lbrk fnref style enum special
y)]
                      where
                        -- \^ when the heading is added to the toc, we want to get rid of footnotes. (luckily Styled is not allowed in HeadingTextTree)

                        isFN :: TextTree lbrk fnref style enum special -> Bool
isFN (FootnoteRef fnref
_) = Bool
True
                        isFN TextTree lbrk fnref style enum special
_ = Bool
False
                PreLaTeX
tocEntry <- [HeadingTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM ([HeadingTextTree] -> State GlobalState PreLaTeX)
-> [HeadingTextTree] -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ [HeadingTextTree] -> [HeadingTextTree]
forall {lbrk} {fnref} {style} {enum} {special}.
[TextTree lbrk fnref style enum special]
-> [TextTree lbrk fnref style enum special]
filterFN [HeadingTextTree]
tt
                case SectionBody
nodes of
                    LeafSectionBody [Node Paragraph]
paragraphs -> do
                        Int
n <-
                            (if Bool
isInserted then Getting Int GlobalState Int -> State GlobalState Int
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use (Getting Int GlobalState Int -> State GlobalState Int)
-> Getting Int GlobalState Int -> State GlobalState Int
forall a b. (a -> b) -> a -> b
$ (CounterState -> Const Int CounterState)
-> GlobalState -> Const Int GlobalState
Lens' GlobalState CounterState
GS.counterState ((CounterState -> Const Int CounterState)
 -> GlobalState -> Const Int GlobalState)
-> ((Int -> Const Int Int)
    -> CounterState -> Const Int CounterState)
-> Getting Int GlobalState Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Const Int Int) -> CounterState -> Const Int CounterState
Lens' CounterState Int
GS.sectionCTR else State GlobalState Int
GS.nextSection)
                        Int
ni <- (if Bool
isInserted then State GlobalState Int
GS.nextInsertedSection else Int -> State GlobalState Int
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0)
                        Int -> StateT GlobalState Identity ()
forall {a}. Show a => a -> StateT GlobalState Identity ()
setLabel Int
n
                        (FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((Bool -> Identity Bool) -> FlagState -> Identity FlagState)
-> (Bool -> Identity Bool)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> FlagState -> Identity FlagState
Lens' FlagState Bool
GS.onlyOneParagraph ((Bool -> Identity Bool) -> GlobalState -> Identity GlobalState)
-> Bool -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= ([Node Paragraph] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Node Paragraph]
paragraphs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1)
                        PreLaTeX
tocAnchor <- Int
-> Int
-> KeyFormat
-> IdentifierFormat
-> PreLaTeX
-> State GlobalState PreLaTeX
GS.addTOCEntry Int
n Int
ni KeyFormat
keyident IdentifierFormat
ident PreLaTeX
tocEntry
                        PreLaTeX
headingDoc <- Int -> Int -> State GlobalState PreLaTeX
buildHeading Int
n Int
ni
                        PreLaTeX
content' <- [Node Paragraph] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Node Paragraph]
paragraphs
                        let refAnchor :: PreLaTeX
refAnchor = PreLaTeX -> (Label -> PreLaTeX) -> Maybe Label -> PreLaTeX
forall b a. b -> (a -> b) -> Maybe a -> b
maybe PreLaTeX
headingDoc (Label -> PreLaTeX -> PreLaTeX
`hypertarget` PreLaTeX
headingDoc) Maybe Label
mLabel
                        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
tocAnchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
refAnchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
content'
                    InnerSectionBody [Flagged' FormattedSection]
subsections -> do
                        Int
n <- State GlobalState Int
GS.nextSupersection
                        Int -> StateT GlobalState Identity ()
forall {a}. Show a => a -> StateT GlobalState Identity ()
setLabel Int
n
                        (CounterState -> Identity CounterState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState CounterState
GS.counterState ((CounterState -> Identity CounterState)
 -> GlobalState -> Identity GlobalState)
-> ((Int -> Identity Int) -> CounterState -> Identity CounterState)
-> (Int -> Identity Int)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> CounterState -> Identity CounterState
Lens' CounterState Int
GS.supersectionCTR ((Int -> Identity Int) -> GlobalState -> Identity GlobalState)
-> Int -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Int
0
                        PreLaTeX
tocAnchor <- Int
-> Int
-> KeyFormat
-> IdentifierFormat
-> PreLaTeX
-> State GlobalState PreLaTeX
GS.addTOCEntry Int
n Int
0 KeyFormat
keyident IdentifierFormat
ident PreLaTeX
tocEntry
                        PreLaTeX
headingDoc <- Int -> Int -> State GlobalState PreLaTeX
buildHeading Int
n Int
0
                        PreLaTeX
content' <- [Flagged' FormattedSection] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Flagged' FormattedSection]
subsections
                        (CounterState -> Identity CounterState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState CounterState
GS.counterState ((CounterState -> Identity CounterState)
 -> GlobalState -> Identity GlobalState)
-> ((Int -> Identity Int) -> CounterState -> Identity CounterState)
-> (Int -> Identity Int)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> CounterState -> Identity CounterState
Lens' CounterState Int
GS.supersectionCTR ((Int -> Identity Int) -> GlobalState -> Identity GlobalState)
-> Int -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Int
n
                        let refAnchor :: PreLaTeX
refAnchor =
                                PreLaTeX -> (Label -> PreLaTeX) -> Maybe Label -> PreLaTeX
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (PreLaTeX
headingDoc PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
linebreak) (Label -> PreLaTeX -> PreLaTeX
`hypertarget` (PreLaTeX
headingDoc PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
linebreak)) Maybe Label
mLabel
                        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
tocAnchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
refAnchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
content'
                    SimpleLeafSectionBody [SimpleBlock]
simpleblocks -> do
                        [SimpleBlock] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [SimpleBlock]
simpleblocks

-------------------------------- Block ----------------------------------

instance ToPreLaTeXM SimpleBlock where
    toPreLaTeXM :: SimpleBlock -> State GlobalState PreLaTeX
toPreLaTeXM (SimpleParagraphBlock SimpleParagraph
b) = SimpleParagraph -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM SimpleParagraph
b
    toPreLaTeXM (TableBlock Table
b) = Table -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM Table
b -- TODO table

-------------------------------- Table ----------------------------------

instance ToPreLaTeXM Table where
    toPreLaTeXM :: Table -> State GlobalState PreLaTeX
toPreLaTeXM (Table ColumnProps
mProps [Row]
rows) = do
        let Row [Cell]
c = [Row] -> Row
forall a. HasCallStack => [a] -> a
head [Row]
rows
            n :: Int
n = [Cell] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Cell]
c
            props :: [Int]
props = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ case ColumnProps
mProps of
                ColumnProps
Nothing -> Int -> [Int]
forall a. a -> [a]
repeat Int
1
                Just [Int]
xs -> [Int]
xs [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
1
            total :: Int
total = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
props
            applyMargin :: p -> String
applyMargin p
x =
                let margin :: Double
margin = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max ((p -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral p
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
total) Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
0.02) Double
0.01
                    marginS :: String
marginS = Maybe Int -> Double -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
showFFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2) Double
margin String
""
                 in String
"|p{" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
marginS String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\\textwidth}"
            option :: Text
option = String -> Text
T.pack ((Int -> String) -> [Int] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Int -> String
forall {p}. Integral p => p -> String
applyMargin [Int]
props) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"|"
        [PreLaTeX]
rows' <- (Row -> State GlobalState PreLaTeX)
-> [Row] -> StateT GlobalState Identity [PreLaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Row -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Row]
rows
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ Text -> PreLaTeX -> PreLaTeX
tabular Text
option ([PreLaTeX] -> PreLaTeX
ISequence [PreLaTeX]
rows' PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
hline)

instance ToPreLaTeXM Row where
    toPreLaTeXM :: Row -> State GlobalState PreLaTeX
toPreLaTeXM (Row [Cell]
cells) = do
        [PreLaTeX]
cells' <- (Cell -> State GlobalState PreLaTeX)
-> [Cell] -> StateT GlobalState Identity [PreLaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Cell -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM ((Cell -> Bool) -> [Cell] -> [Cell]
forall a. (a -> Bool) -> [a] -> [a]
filter (Cell -> Cell -> Bool
forall a. Eq a => a -> a -> Bool
/= Cell
HSpannedCell) [Cell]
cells)
        let rowContent :: PreLaTeX
rowContent = [PreLaTeX] -> PreLaTeX
forall a. Monoid a => [a] -> a
mconcat ([PreLaTeX] -> PreLaTeX) -> [PreLaTeX] -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX -> [PreLaTeX] -> [PreLaTeX]
forall {a}. a -> [a] -> [a]
intersperse (Text -> PreLaTeX
IRaw Text
" & ") [PreLaTeX]
cells'
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
allcLines PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
rowContent PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
linebreak
      where
        intersperse :: a -> [a] -> [a]
intersperse a
_ [] = []
        intersperse a
sep (a
x : [a]
xs) = a
x a -> [a] -> [a]
forall {a}. a -> [a] -> [a]
: a -> [a] -> [a]
forall {a}. a -> [a] -> [a]
prependToAll a
sep [a]
xs

        prependToAll :: t -> [t] -> [t]
prependToAll t
_ [] = []
        prependToAll t
sep (t
y : [t]
ys) = t
sep t -> [t] -> [t]
forall {a}. a -> [a] -> [a]
: t
y t -> [t] -> [t]
forall {a}. a -> [a] -> [a]
: t -> [t] -> [t]
prependToAll t
sep [t]
ys

        allcLines :: PreLaTeX
        allcLines :: PreLaTeX
allcLines =
            let (PreLaTeX
res, Int
_, Int
_) = PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
go PreLaTeX
forall a. Monoid a => a
mempty Int
1 Int
1 [Cell]
cells
             in PreLaTeX
res
          where
            go :: PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
            go :: PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
go PreLaTeX
latex Int
_ Int
_ [] = (PreLaTeX
latex, Int
0, Int
0)
            go PreLaTeX
latex Int
i Int
j (VSpannedCell Int
w : [Cell]
cs) = PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
go PreLaTeX
latex (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
w) [Cell]
cs
            go PreLaTeX
latex Int
i Int
j (Cell
_ : [Cell]
cs) =
                if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j
                    then PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
go (PreLaTeX
latex PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> Int -> Int -> PreLaTeX
cline Int
i Int
i) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [Cell]
cs
                    else PreLaTeX -> Int -> Int -> [Cell] -> (PreLaTeX, Int, Int)
go PreLaTeX
latex (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
j [Cell]
cs

instance ToPreLaTeXM Cell where
    toPreLaTeXM :: Cell -> State GlobalState PreLaTeX
toPreLaTeXM (Cell (CellFormat BGColor
bg (Typography TextAlignment
_ FontSize
fontsize [FontStyle]
_)) [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
content Int
w Int
h) = do
        PreLaTeX
content' <-
            (PreLaTeX
 -> [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
 -> State GlobalState PreLaTeX)
-> PreLaTeX
-> [[TextTree HardLineBreak FootnoteReference FontStyle Void Void]]
-> State GlobalState PreLaTeX
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM
                ( \PreLaTeX
acc [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
x ->
                    [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
-> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
x
                        State GlobalState PreLaTeX
-> (PreLaTeX -> State GlobalState PreLaTeX)
-> State GlobalState PreLaTeX
forall a b.
StateT GlobalState Identity a
-> (a -> StateT GlobalState Identity b)
-> StateT GlobalState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PreLaTeX
r ->
                            if (TextTree HardLineBreak FootnoteReference FontStyle Void Void
 -> Bool)
-> [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
-> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TextTree HardLineBreak FootnoteReference FontStyle Void Void
-> Bool
forall {lbrk} {fnref} {style} {enum} {special}.
TextTree lbrk fnref style enum special -> Bool
findLineBreak [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
x
                                then PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX
acc PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
r)
                                else PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
acc PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> FontSize -> PreLaTeX -> PreLaTeX
forall a. Stylable a => a -> PreLaTeX -> PreLaTeX
applyTextStyle FontSize
fontsize PreLaTeX
r
                )
                PreLaTeX
forall a. Monoid a => a
mempty
                ([TextTree HardLineBreak FootnoteReference FontStyle Void Void]
-> [[TextTree HardLineBreak FootnoteReference FontStyle Void Void]]
forall lbrk fnref style enum special.
[TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
surfaceLineBreaks [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
content) -- TODO
        let lineBreakCase :: PreLaTeX -> PreLaTeX
lineBreakCase =
                if (TextTree HardLineBreak FootnoteReference FontStyle Void Void
 -> Bool)
-> [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
-> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TextTree HardLineBreak FootnoteReference FontStyle Void Void
-> Bool
forall {lbrk} {fnref} {style} {enum} {special}.
TextTree lbrk fnref style enum special -> Bool
findLineBreak [TextTree HardLineBreak FootnoteReference FontStyle Void Void]
content
                    then PreLaTeX -> PreLaTeX
makecell
                    else PreLaTeX -> PreLaTeX
forall a. a -> a
id
            stylizedContent :: PreLaTeX
stylizedContent =
                PreLaTeX -> PreLaTeX
lineBreakCase PreLaTeX
content' PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> BGColor -> PreLaTeX
getColor BGColor
bg
        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
            if Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Bool -> Bool -> Bool
&& Int
h Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
                then Int -> Text -> PreLaTeX -> PreLaTeX
multicolumn Int
w Text
"|l|" (PreLaTeX -> PreLaTeX) -> PreLaTeX -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ Int -> PreLaTeX -> PreLaTeX
multirow Int
h PreLaTeX
stylizedContent
                else
                    if Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
                        then Int -> Text -> PreLaTeX -> PreLaTeX
multicolumn Int
w Text
"|l|" PreLaTeX
stylizedContent
                        else
                            if Int
h Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
                                then Int -> PreLaTeX -> PreLaTeX
multirow Int
h PreLaTeX
stylizedContent
                                else PreLaTeX
stylizedContent
      where
        getColor :: BGColor -> PreLaTeX
getColor BGColor
White = PreLaTeX
forall a. Monoid a => a
mempty
        getColor BGColor
Gray = Text -> PreLaTeX
cellcolor Text
"gray!30"

        findLineBreak :: TextTree lbrk fnref style enum special -> Bool
findLineBreak (LineBreak lbrk
_) = Bool
True
        findLineBreak (Styled style
_ [TextTree lbrk fnref style enum special]
tt) = (TextTree lbrk fnref style enum special -> Bool)
-> [TextTree lbrk fnref style enum special] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TextTree lbrk fnref style enum special -> Bool
findLineBreak [TextTree lbrk fnref style enum special]
tt
        findLineBreak TextTree lbrk fnref style enum special
_ = Bool
False

        surfaceLineBreaks
            :: [TextTree lbrk fnref style enum special]
            -> [[TextTree lbrk fnref style enum special]]
        surfaceLineBreaks :: forall lbrk fnref style enum special.
[TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
surfaceLineBreaks =
            (TextTree lbrk fnref style enum special
 -> [[TextTree lbrk fnref style enum special]]
 -> [[TextTree lbrk fnref style enum special]])
-> [[TextTree lbrk fnref style enum special]]
-> [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
                ( \TextTree lbrk fnref style enum special
tt [[TextTree lbrk fnref style enum special]]
acc ->
                    case TextTree lbrk fnref style enum special
tt of
                        LineBreak lbrk
lb -> [lbrk -> TextTree lbrk fnref style enum special
forall lbrk fnref style enum special.
lbrk -> TextTree lbrk fnref style enum special
LineBreak lbrk
lb] [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall {a}. a -> [a] -> [a]
: [[TextTree lbrk fnref style enum special]]
acc
                        Styled style
style [TextTree lbrk fnref style enum special]
innerTTs ->
                            let innerSplits :: [[TextTree lbrk fnref style enum special]]
innerSplits = [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
forall lbrk fnref style enum special.
[TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
surfaceLineBreaks [TextTree lbrk fnref style enum special]
innerTTs
                                wrappedSplits :: [[TextTree lbrk fnref style enum special]]
wrappedSplits =
                                    ([TextTree lbrk fnref style enum special]
 -> [TextTree lbrk fnref style enum special])
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall a b. (a -> b) -> [a] -> [b]
map (\[TextTree lbrk fnref style enum special]
zs -> if (TextTree lbrk fnref style enum special -> Bool)
-> [TextTree lbrk fnref style enum special] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any TextTree lbrk fnref style enum special -> Bool
forall {lbrk} {fnref} {style} {enum} {special}.
TextTree lbrk fnref style enum special -> Bool
findLineBreak [TextTree lbrk fnref style enum special]
zs then [TextTree lbrk fnref style enum special]
zs else [style
-> [TextTree lbrk fnref style enum special]
-> TextTree lbrk fnref style enum special
forall lbrk fnref style enum special.
style
-> [TextTree lbrk fnref style enum special]
-> TextTree lbrk fnref style enum special
Styled style
style [TextTree lbrk fnref style enum special]
zs]) [[TextTree lbrk fnref style enum special]]
innerSplits
                             in [[TextTree lbrk fnref style enum special]]
wrappedSplits [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall a. [a] -> [a] -> [a]
++ [[TextTree lbrk fnref style enum special]]
acc
                        TextTree lbrk fnref style enum special
other -> case [[TextTree lbrk fnref style enum special]]
acc of
                            [] -> [[TextTree lbrk fnref style enum special
other]]
                            ([LineBreak lbrk
lb] : [[TextTree lbrk fnref style enum special]]
xs) -> [TextTree lbrk fnref style enum special
other] [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall {a}. a -> [a] -> [a]
: [lbrk -> TextTree lbrk fnref style enum special
forall lbrk fnref style enum special.
lbrk -> TextTree lbrk fnref style enum special
LineBreak lbrk
lb] [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall {a}. a -> [a] -> [a]
: [[TextTree lbrk fnref style enum special]]
xs
                            ([TextTree lbrk fnref style enum special]
x : [[TextTree lbrk fnref style enum special]]
xs) -> (TextTree lbrk fnref style enum special
other TextTree lbrk fnref style enum special
-> [TextTree lbrk fnref style enum special]
-> [TextTree lbrk fnref style enum special]
forall {a}. a -> [a] -> [a]
: [TextTree lbrk fnref style enum special]
x) [TextTree lbrk fnref style enum special]
-> [[TextTree lbrk fnref style enum special]]
-> [[TextTree lbrk fnref style enum special]]
forall {a}. a -> [a] -> [a]
: [[TextTree lbrk fnref style enum special]]
xs
                )
                []
    toPreLaTeXM (VSpannedCell Int
w) = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ if Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 then Int -> Text -> PreLaTeX -> PreLaTeX
multicolumn Int
w Text
"|l|" PreLaTeX
forall a. Monoid a => a
mempty else PreLaTeX
forall a. Monoid a => a
mempty
    toPreLaTeXM Cell
HSpannedCell = PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty

-------------------------------- Document -----------------------------------

instance ToPreLaTeXM Document where
    toPreLaTeXM :: Document -> State GlobalState PreLaTeX
toPreLaTeXM = Maybe Label -> Document -> State GlobalState PreLaTeX
forall a.
Labelable a =>
Maybe Label -> a -> State GlobalState PreLaTeX
attachLabel Maybe Label
forall a. Maybe a
Nothing

instance Labelable Document where
    attachLabel :: Maybe Label -> Document -> State GlobalState PreLaTeX
attachLabel
        Maybe Label
mLabel
        ( Document
                (DocumentFormat Maybe TocFormat
mTOC)
                Parsed DocumentHeading
dh
                (DocumentBody Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
intro (Flagged Bool
b (NavTocHeaded NavTocHeading
_ Parsed SectionBody
content)) Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
outro)
                Map Label Footnote
footnotemap
            ) =
            case Parsed DocumentHeading
dh of
                Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
                Right (DocumentHeading [HeadingTextTree]
tt) -> do
                    -- \| build the heading text from the given HeadingFormat
                    --                    passed by the state and depending on the position we are in
                    PreLaTeX
tt' <- [HeadingTextTree] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [HeadingTextTree]
tt
                    PreLaTeX
headingText <- PreLaTeX -> State GlobalState PreLaTeX
buildHeading PreLaTeX
tt'

                    -- \| prepare the state for this document
                    (Map Label Footnote -> Identity (Map Label Footnote))
-> GlobalState -> Identity GlobalState
Lens' GlobalState (Map Label Footnote)
GS.labelToFootNote ((Map Label Footnote -> Identity (Map Label Footnote))
 -> GlobalState -> Identity GlobalState)
-> Map Label Footnote -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Map Label Footnote
footnotemap
                    StateT GlobalState Identity ()
GS.resetCountersSoft
                    (DList PreLaTeX -> Identity (DList PreLaTeX))
-> GlobalState -> Identity GlobalState
Lens' GlobalState (DList PreLaTeX)
GS.toc ((DList PreLaTeX -> Identity (DList PreLaTeX))
 -> GlobalState -> Identity GlobalState)
-> DList PreLaTeX -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= DList PreLaTeX
forall a. Monoid a => a
mempty

                    -- \| recursively receive the needed parts of the document
                    PreLaTeX
intro' <- Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
-> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
intro
                    PreLaTeX
content' <- case Parsed SectionBody
content of
                        Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
                        Right SectionBody
section -> case SectionBody
section of
                            (LeafSectionBody [Node Paragraph]
paragraphs) -> do
                                Flagged Bool [Node Paragraph] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM (Bool -> [Node Paragraph] -> Flagged Bool [Node Paragraph]
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
b [Node Paragraph]
paragraphs)
                            (SimpleLeafSectionBody [SimpleBlock]
simpleblocks) -> do
                                Flagged Bool [SimpleBlock] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM (Bool -> [SimpleBlock] -> Flagged Bool [SimpleBlock]
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
b [SimpleBlock]
simpleblocks)
                            (InnerSectionBody [Flagged' FormattedSection]
sections) -> do
                                Flagged Bool [Flagged' FormattedSection]
-> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM (Bool
-> [Flagged' FormattedSection]
-> Flagged Bool [Flagged' FormattedSection]
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
b [Flagged' FormattedSection]
sections)
                    PreLaTeX
outro' <- Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
-> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM Maybe (Flagged' (NavTocHeaded (Parsed DocumentIntro)))
outro

                    -- \| if we need a toc then we assemble it.
                    PreLaTeX
toc' <- case Maybe TocFormat
mTOC of
                        Maybe TocFormat
Nothing -> PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty
                        Just (TocFormat (TocHeading Text
tocHeading)) -> Text -> State GlobalState PreLaTeX
buildTOC Text
tocHeading

                    Bool
isFlagged <- Getting Bool GlobalState Bool -> StateT GlobalState Identity Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const Bool FlagState)
-> GlobalState -> Const Bool GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const Bool FlagState)
 -> GlobalState -> Const Bool GlobalState)
-> ((Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState)
-> Getting Bool GlobalState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Bool Bool) -> FlagState -> Const Bool FlagState
Lens' FlagState Bool
GS.flaggedParent)

                    PreLaTeX
preamble <- if Bool
isFlagged then PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
headingText PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
toc' else PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty

                    -- \| assemble the final document
                    PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
                        PreLaTeX
resetfootnote
                            -- \^ since footnotes are document scoped, we need to reset them in latex as well
                            PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
preamble
                            PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
intro'
                            PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
content'
                            PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
outro'
          where
            -- \| helper function to create the heading depending on context
            buildHeading :: PreLaTeX -> State GS.GlobalState PreLaTeX
            buildHeading :: PreLaTeX -> State GlobalState PreLaTeX
buildHeading PreLaTeX
tt' = do
                DocType
docType <- Getting DocType GlobalState DocType
-> StateT GlobalState Identity DocType
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const DocType FlagState)
-> GlobalState -> Const DocType GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const DocType FlagState)
 -> GlobalState -> Const DocType GlobalState)
-> ((DocType -> Const DocType DocType)
    -> FlagState -> Const DocType FlagState)
-> Getting DocType GlobalState DocType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DocType -> Const DocType DocType)
-> FlagState -> Const DocType FlagState
Lens' FlagState DocType
GS.docType)
                case DocType
docType of
                    DocType
GS.Appendix -> do
                        Int
n <- State GlobalState Int
GS.nextAppendix
                        AppendixElementFormat IdentifierFormat
ident (TocKeyFormat KeyFormat
key) InnerHeadingFormat
fmt <-
                            Getting AppendixElementFormat GlobalState AppendixElementFormat
-> StateT GlobalState Identity AppendixElementFormat
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FormatState -> Const AppendixElementFormat FormatState)
-> GlobalState -> Const AppendixElementFormat GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Const AppendixElementFormat FormatState)
 -> GlobalState -> Const AppendixElementFormat GlobalState)
-> ((AppendixElementFormat
     -> Const AppendixElementFormat AppendixElementFormat)
    -> FormatState -> Const AppendixElementFormat FormatState)
-> Getting AppendixElementFormat GlobalState AppendixElementFormat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AppendixElementFormat
 -> Const AppendixElementFormat AppendixElementFormat)
-> FormatState -> Const AppendixElementFormat FormatState
Lens' FormatState AppendixElementFormat
GS.appendixFormat)
                        let iText :: Text
iText = IdentifierFormat -> Int -> Int -> Text
getIdentifier IdentifierFormat
ident Int
n Int
0
                        Maybe Label -> Text -> StateT GlobalState Identity ()
GS.insertRefLabel Maybe Label
mLabel Text
iText
                        PreLaTeX
tocAnchor <- Int
-> Int
-> KeyFormat
-> IdentifierFormat
-> PreLaTeX
-> State GlobalState PreLaTeX
GS.addTOCEntry Int
n Int
0 KeyFormat
key IdentifierFormat
ident PreLaTeX
tt'
                        -- \^ inserts a toc entry and returns a hypertarget, so that it is possible to jump here from the toc
                        Int
-> KeyFormat
-> IdentifierFormat
-> PreLaTeX
-> StateT GlobalState Identity ()
GS.addAppendixHeaderEntry Int
n KeyFormat
key IdentifierFormat
ident PreLaTeX
tt'
                        PreLaTeX
heading <- InnerHeadingFormat
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
forall (b :: Bool).
HeadingFormat b
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
createHeading InnerHeadingFormat
fmt PreLaTeX
tt' (Text -> PreLaTeX
IText Text
iText)
                        PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
tocAnchor PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
heading
                    DocType
GS.Main -> do
                        MainHeadingFormat
fmt <- Getting MainHeadingFormat GlobalState MainHeadingFormat
-> StateT GlobalState Identity MainHeadingFormat
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FormatState -> Const MainHeadingFormat FormatState)
-> GlobalState -> Const MainHeadingFormat GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Const MainHeadingFormat FormatState)
 -> GlobalState -> Const MainHeadingFormat GlobalState)
-> ((MainHeadingFormat
     -> Const MainHeadingFormat MainHeadingFormat)
    -> FormatState -> Const MainHeadingFormat FormatState)
-> Getting MainHeadingFormat GlobalState MainHeadingFormat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MainHeadingFormat -> Const MainHeadingFormat MainHeadingFormat)
-> FormatState -> Const MainHeadingFormat FormatState
Lens' FormatState MainHeadingFormat
GS.docHeadingFormat)
                        MainHeadingFormat
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
forall (b :: Bool).
HeadingFormat b
-> PreLaTeX -> PreLaTeX -> State GlobalState PreLaTeX
createHeading MainHeadingFormat
fmt PreLaTeX
tt' (Text -> PreLaTeX
IText Text
" ")

            -- \| helper function to render the toc
            buildTOC :: Text -> State GS.GlobalState PreLaTeX
            buildTOC :: Text -> State GlobalState PreLaTeX
buildTOC Text
tocHeading = do
                DocType
t <- Getting DocType GlobalState DocType
-> StateT GlobalState Identity DocType
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((FlagState -> Const DocType FlagState)
-> GlobalState -> Const DocType GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Const DocType FlagState)
 -> GlobalState -> Const DocType GlobalState)
-> ((DocType -> Const DocType DocType)
    -> FlagState -> Const DocType FlagState)
-> Getting DocType GlobalState DocType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DocType -> Const DocType DocType)
-> FlagState -> Const DocType FlagState
Lens' FlagState DocType
GS.docType)
                DList PreLaTeX
toc' <- Getting (DList PreLaTeX) GlobalState (DList PreLaTeX)
-> StateT GlobalState Identity (DList PreLaTeX)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting (DList PreLaTeX) GlobalState (DList PreLaTeX)
Lens' GlobalState (DList PreLaTeX)
GS.toc
                DList PreLaTeX
appendixHeaders' <- Getting (DList PreLaTeX) GlobalState (DList PreLaTeX)
-> StateT GlobalState Identity (DList PreLaTeX)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting (DList PreLaTeX) GlobalState (DList PreLaTeX)
Lens' GlobalState (DList PreLaTeX)
GS.appendixHeaders
                PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$
                    PreLaTeX -> PreLaTeX
bold (Text -> PreLaTeX
IText Text
tocHeading) PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
linebreak PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> case DocType
t of
                        DocType
GS.Appendix ->
                            [PreLaTeX] -> PreLaTeX
ISequence ([PreLaTeX] -> PreLaTeX) -> [PreLaTeX] -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ DList PreLaTeX -> [PreLaTeX]
forall a. DList a -> [a]
DList.toList DList PreLaTeX
toc'
                        DocType
GS.Main ->
                            [PreLaTeX] -> PreLaTeX
ISequence ([PreLaTeX] -> PreLaTeX) -> [PreLaTeX] -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ DList PreLaTeX -> [PreLaTeX]
forall a. DList a -> [a]
DList.toList (DList PreLaTeX
toc' DList PreLaTeX -> DList PreLaTeX -> DList PreLaTeX
forall a. Semigroup a => a -> a -> a
<> DList PreLaTeX
appendixHeaders')

-------------------------------- AppendixSection -----------------------------------

instance ToPreLaTeXM AppendixSection where
    toPreLaTeXM :: AppendixSection -> State GlobalState PreLaTeX
toPreLaTeXM
        ( AppendixSection
                ( AppendixSectionFormat
                        (AppendixSectionTitle Text
t)
                        AppendixElementFormat
elementFmt
                    )
                [Flagged' (Node Document)]
nodes
            ) = do
            if [Flagged' (Node Document)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Flagged' (Node Document)]
nodes
                -- \^ mainly to prevent the title to appear in the main toc, if there are no appendices
                then PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreLaTeX
forall a. Monoid a => a
mempty
                else do
                    (CounterState -> Identity CounterState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState CounterState
GS.counterState ((CounterState -> Identity CounterState)
 -> GlobalState -> Identity GlobalState)
-> ((Int -> Identity Int) -> CounterState -> Identity CounterState)
-> (Int -> Identity Int)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> CounterState -> Identity CounterState
Lens' CounterState Int
GS.appendixCTR ((Int -> Identity Int) -> GlobalState -> Identity GlobalState)
-> Int -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Int
0
                    (FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((DocType -> Identity DocType)
    -> FlagState -> Identity FlagState)
-> (DocType -> Identity DocType)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DocType -> Identity DocType) -> FlagState -> Identity FlagState
Lens' FlagState DocType
GS.docType ((DocType -> Identity DocType)
 -> GlobalState -> Identity GlobalState)
-> DocType -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= DocType
GS.Appendix
                    (FormatState -> Identity FormatState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Identity FormatState)
 -> GlobalState -> Identity GlobalState)
-> ((AppendixElementFormat -> Identity AppendixElementFormat)
    -> FormatState -> Identity FormatState)
-> (AppendixElementFormat -> Identity AppendixElementFormat)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AppendixElementFormat -> Identity AppendixElementFormat)
-> FormatState -> Identity FormatState
Lens' FormatState AppendixElementFormat
GS.appendixFormat ((AppendixElementFormat -> Identity AppendixElementFormat)
 -> GlobalState -> Identity GlobalState)
-> AppendixElementFormat -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= AppendixElementFormat
elementFmt
                    (DList PreLaTeX -> Identity (DList PreLaTeX))
-> GlobalState -> Identity GlobalState
Lens' GlobalState (DList PreLaTeX)
GS.appendixHeaders ((DList PreLaTeX -> Identity (DList PreLaTeX))
 -> GlobalState -> Identity GlobalState)
-> (DList PreLaTeX -> DList PreLaTeX)
-> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= (DList PreLaTeX -> DList PreLaTeX -> DList PreLaTeX
forall a. Semigroup a => a -> a -> a
<> [PreLaTeX] -> DList PreLaTeX
forall a. [a] -> DList a
DList.fromList [Text -> PreLaTeX
IText Text
t, PreLaTeX
linebreak])
                    [PreLaTeX]
nodes' <- (Flagged' (Node Document) -> State GlobalState PreLaTeX)
-> [Flagged' (Node Document)]
-> StateT GlobalState Identity [PreLaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Flagged' (Node Document) -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Flagged' (Node Document)]
nodes
                    PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ [PreLaTeX] -> PreLaTeX
ISequence ([PreLaTeX] -> PreLaTeX) -> [PreLaTeX] -> PreLaTeX
forall a b. (a -> b) -> a -> b
$ (PreLaTeX -> PreLaTeX) -> [PreLaTeX] -> [PreLaTeX]
forall a b. (a -> b) -> [a] -> [b]
map (PreLaTeX
newpage PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<>) [PreLaTeX]
nodes'

-------------------------------- DocumentContainer -----------------------------------

instance ToPreLaTeXM DocumentContainer where
    toPreLaTeXM :: DocumentContainer -> State GlobalState PreLaTeX
toPreLaTeXM
        ( DocumentContainer
                ( DocumentContainerFormat
                        HeaderFooterFormat
headerFmt
                        HeaderFooterFormat
footerFmt
                        (MainDocumentFormat Fallback NavTocHeading
_ MainHeadingFormat
headingFmt)
                    )
                (NavTocHeaded NavTocHeading
_ Parsed DocumentContainerHeader
dch)
                Flagged' Document
doc
                [Flagged' AppendixSection]
appendices
            ) = case Parsed DocumentContainerHeader
dch of
            Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
            Right (DocumentContainerHeader Text
pdfTitle Text
superTitle Text
title Text
date) -> do
                -- \| prepare the state
                (PreLaTeX -> Identity PreLaTeX)
-> GlobalState -> Identity GlobalState
Lens' GlobalState PreLaTeX
GS.preDocument ((PreLaTeX -> Identity PreLaTeX)
 -> GlobalState -> Identity GlobalState)
-> (PreLaTeX -> PreLaTeX) -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= (PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> Text -> PreLaTeX
setpdftitle Text
pdfTitle)
                HeaderFooterFormat
-> HeaderFooterFormat
-> Text
-> Text
-> Text
-> StateT GlobalState Identity ()
GS.addHeaderFooter HeaderFooterFormat
headerFmt HeaderFooterFormat
footerFmt Text
superTitle Text
title Text
date
                (FormatState -> Identity FormatState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FormatState
GS.formatState ((FormatState -> Identity FormatState)
 -> GlobalState -> Identity GlobalState)
-> ((MainHeadingFormat -> Identity MainHeadingFormat)
    -> FormatState -> Identity FormatState)
-> (MainHeadingFormat -> Identity MainHeadingFormat)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MainHeadingFormat -> Identity MainHeadingFormat)
-> FormatState -> Identity FormatState
Lens' FormatState MainHeadingFormat
GS.docHeadingFormat ((MainHeadingFormat -> Identity MainHeadingFormat)
 -> GlobalState -> Identity GlobalState)
-> MainHeadingFormat -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= MainHeadingFormat
headingFmt
                StateT GlobalState Identity ()
GS.resetCountersHard

                PreLaTeX
appendices' <- [Flagged' AppendixSection] -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM [Flagged' AppendixSection]
appendices
                -- \^ appendices before main doc to gather the headings for the toc of main doc

                (FlagState -> Identity FlagState)
-> GlobalState -> Identity GlobalState
Lens' GlobalState FlagState
GS.flagState ((FlagState -> Identity FlagState)
 -> GlobalState -> Identity GlobalState)
-> ((DocType -> Identity DocType)
    -> FlagState -> Identity FlagState)
-> (DocType -> Identity DocType)
-> GlobalState
-> Identity GlobalState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DocType -> Identity DocType) -> FlagState -> Identity FlagState
Lens' FlagState DocType
GS.docType ((DocType -> Identity DocType)
 -> GlobalState -> Identity GlobalState)
-> DocType -> StateT GlobalState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= DocType
GS.Main
                PreLaTeX
doc' <- Flagged' Document -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM Flagged' Document
doc

                -- \| assemble the final document container
                PreLaTeX -> State GlobalState PreLaTeX
forall a. a -> StateT GlobalState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreLaTeX -> State GlobalState PreLaTeX)
-> PreLaTeX -> State GlobalState PreLaTeX
forall a b. (a -> b) -> a -> b
$ PreLaTeX
doc' PreLaTeX -> PreLaTeX -> PreLaTeX
forall a. Semigroup a => a -> a -> a
<> PreLaTeX
appendices'

-------------------------------- NavTocHeaded -----------------------------------

-- | irrelevant for pdf generation
instance (ToPreLaTeXM a) => ToPreLaTeXM (NavTocHeaded (Parsed a)) where
    toPreLaTeXM :: NavTocHeaded (Parsed a) -> State GlobalState PreLaTeX
toPreLaTeXM (NavTocHeaded NavTocHeading
_ Parsed a
content) = case Parsed a
content of
        Left ParseError
e -> String -> State GlobalState PreLaTeX
forall a. HasCallStack => String -> a
error (ParseError -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseError
e)
        Right a
c -> a -> State GlobalState PreLaTeX
forall a. ToPreLaTeXM a => a -> State GlobalState PreLaTeX
toPreLaTeXM a
c