----------------------------------------------------------------
--
-- Module      :  Uniform.latex
--
-- | convert latex to pdf 
---------------------------------------------------------------
{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DeriveGeneric  #-}

{-# OPTIONS_GHC -w #-}

module Uniform.WritePDF
  ( module Uniform.WritePDF
  ) where

import qualified System.Exit as Sys
import qualified System.Process as SysP
import System.IO.Silently (silence)
-- import Uniform.Json
import UniformBase




writePDF2 :: NoticeLevel -> Path Abs File -> Path Abs File -> Path Abs Dir -> ErrIO ()
-- convert the text in the file given (a full latex, exetnsion "tex") into a pdf
-- in the second path
-- refDir is the current working directory (which must be the directory
-- where the intermediate files are produced
--  likely wrong: from which images etc. are searched for )
writePDF2 :: NoticeLevel
-> Path Abs File -> Path Abs File -> Path Abs Dir -> ErrIO ()
writePDF2 NoticeLevel
debug Path Abs File
fn Path Abs File
fnres Path Abs Dir
refDir = do
    -- -- check for locale
    -- loc <- callIO $ Sys.callProcess "locale" []
    -- putIOwords ["writePDF2 locale "]
    -- ls <- callIO $ Sys.callProcess "ls" []
    -- putIOwords ["writePDF2 ls "]

    -- process

    let infn :: FilePath
infn =   forall fp. Filenames1 fp => fp -> FilePath
getNakedFileName forall a b. (a -> b) -> a -> b
$ Path Abs File
fn :: FilePath -- setExtension extTex fn :: Path Abs File
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (NoticeLevel -> Bool
inform NoticeLevel
debug) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadIO m => [Text] -> m ()
putIOwords
        [ Text
"writePDF2 1 infn"
        , forall {a}. Show a => a -> Text
showT FilePath
infn
        , Text
"\n\t fnres"
        , forall {a}. Show a => a -> Text
showT Path Abs File
fnres
        , Text
"\n\t refDir (will be current working dir but seem not to work)"
        , forall {a}. Show a => a -> Text
showT Path Abs Dir
refDir
        ]
    let dir1 :: FilePath
dir1 = forall fp. Filenames1 fp => fp -> FilePath
getParentDir Path Abs File
fnres :: FilePath 
    let out1 :: FilePath
out1 = FilePath
"--output-directory=" forall a. Semigroup a => a -> a -> a
<> FilePath
dir1
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (NoticeLevel -> Bool
inform NoticeLevel
debug) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadIO m => [Text] -> m ()
putIOwords [Text
"writePDF2 2 out1", forall {a}. Show a => a -> Text
showT FilePath
out1]

    ExitCode
exit_code1 <- Bool -> FilePath -> [FilePath] -> Path Abs Dir -> ErrIO ExitCode
callProcessWithCWD Bool
True -- (not (inform debug))  -- silenced or not 
        FilePath
"lualatex"
        [FilePath
out1, FilePath
"-interaction=nonstopmode",  FilePath
infn]
        Path Abs Dir
refDir
    ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling ExitCode
exit_code1 FilePath
infn Int
1

    ExitCode
exit_code2 <- Bool -> FilePath -> [FilePath] -> Path Abs Dir -> ErrIO ExitCode
callProcessWithCWD Bool
True -- (not (inform debug))  -- silenced or not 
        FilePath
"biber"
        [ FilePath
infn]
        Path Abs Dir
refDir
    ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling ExitCode
exit_code2 FilePath
infn Int
2

    ExitCode
exit_code3 <- Bool -> FilePath -> [FilePath] -> Path Abs Dir -> ErrIO ExitCode
callProcessWithCWD Bool
True -- (not (inform debug))  -- silenced or not 
        FilePath
"makeindex"
        [FilePath
"-q", FilePath
infn]
        Path Abs Dir
refDir
    ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling ExitCode
exit_code3 FilePath
infn Int
3

    ExitCode
exit_code3 <- Bool -> FilePath -> [FilePath] -> Path Abs Dir -> ErrIO ExitCode
callProcessWithCWD Bool
True -- (not (inform debug))  -- silenced or not 
        FilePath
"lualatex"
        [FilePath
out1, FilePath
"-interaction=nonstopmode",  FilePath
infn]
        Path Abs Dir
refDir
    ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling ExitCode
exit_code3 FilePath
infn Int
4

    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (NoticeLevel -> Bool
inform NoticeLevel
debug) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadIO m => [Text] -> m ()
putIOwords [Text
"writePDF2 end for", forall {a}. Show a => a -> Text
showT FilePath
out1]

exitHandling :: Sys.ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling :: ExitCode -> FilePath -> Int -> ErrIO ()
exitHandling ExitCode
exit_code FilePath
filename Int
step = do
    -- the count indicated the step count 
    case ExitCode
exit_code of
        ExitCode
Sys.ExitSuccess -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Sys.ExitFailure Int
r -> do 
                forall (m :: * -> *). MonadIO m => [Text] -> m ()
putIOwords [Text
"callProcessWithCWD - failed - check for 1 log, for 2 blg " 
                            , Text
"show exit code", forall {a}. Show a => a -> Text
showT Int
r, Text
"step", forall {a}. Show a => a -> Text
showT Int
step
                            -- , "\n\tif lualatex: 1 is normal, check log file "
                            -- , "\n\tif biber: 2 is normal, check blg file "
                            -- , "\n\tfor output file", showT filename
                            ]
                -- fail . show $ r
                forall (m :: * -> *) a. Monad m => a -> m a
return ()  -- lualatex does not deal with error information well - check log file 


    forall (m :: * -> *) a. Monad m => a -> m a
return ()

--------------------------------
-- callProcess/callCommand with current working directory
-- from http://hackage.haskell.org/package/process-1.6.10.0/docs/src/System.Process.html#callProcess

{- | Creates a new process to run the specified command with the given
 arguments, and wait for it to finish.  If the command returns a non-zero
 exit code, an exception is raised.

 If an asynchronous exception is thrown to the thread executing
 @callProcess@, the forked process will be terminated and
 @callProcess@ will wait (block) until the process has been
 terminated.

 @since 1.2.0.0

 wrapped in silence to avoid output on std out
-}
callProcessWithCWD :: Bool ->  FilePath -> [String] -> Path Abs Dir -> ErrIO Sys.ExitCode
-- | call a process silenced 
-- cwd1 is the curren working dir (where the intermediate files are
-- but seems not to be the place where biblio is searched for
callProcessWithCWD :: Bool -> FilePath -> [FilePath] -> Path Abs Dir -> ErrIO ExitCode
callProcessWithCWD Bool
silenced FilePath
cmd [FilePath]
args Path Abs Dir
cwd1 = forall a. IO a -> ErrIO a
callIO 
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Bool
silenced then (forall a. IO a -> IO a
silence) else (forall a. a -> a
id)) forall a b. (a -> b) -> a -> b
$ do -- . silence $ do
    ExitCode
exit_code <-
        forall a.
CreateProcess
-> (Maybe Handle
    -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-> IO a
SysP.withCreateProcess -- "callProcess"
            (FilePath -> [FilePath] -> CreateProcess
SysP.proc FilePath
cmd   [FilePath]
args)
                { delegate_ctlc :: Bool
SysP.delegate_ctlc = Bool
True
                , cwd :: Maybe FilePath
SysP.cwd = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b t. Path b t -> FilePath
toFilePath forall a b. (a -> b) -> a -> b
$ Path Abs Dir
cwd1
                }
            forall a b. (a -> b) -> a -> b
$ \Maybe Handle
_ Maybe Handle
_ Maybe Handle
_ ProcessHandle
p ->
                ProcessHandle -> IO ExitCode
SysP.waitForProcess ProcessHandle
p
    forall (m :: * -> *) a. Monad m => a -> m a
return ExitCode
exit_code