module Text.FromHTML
( fromHTML
, ExportType(..)
) where
import qualified Data.Char as C
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import qualified Data.ByteString as B
import GHC.IO.Handle
import System.Exit
import System.Process
import System.IO.Unsafe
data ExportType = HTML
| LaTeX
| RTF
| RST
| Markdown
| AsciiDoc
| Docx
| ODT
| DokuWiki
| MediaWiki
| EPUB2
| EPUB3
| PDF
deriving (Show, Read, Enum, Bounded, Eq)
eitherToMaybe :: Show a => Either a b -> Maybe b
eitherToMaybe (Right x) = Just x
eitherToMaybe _ = Nothing
str2BS :: String -> B.ByteString
str2BS = E.encodeUtf8 . T.pack
fromHTML :: ExportType -> String -> Maybe B.ByteString
fromHTML HTML html = Just . str2BS $ html
fromHTML PDF html = handleMaker $ makePDF html
fromHTML extp html = handleMaker $ makePD extp html
type Input = String
type Output = B.ByteString
type Command = Input -> IO (Either Output Output)
type Process = IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
handleMaker :: Either Output Output -> Maybe B.ByteString
handleMaker (Right x) = Just x
handleMaker _ = Nothing
makePDF :: Input -> Either Output Output
makePDF html = unsafePerformIO $ wkhtmltopdf html
makePD :: ExportType -> Input -> Either Output Output
makePD expt html = unsafePerformIO $ pandoc expt html
wkhtmltopdf :: Command
wkhtmltopdf = perform cprocess
where
opts = ["--quiet", "--encoding", "utf-8", "-", "-"]
cprocess = procWith $ proc "wkhtmltopdf" opts
pandoc :: ExportType -> Command
pandoc expt = perform cprocess
where
format = exportType2PD expt
opts = ["-s", "-f", "html", "-t", format, "-o", "-"]
cprocess = procWith $ proc "pandoc" opts
perform :: CreateProcess -> Command
perform cprocess input = do
(Just stdin, Just stdout, Just stderr, p) <- createProcess cprocess
hPutStr stdin input >> hClose stdin
exitCode <- waitForProcess p
case exitCode of
ExitSuccess -> Right <$> B.hGetContents stdout
_ -> Left <$> B.hGetContents stderr
procWith p = p { std_out = CreatePipe
, std_in = CreatePipe
, std_err = CreatePipe
}
exportType2PD :: ExportType -> String
exportType2PD = map C.toLower . show