hpdft-0.4.7.0: app/Cli/Text.hs
{-# LANGUAGE OverloadedStrings #-}
module Cli.Text
( runExtractText
, streamLegacyToStdout
, showPage
) where
import Cli.Common (maybePassword, printWarnings, runOrDie, withFile)
import Cli.Parser (ExtractOpt(..))
import PDF.Document (Document(..), docRootRef, openDocument)
import PDF.Layout (LayoutOptions(..), defaultLayoutOptions)
import PDF.Page (pageRefsFromRoot)
import PDF.Text
( pageTextGeomWith
, pdfToTextGeomBSWith
, pdfToTextStreamDoc
, pdfToTextTaggedBSWith
)
import System.IO (hFlush, hIsTerminalDevice, hPutStr, hPutStrLn, putStrLn, stderr, stdout)
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.IORef (newIORef, readIORef, writeIORef)
import Control.Monad (when)
runExtractText :: ExtractOpt -> IO ()
runExtractText ExtractOpt{eoPage=pg, eoGeom=gm, eoTagged=tg, eoLegacy=lg,
eoQuiet=quiet, eoFootnotes=fnn, eoRuby=rb,
eoPassword=pw, eoFile=fn} =
withFile fn $
let mpw = maybePassword pw
lopts = defaultLayoutOptions {optFootnotes = fnn, optRuby = rb}
in if pg /= 0
then showPage lopts fn mpw pg
else case () of
_ | lg && not gm && not tg -> do
doc <- runOrDie (openDocument fn mpw)
streamLegacyToStdout doc quiet
| gm && not tg && not lg -> pdfToTextGeom lopts fn mpw
| otherwise -> pdfToTextTagged lopts fn mpw
streamLegacyToStdout :: Document -> Bool -> IO ()
streamLegacyToStdout doc quiet = do
stderrTTY <- hIsTerminalDevice stderr
let showProgress pg total =
when (not quiet && stderrTTY && total > 0) $
hPutStr stderr ("\rhpdft: page " ++ show pg ++ "/" ++ show total ++ "...")
clearProgress total =
when (not quiet && stderrTTY && total > 0) $
hPutStr stderr ("\r\ESC[K")
totalRef <- newIORef (0 :: Int)
ws <- pdfToTextStreamDoc doc $ \pg total txt -> do
writeIORef totalRef total
showProgress pg total
BSL.putStr txt
hFlush stdout
total <- readIORef totalRef
clearProgress total
putStrLn ""
printWarnings ws
pdfToTextGeom :: LayoutOptions -> FilePath -> Maybe String -> IO ()
pdfToTextGeom lopts filename mpw = do
txt <- runOrDie (pdfToTextGeomBSWith lopts filename mpw)
BSL.putStrLn txt
pdfToTextTagged :: LayoutOptions -> FilePath -> Maybe String -> IO ()
pdfToTextTagged lopts filename mpw = do
txt <- runOrDie (pdfToTextTaggedBSWith lopts filename mpw)
BSL.putStrLn txt
showPage :: LayoutOptions -> FilePath -> Maybe String -> Int -> IO ()
showPage lopts filename mpw page = do
doc <- runOrDie (openDocument filename mpw)
root <- runOrDie (return (docRootRef doc))
let pagetree = pageRefsFromRoot root (docObjs doc)
if page >= 1 && length pagetree >= page
then do
txt <- runOrDie (return (pageTextGeomWith lopts doc (pagetree !! (page - 1))))
BSL.putStr txt
else putStrLn $ "hpdft: No Page " ++ show page