reveal/src/Main.hs

52 lines
1.7 KiB
Haskell

{-# LANGUAGE NamedFieldPuns #-}
module Main where
import Codec.Compression.Zlib (compress, decompress)
import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as BS (
length, lines, readFile, unlines, writeFile
)
import qualified Data.Map as Map (insert, lookup)
import PDF (Document(..), parseDocument, render)
import PDF.Object (Content(..), DirectObject(..), Object(..), Name(..), Number(..))
import PDF.TextRendering (TextRendering(..), update)
import System.Environment (getArgs)
import System.IO (hPutStrLn, stderr)
revealFlateEncodedText :: ByteString -> ByteString
revealFlateEncodedText = compress . revealText . decompress
where
revealText = BS.unlines . fmap fill . BS.lines
fill = update $ const Fill
revealObject :: Object -> Object
revealObject obj@(Stream {header, streamContent}) =
case Map.lookup (Name "Filter") header of
Just (NameObject (Name "FlateDecode")) ->
let newStreamContent = revealFlateEncodedText streamContent in
let newLength = Number . fromIntegral $ BS.length newStreamContent in
Stream {
header = Map.insert (Name "Length") (NumberObject newLength) header
, streamContent = newStreamContent
}
_ -> obj
revealObject obj = obj
revealContent :: Content -> Content
revealContent content = content {
objects = revealObject <$> (objects content)
}
reveal :: Document -> Document
reveal document = document {
contents = revealContent <$> (contents document)
}
main :: IO ()
main = do
[inputPath, outputPath] <- getArgs
result <- parseDocument <$> BS.readFile inputPath
case result of
Left parseError -> hPutStrLn stderr $ show parseError
Right doc -> BS.writeFile outputPath . render $ reveal doc