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_, void)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Concurrent.Async (async, wait)
import System.FilePath
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
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 (projectBuildDir conf </> mainTexFile) latex
let renderMain = do
let mainBibFile = projectBibFileName conf ++ ".bib"
T.writeFile (projectBuildDir conf </> mainBibFile) $
renderReferences refs
let performAction (name, action) = do
void $ action $ projectBuildDir conf
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, FilePath -> IO ())])
execLambdaTeXT func conf = do
((_, latex), _, output) <-
runΛTeX func (ΛConfig $ generationSelection conf) initState
let mresult =
injectPackageDependencies
(S.toList $ outputPackageDependencies output)
latex
let (extraErrs, result) =
case mresult of
Nothing -> ([IncompatibleDependencies], latex)
Just res -> ([], res)
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 (extraErrs ++ referss, result, refs, actions)
where
initState :: ΛState
initState = ΛState {stateCurrentPart = emptyPart}
data ProjectConfig = ProjectConfig
{ projectGenerationConfig :: GenerationConfig
, projectBibFileName :: String
, projectTexFileName :: String
, projectBuildDir :: FilePath
} deriving (Show, Eq)
defaultProjectConfig :: ProjectConfig
defaultProjectConfig =
ProjectConfig
{ projectGenerationConfig = defaultGenerationConfig
, projectBibFileName = "main"
, projectTexFileName = "main"
, projectBuildDir = "."
}
newtype GenerationConfig = GenerationConfig
{ generationSelection :: Selection
} deriving (Show, Eq)
defaultGenerationConfig :: GenerationConfig
defaultGenerationConfig = GenerationConfig {generationSelection = [All]}