diff options
Diffstat (limited to 'src/Math.hs')
-rw-r--r-- | src/Math.hs | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/src/Math.hs b/src/Math.hs index e927fdd..db01f75 100644 --- a/src/Math.hs +++ b/src/Math.hs | |||
@@ -2,40 +2,61 @@ module Math | |||
2 | ( compileMath | 2 | ( compileMath |
3 | ) where | 3 | ) where |
4 | 4 | ||
5 | import System.IO (stdout, stderr, hPutStrLn, writeFile, readFile) | ||
5 | import System.IO.Temp (withSystemTempDirectory) | 6 | import System.IO.Temp (withSystemTempDirectory) |
6 | import System.Process (callProcess) | 7 | import System.Process (callProcess, readProcessWithExitCode) |
7 | import System.Directory (copyFile, getCurrentDirectory, setCurrentDirectory) | 8 | import System.Directory (copyFile, getCurrentDirectory, setCurrentDirectory) |
8 | import System.FilePath (takeFileName, FilePath(..), (</>)) | 9 | import System.FilePath (takeFileName, FilePath(..), (</>)) |
10 | import System.Exit (ExitCode(..)) | ||
9 | 11 | ||
10 | import Control.Monad | 12 | import Control.Monad (when) |
11 | import Control.Exception (bracket) | 13 | import Control.Exception (bracket, throwIO) |
14 | import Data.Maybe (fromMaybe, listToMaybe) | ||
15 | |||
16 | import Control.Monad.Writer.Strict (WriterT(..), execWriterT, tell) | ||
17 | import Control.Monad.Trans (liftIO) | ||
12 | 18 | ||
13 | import Control.DeepSeq (($!!)) | 19 | import Control.DeepSeq (($!!)) |
14 | 20 | ||
15 | compileMath :: String -> IO String | 21 | import Text.Regex.TDFA ((=~)) |
22 | |||
23 | instance Monoid ExitCode where | ||
24 | mempty = ExitSuccess | ||
25 | (ExitFailure a) `mappend` _ = ExitFailure a | ||
26 | ExitSuccess `mappend` x@(ExitFailure _) = x | ||
27 | ExitSuccess `mappend` ExitSuccess = ExitSuccess | ||
28 | |||
29 | |||
30 | compileMath :: String -> IO (String, String) | ||
16 | compileMath = withSystemTempDirectory "math" . compileMath' | 31 | compileMath = withSystemTempDirectory "math" . compileMath' |
17 | 32 | ||
18 | compileMath' :: String -> FilePath -> IO String | 33 | compileMath' :: String -> FilePath -> IO (String, String) |
19 | compileMath' input tmpDir = do | 34 | compileMath' input tmpDir = do |
20 | mapM_ (copyToTmp . ("tex" </>)) [ "preamble.tex" | 35 | mapM_ (copyToTmp . ("tex" </>)) [ "preamble.tex" |
21 | , "preview.dtx" | 36 | , "preview.dtx" |
22 | , "preview.ins" | 37 | , "preview.ins" |
23 | ] | 38 | ] |
24 | withCurrentDirectory tmpDir $ do | 39 | (exitCode, out, err) <- withCurrentDirectory tmpDir $ execWriterT $ do |
25 | callProcess "latex" [ "-interaction=batchmode" | 40 | run "latex" [ "-interaction=batchmode" |
26 | , "preview.ins" | 41 | , "preview.ins" |
27 | ] | 42 | ] "" |
28 | writeFile (tmpDir </> "image.tex") input | 43 | liftIO $ writeFile (tmpDir </> "image.tex") input |
29 | callProcess "latex" [ "-interaction=batchmode" | 44 | run "latex" [ "-interaction=batchmode" |
30 | , "image.tex" | 45 | , "image.tex" |
31 | ] | 46 | ] "" |
32 | callProcess "dvisvgm" [ "--exact" | 47 | run "dvisvgm" [ "--exact" |
33 | , "--no-fonts" | 48 | , "--no-fonts" |
34 | , tmpDir </> "image.dvi" | 49 | , tmpDir </> "image.dvi" |
35 | ] | 50 | ] "" |
36 | (\x -> return $!! x) =<< (readFile $ tmpDir </> "image.svg") | 51 | when (exitCode /= ExitSuccess) $ do |
52 | hPutStrLn stdout out | ||
53 | hPutStrLn stderr err | ||
54 | throwIO exitCode | ||
55 | (\x -> return $!! (x, extractAlignment err)) =<< (readFile $ tmpDir </> "image.svg") | ||
37 | where | 56 | where |
38 | copyToTmp fp = copyFile fp (tmpDir </> takeFileName fp) | 57 | copyToTmp fp = copyFile fp (tmpDir </> takeFileName fp) |
58 | run :: String -> [String] -> String -> WriterT (ExitCode, String, String) IO () | ||
59 | run bin args stdin = tell =<< liftIO (readProcessWithExitCode bin args stdin) | ||
39 | 60 | ||
40 | withCurrentDirectory :: FilePath -- ^ Directory to execute in | 61 | withCurrentDirectory :: FilePath -- ^ Directory to execute in |
41 | -> IO a -- ^ Action to be executed | 62 | -> IO a -- ^ Action to be executed |
@@ -44,3 +65,9 @@ withCurrentDirectory dir action = | |||
44 | bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do | 65 | bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do |
45 | setCurrentDirectory dir | 66 | setCurrentDirectory dir |
46 | action | 67 | action |
68 | |||
69 | extractAlignment :: String -> String | ||
70 | extractAlignment = fromMaybe "0pt" . extract . (=~ "depth=([^\\s]+)") | ||
71 | where | ||
72 | extract :: (String, String, String, [String]) -> Maybe String | ||
73 | extract (_, _, _, xs) = listToMaybe xs | ||