module Text.LaTeX.LambdaTeX (
module Text.LaTeX.LambdaTeX
, module Text.LaTeX.LambdaTeX.Selection
, module Text.LaTeX.LambdaTeX.Reference
, module Text.LaTeX.LambdaTeX.Package
, module Text.LaTeX.LambdaTeX.Action
, module Text.LaTeX.LambdaTeX.Types
) where
import Control.Monad (forM_)
import Control.Monad.IO.Class (MonadIO (..))
import Control.Concurrent.Async (async, wait)
import qualified Data.Set as S
import qualified Data.Text.IO as T
import Text.LaTeX.Base (LaTeX, renderFile)
import Text.LaTeX.LambdaTeX.Action
import Text.LaTeX.LambdaTeX.Package
import Text.LaTeX.LambdaTeX.Package.Internal
import Text.LaTeX.LambdaTeX.Reference
import Text.LaTeX.LambdaTeX.Reference.Internal
import Text.LaTeX.LambdaTeX.Reference.Types
import Text.LaTeX.LambdaTeX.Selection
import Text.LaTeX.LambdaTeX.Selection.Types
import Text.LaTeX.LambdaTeX.Types
import Text.LaTeX.LambdaTeX.Utils
buildLaTeXProject :: MonadIO m => ΛTeXT m a -> ProjectConfig -> m (Either [ΛError] ())
buildLaTeXProject func conf = do
(errs, latex, refs, actions) <- execLambdaTeXT func $ projectGenerationConfig conf
let renderTex = do
let mainTexFile = projectTexFileName conf ++ ".tex"
renderFile mainTexFile latex
let renderMain = do
let mainBibFile = projectBibFileName conf ++ ".bib"
removeIfExists mainBibFile
T.appendFile mainBibFile $ renderReferences refs
let performAction (name, action) = do
action
putStrLn $ "Job " ++ name ++ " done."
as <- liftIO $ mapM async $ renderTex : renderMain : map performAction actions
liftIO $ forM_ as wait
return $ if null errs
then Right ()
else Left errs
execLambdaTeXT :: Monad m => ΛTeXT m a -> GenerationConfig -> m ([ΛError], LaTeX, [Reference], [(String, IO ())])
execLambdaTeXT func conf = do
((_,latex), _, output) <- runΛTeX func (ΛConfig $ generationSelection conf) initState
let result = injectPackageDependencies (S.toList $ outputPackageDependencies output) latex
let refs = S.toList $ outputExternalReferences output
let actions = outputActions output
let made = outputLabelsMade output
needed = outputLabelsNeeded output
diff = S.difference needed made
let referss = map ReferenceMissing $ S.toList diff
return (referss, result, refs, actions)
where
initState :: ΛState
initState = ΛState { stateCurrentPart = emptyPart }
data ProjectConfig = ProjectConfig {
projectGenerationConfig :: GenerationConfig
, projectBibFileName :: String
, projectTexFileName :: String
}
defaultProjectConfig :: ProjectConfig
defaultProjectConfig = ProjectConfig {
projectGenerationConfig = defaultGenerationConfig
, projectBibFileName = "main"
, projectTexFileName = "main"
}
data GenerationConfig = GenerationConfig {
generationSelection :: Selection
}
defaultGenerationConfig :: GenerationConfig
defaultGenerationConfig = GenerationConfig {
generationSelection = [All]
}