{-| imperative part of the programm. The outer flow of the programm is controlled here -} module All where import System.Directory.Tree import Data.String.HT import Logger import Control.Exception import ImperativeState import UrlAnalyse hiding (url) import Load import Compiler import GetImages import Control.Monad.State hiding (join) import Tools import Data.ByteString hiding (take, reverse, dropWhile, takeWhile, drop, map, concat, elem, zip, intercalate) import System.Directory import System.IO.Temp import WikiHelper import System.Info import System.Process hiding (cwd) import Static import Babel import Data.List.Split import MagicStrings import Codec.Binary.UTF8.String import Data.Map.Strict hiding (map, take, drop) import Data.ByteString.UTF8 (toString) import Data.List import Data.Maybe import Data.Char import MediaWikiParseTree import qualified Data.Map.Strict as Map hiding (take, drop) import MediaWikiParser import SimpleContributors import UrlAnalyse import Network.URL import System.FilePath import Control.Concurrent.MVar () import Data.Hashable import Hex import Data.IORef import System.IO import Codec.Archive.Zip import Data.ByteString.Lazy (toStrict) import System.Exit import System.IO.Error {-| takes a filename as input parameter and returns the so called normalized extension for it. This is and extension classifying the type of the file while used in this program. Its not necessarily the real extension of the filename. For example .jpeg images will be converted to jpg and so on. -} getExtension :: String -> String getExtension s = normalizeExtension2 (map toLower (reverse . (takeWhile (/= '.')) . reverse $ s)) {-| returns that name of image magick convert command on the current operating system. It takes the path from which mediawiki2latex was started as input parameter. On Windows convert.exe has to reside in a path relative to it for this to work. On linux it does not matter -} getConvert :: FilePath -> String getConvert p = if os == "linux" then convert else (getPathPrefix p) ++ convert where convert = if os == "linux" then "convert " else "convert.exe " {-| generates the information for the titlepage. It takes the result of the wiki text compilation (CompileResult) as first input parameter and the FullWikiUrl to the article as second parameter. It title information is found in the CompileResult it is used, otherise it is generated from the FullWikiUrl -} makeTitle :: CompileResult -> FullWikiUrl -> [Char] makeTitle result fu = theTitle where theTitle = if (Compiler.title result) == "" then pub ++ tit else pub ++ (Compiler.title result) pub = "\\publishers{" ++ (concat (map chartrans (UrlAnalyse.hostname fu))) ++ "}\n" tit = "\\title{" ++ (concat (map (chartrans) ((removePrintVersion (lemma fu))))) ++ "}\n" makeTitle2 :: CompileResult -> FullWikiUrl -> [Char] makeTitle2 result fu = theTitle where theTitle = if (Compiler.title result) == "" then tit else (Compiler.title result) tit = (concat (map (chartrans) ((removePrintVersion (lemma fu))))) {-| returns the prefix of the path where addional needed software resides depending on the operation system -} getPathPrefix :: FilePath -> String getPathPrefix p = if os == "linux" then "" else (p ++ "..\\lib\\") {-| applied the necessary image processing to a file so that it can be included in a latex document and does not take too much discspace. It takes the path form which mediawiki2latex was started as first input parameter. It takes filename with its exension stiped as second input parameter. It takes the normalized exension of the file as third parameter (see also function getExtension in this module). It takes the maximum resolution that images should have as fourth parameter. It takes the imagenumbers of the images residing in image galleries in the wiki source text as fifth parameter (those images are given a lower absolute with in cm in the pdf document and thus can be dithered to a loweder absolute with in pixels). It takes the image number of the current image as sixth parameter. -} runFileMods :: FilePath -> String -> String -> Integer -> [Integer] -> Integer -> String -> IO () runFileMods p filenamebase extension theResolution gals imgNumber pathname = case extension of ('s' : ('v' : ('g' : _))) -> do _ <- system ((getPathPrefix p) ++ "rsvg-convert -o " ++ pngfilename ++ " -a -w 1250 " ++ filename) postprocpng pngfilename _ <- system ((getPathPrefix p) ++ "rsvg-convert --format=pdf -o " ++ (filenamebase ++ "." ++ "pdf") ++ " -a -w 1250 " ++ filename) return () ('g' : ('i' : ('f' : _))) -> do stdfun b <- doesFileExist firstpngfilename if b then copyFile firstpngfilename newfilename else return () postprocpng newfilename ('t' : ('i' : ('f' : _))) -> do stdfun postprocpng newfilename ('j' : ('p' : ('g' : _))) -> postprocjpg filename ('p' : ('n' : ('g' : _))) -> postprocpng filename _ -> return () where firstpngfilename = (reverse . (drop 4) . reverse $ newfilename) ++ "-0.png" newfilename = filenamebase ++ "." ++ (normalizeExtension extension) filename = filenamebase ++ "." ++ extension stdfun = do _ <- system ((getConvert p) ++ "\"" ++ filename ++ "\" \"" ++ newfilename ++ "\"") return () postprocpng fn = do _ <- background fn dither fn return () postprocjpg fn = do _ <- system ((getConvert p) ++ "-verbose " ++ fn ++ " " ++ fn) dither fn return () background fn = system ((getConvert p) ++ fn ++ " -background white -flatten " ++ fn) pngfilename = filenamebase ++ "." ++ "png" dither :: String -> IO () dither fn = do _ <- system ((getConvert p) ++ "-verbose " ++ fn ++ " -format '%w' " ++ pathname ++ "nullfile.bmp" ++ " > " ++ pathname ++ "dump2 2> " ++ pathname ++ "dump") dump <- Tools.readFile (pathname ++ "dump") case reverse (Prelude.filter (\ x -> (trim x) /= "") (splitOn "\n" dump)) of (x : _) -> case splitOn " " x of (_ : (_ : (y : _))) -> case splitOn "x" y of (z : _) -> case reads z of [(ii, _)] -> do runDither fn (if imgNumber `elem` gals then galleryWidth else imageWidth) ii _ -> return () _ -> return () _ -> return () _ -> return () runDither :: String -> Integer -> Integer -> IO () runDither fn newSize oldSize = if newSize < oldSize then system ((getConvert p) ++ fn ++ " -resize " ++ (show newSize) ++ " " ++ fn) >> return () else return () textWidth = 10.5 galleryImageWidth = 5.0 centimetersPerInch :: Double centimetersPerInch = 2.54 galleryWidth :: Integer galleryWidth = round ((fromIntegral theResolution) * galleryImageWidth / centimetersPerInch) imageWidth :: Integer imageWidth = round ((fromIntegral theResolution) * textWidth / centimetersPerInch) {-| function to write the image files into the temporary directory and modify the files for use in a LaTeX document. It takes the pathname of temporary image download directory as first input parameter. Please not the the temporary image download directory is always different from the temporary directory. It takes the pathname of the directory in which mediawiki2latex was stated as second input parameter. It takes the name of the temporary directory as third input parameter. It takes the result of the image downloading process as fourth input parameter. This structure has a Maybe monad as outer type since the image download may fail. Inside is a 3 element tuple. The first one is the filename of the image on the wiki. The second one is the number under which the image was stored in the temporary image download directory. The third one is a list of possible urls where the image may be found on the wiki. It takes maximum resolution that images should have as fifth parameter. It takes the list of images number of images residing in galleries as sixth input parameter. -} writeFiles :: FilePath -> FilePath -> String -> [Maybe ImageInfo] -> Integer -> [Integer] -> IO () writeFiles dir p pathname theImages theResolution gals = mapM_ go (Prelude.zip ([1 ..] :: [Integer]) theImages) where go (i, Just x) = do let filenamebase = (pathname ++ (show i)) let filename = filenamebase ++ "." ++ (getExtension (wikiFilename x)) filecontent <- Data.ByteString.readFile (dir > (show (imageNumber x))) Data.ByteString.writeFile filename filecontent runFileMods p filenamebase (getExtension (wikiFilename x)) theResolution gals i pathname go _ = return () writeFiles2 :: String -> String -> [(String, Int)] -> IO () writeFiles2 tmpdir pathname forms = mapM_ go forms where go (x, _) = do filecontent <- Data.ByteString.readFile (tmpdir > x) Data.ByteString.writeFile (pathname ++ (Prelude.last (splitOn "/" x))) filecontent data LatexConfig = LatexConfig{figures :: [Maybe ImageInfo], title :: String, fullConfig :: FullConfig, content :: String, hostname :: String, theResult :: CompileResult, onlyTables :: Bool, lang :: Maybe String, theTempDir :: String, formulas :: [(String, Int)], figHTML :: String} runLaTeX :: LatexConfig -> ImperativeMonad ByteString runLaTeX config = liftIO (withSystemTempDirectory "MediaWiki2LaTeX" (runLaTeXCallback config)) runLaTeXCallback :: LatexConfig -> FilePath -> IO ByteString runLaTeXCallback config pathname = do extract pathname case (ImperativeState.headers (fullConfig config)) of Just x -> do d <- readDirectoryWith Data.ByteString.readFile (x ++ "/./") _ <- writeDirectoryWith Data.ByteString.writeFile d{anchor = pathname > "document/headers"} return () _ -> return () if os == "linux" then return () else do d <- readDirectoryWith Data.ByteString.readFile ((mainPath (fullConfig config)) ++ "../fonts/main/") _ <- writeDirectoryWith Data.ByteString.writeFile d{anchor = pathname ++ "/document/"} return () Tools.writeFile (pathname ++ "/document/main/main.tex") (content config) Tools.writeFile (pathname ++ "/document/index.html") ((html (theResult config)) ++ "
Number | Contributors | License |