Improve getObj example to catch no-existing ObjectId and default to listing existing ObjectIds when none is provided

This commit is contained in:
Tissevert 2019-11-29 11:53:08 +01:00
parent 380c1e439b
commit 7eca875900

View file

@ -4,16 +4,17 @@ import Codec.Compression.Zlib (decompress)
import Data.ByteString.Lazy.Char8 (ByteString) import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS (readFile) import qualified Data.ByteString.Char8 as BS (readFile)
import qualified Data.ByteString.Lazy.Char8 as Lazy (fromStrict, putStr, toStrict) import qualified Data.ByteString.Lazy.Char8 as Lazy (fromStrict, putStr, toStrict)
import Data.Map ((!)) import Data.Map ((!?))
import qualified Data.Map as Map (lookup) import qualified Data.Map as Map (keys, lookup)
import PDF (Document(..), parseDocument) import PDF (Document(..), parseDocument)
import qualified PDF.EOL as EOL (Style) import qualified PDF.EOL as EOL (Style)
import PDF.Object (Content(..), DirectObject(..), Object(..), Name(..)) import PDF.Object (Content(..), DirectObject(..), Object(..), Name(..))
import PDF.Output (ObjectId(..)) import PDF.Output (ObjectId(..))
import qualified PDF.Output as Output (render) import qualified PDF.Output as Output (render)
import PDF.Update (unify) import PDF.Update (unify)
import System.Environment (getArgs) import System.Environment (getArgs, getProgName)
import System.IO (hPutStrLn, stderr) import System.Exit (die)
import Text.Printf (printf)
display :: EOL.Style -> Object -> ByteString display :: EOL.Style -> Object -> ByteString
display eolStyle d@(Direct _) = Output.render eolStyle d display eolStyle d@(Direct _) = Output.render eolStyle d
@ -25,16 +26,28 @@ display eolStyle s@(Stream {header, streamContent}) = Output.render eolStyle $
} }
_ -> s _ -> s
extractObject :: ObjectId -> Document -> ByteString extractObject :: ObjectId -> Document -> Either String ByteString
extractObject objectId (Document {eolStyle, updates}) = extractObject objectId (Document {eolStyle, updates}) =
display eolStyle . (!objectId) $ objects content case objects content !? objectId of
Nothing -> Left $ "No object has ID " ++ show (getObjectId objectId)
Just o -> Right $ display eolStyle o
where where
content = unify updates content = unify updates
listObjectIds :: Document -> Either String [String]
listObjectIds =
Right . prependTitle . toString . Map.keys . objects . unify . updates
where
toString = fmap (show . getObjectId)
prependTitle = ("ObjectIds defined in this PDF:":)
main :: IO () main :: IO ()
main = do main = do
[inputFile, objectId] <- getArgs (inputFile, getData) <- parse =<< getArgs
result <- parseDocument <$> BS.readFile inputFile input <- BS.readFile inputFile
case result of either die id $ (parseDocument input >>= getData)
Left parseError -> hPutStrLn stderr parseError where
Right doc -> Lazy.putStr $ extractObject (ObjectId (read objectId)) doc parse [inputFile] = return (inputFile, fmap (mapM_ putStrLn) . listObjectIds)
parse [inputFile, objectId] = return
(inputFile, fmap Lazy.putStr . extractObject (ObjectId (read objectId)))
parse _ = die . printf "Syntax: %s inputFile [OBJECT_ID]\n" =<< getProgName