data-pdf-fieldreader (empty) → 0.1.0.0
raw patch · 6 files changed
+187/−0 lines, 6 filesdep +basedep +bytestringdep +containers
Dependencies added: base, bytestring, containers, data-pdf-fieldreader, optparse-applicative, text
Files
- CHANGELOG.md +9/−0
- LICENSE +21/−0
- README.md +8/−0
- app/Main.hs +27/−0
- data-pdf-fieldreader.cabal +67/−0
- src/Data/Pdf/FieldReader.hs +55/−0
+ CHANGELOG.md view
@@ -0,0 +1,9 @@+# Changelog++`pdfreader` uses [PVP Versioning][1].++## 0.1.0.0++* Initially created.++[1]: https://pvp.haskell.org
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2021 Scott Sedgwick++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,8 @@+# Data.Pdf.FieldReader++[](https://hackage.haskell.org/package/pdfreader)+[](LICENSE)++This is a minimal library for reading the data in form fields out of a PDF document.++A trivial example of how to use this library can be found in `app/Main.hs` in the source repository.
+ app/Main.hs view
@@ -0,0 +1,27 @@+module Main (main) where++import Data.Pdf.FieldReader (readPdfFields)+import qualified Data.ByteString as B+import Options.Applicative++data Options = Options {+ datafile :: String+}++options :: Parser Options+options = Options+ <$> strOption ( short 'f' <> long "datafile" <> metavar "DATAFILE" <> help "PDF file to read" )+ +main :: IO ()+main = run =<< execParser opts+ where+ opts = info (options <**> helper)+ ( fullDesc+ <> progDesc "Read a PDF file and print all the values in its form fields"+ <> header "pdfreader - a test for Data.Pdf.FieldReader" )+ +run :: Options -> IO()+run opts = do+ xs <- B.readFile (datafile opts)+ let ys = readPdfFields xs+ print ys
+ data-pdf-fieldreader.cabal view
@@ -0,0 +1,67 @@+cabal-version: 2.4+name: data-pdf-fieldreader+version: 0.1.0.0+description: Simple function to extract PDF form field values from a PDF file.+synopsis: Read PDF form fields+category: Data+homepage: https://github.com/ScottSedgwick/Data.Pdf.FieldReader+license: MIT+license-file: LICENSE+author: Scott Sedgwick+maintainer: Scott Sedgwick <scott.sedgwick@gmail.com>+copyright: 2021 Scott Sedgwick+build-type: Simple+extra-doc-files: README.md+ CHANGELOG.md+tested-with: GHC == 8.8.3++common common-options+ build-depends: base == 4.*+ , bytestring >= 0.10.12 && < 0.11+ , containers >= 0.6.4 && < 0.7+ , text >= 1.2.4 && < 1.3+ + ghc-options: -Wall+ -Wcompat+ -Widentities+ -Wincomplete-uni-patterns+ -Wincomplete-record-updates+ if impl(ghc >= 8.0)+ ghc-options: -Wredundant-constraints+ if impl(ghc >= 8.2)+ ghc-options: -fhide-source-paths+ if impl(ghc >= 8.4)+ ghc-options: -Wmissing-export-lists+ -Wpartial-fields+ if impl(ghc >= 8.8)+ ghc-options: -Wmissing-deriving-strategies++ default-language: Haskell2010+ default-extensions: ConstraintKinds+ DeriveGeneric+ GeneralizedNewtypeDeriving+ InstanceSigs+ KindSignatures+ LambdaCase+ OverloadedStrings+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TupleSections+ TypeApplications+ ViewPatterns++library+ import: common-options+ hs-source-dirs: src+ exposed-modules: Data.Pdf.FieldReader++executable pdfreader+ import: common-options+ hs-source-dirs: app+ main-is: Main.hs+ build-depends: data-pdf-fieldreader+ , optparse-applicative >= 0.16.1 && < 0.17+ ghc-options: -threaded+ -rtsopts+ -with-rtsopts=-N
+ src/Data/Pdf/FieldReader.hs view
@@ -0,0 +1,55 @@+{- |+Copyright: (c) 2021 Scott Sedgwick+SPDX-License-Identifier: MIT+Maintainer: Scott Sedgwick <scott.sedgwick@gmail.com>+Stability: experimental+Portability: unknown++Simple function to extract PDF form field values from a PDF file.+-}++module Data.Pdf.FieldReader+ ( -- * File data parser+ --+ -- $fileDataParser+ readPdfFields+ ) where++import Prelude hiding (drop, init, lines)+import Data.ByteString (ByteString)+import Data.ByteString.Char8 (unpack)+import Data.List (foldl')+import Data.Map (Map, fromList)+import Data.Text (Text, drop, init, isPrefixOf, lines, pack, replace, strip)++-- $fileDataParser+-- +-- Extract a Map of name-value pairs from the data read from a PDF file.+-- For example:+--+-- >import qualified Data.ByteString as B+-- >import Data.Pdf.FieldReader (readPdfFields)+-- >+-- >main :: IO()+-- >main = do+-- > xs <- Data.ByteString.readFile "filename"+-- > let ys = readPdfFields xs+-- > print ys++-- | Read fields from file data+readPdfFields :: ByteString -> Map Text Text+readPdfFields = fromList . snd . foldl' f (Nothing, []) . lines . pack . unpack+ where+ f (Nothing, b) x | isFldName x = (Just (fmtFldName x), b) + | otherwise = (Nothing, b)+ f ((Just n), b) x | isFldName x = (Just (fmtFldName x), b)+ | isFldValue x = (Nothing, (n, (fmtFldValue x)) : b)+ | otherwise = ((Just n), b)+ isFldName = isPrefixOf "/T("+ fmtFldName = stripBrackets+ isFldValue = isPrefixOf "/V("+ fmtFldValue = unescape . stripBrackets+ stripBrackets = init . drop 3 . strip+ unescape xs = foldr (\(a, b) c -> replace a b c) xs escPairs+ escPairs = [("\\n", "\n"), ("\\(", "("), ("\\)", ")")]+