packages feed

pdf-toolbox-content 0.0.3.1 → 0.0.3.2

raw patch · 4 files changed

+73/−37 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

changelog.md view
@@ -1,3 +1,7 @@+0.0.3.2++* support array ranges in unicode cmap (#15)+* support Op\_apostrophe content operator (#16)  0.0.3.1 
lib/Pdf/Toolbox/Content/Processor.hs view
@@ -269,6 +269,11 @@     } processOp (Op_Tw, args) _ = left $ UnexpectedError $ "Op_Tw: wrong number of agruments:" ++ show args +processOp (Op_apostrophe, [o]) p = do+  p' <- processOp (Op_T_star, []) p+  processOp (Op_Tj, [o]) p'+processOp (Op_apostrophe, args) _ = left $ UnexpectedError $ "Op_apostrophe: wrong number of agruments:" ++ show args+ processOp _ p = return p  ensureInTextObject :: Monad m => Bool -> Processor -> PdfE m ()
lib/Pdf/Toolbox/Content/UnicodeCMap.hs view
@@ -11,6 +11,8 @@ ) where +import Data.Monoid+import Data.Functor import Data.Char import Data.Map (Map) import qualified Data.Map as Map@@ -39,9 +41,9 @@ parseUnicodeCMap :: ByteString -> Either String UnicodeCMap parseUnicodeCMap cmap =   case (codeRanges, chars, ranges) of-    (Right cr, Right cs, Right rs) -> Right $ UnicodeCMap {+    (Right cr, Right cs, Right (rs, crs)) -> Right $ UnicodeCMap {       unicodeCMapCodeRanges = cr,-      unicodeCMapChars = cs,+      unicodeCMapChars = cs <> crs,       unicodeCMapRanges = rs       }     (Left err, _, _) -> Left $ "CMap code ranges: " ++ err@@ -67,7 +69,9 @@   inRange glyph (start, end) = glyph >= start && glyph <= end  toCode :: ByteString -> Int-toCode bs = fst $ BS.foldr (\b (sm, i) -> (sm + fromIntegral b * i, i * 255)) (0, 1) bs+toCode bs = fst $ BS.foldr (\b (sm, i) ->+                    (sm + fromIntegral b * i, i * 255)) (0, 1) bs+ -- | Convert glyph to text -- -- Note: one glyph can represent more then one char, e.g. for ligatures@@ -77,7 +81,8 @@     Just txt -> Just txt     Nothing ->       case filter inRange (unicodeCMapRanges cmap) of-        [(start, _, char)] -> Just (Text.singleton $ toEnum $ (fromEnum char) + (glyph - start))+        [(start, _, char)] -> Just (Text.singleton $ toEnum+                                    $ (fromEnum char) + (glyph - start))         _ -> Nothing   where   inRange (start, end, _) = glyph >= start && glyph <= end@@ -92,59 +97,77 @@    chars <- replicateM n $ do     P.skipSpace-    _ <- P.char '<'-    i <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'+    i <- parseHex     P.skipSpace-    _ <- P.char '<'-    j <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'+    j <- parseHex     return (toCode i, Text.decodeUtf16BE j)    return $ Map.fromList chars -rangesParser :: Parser [(Int, Int, Char)]+-- | It returns regular ranges and char map+--+-- Array ranges are converted to char map+rangesParser :: Parser ([(Int, Int, Char)], Map Int Text) rangesParser = do-  n <- P.option 0 $ skipTillParser $ do+  n <- P.option (0 :: Int) $ skipTillParser $ do     n <- P.decimal     P.skipSpace-    _ <- P.string "beginbfrange"+    void $ P.string "beginbfrange"     return n -  replicateM n $ do-    P.skipSpace-    _ <- P.char '<'-    i <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'-    P.skipSpace-    _ <- P.char '<'-    j <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'-    P.skipSpace-    _ <- P.char '<'-    k <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'-    return (toCode i, toCode j, Text.head $ Text.decodeUtf16BE k)+  let go 0 rs cs = return (rs, cs)+      go count rs cs = do+        P.skipSpace+        i <- toCode <$> parseHex+        P.skipSpace+        j <- toCode <$> parseHex+        P.skipSpace+        k <- P.eitherP parseHex parseHexArray+        case k of+          Left h -> do+            c <- case Text.uncons $ Text.decodeUtf16BE h of+                   Nothing -> fail "Can't decode range"+                   Just (v, _) -> return v+            go (pred count) ((i, j, c) : rs) cs+          Right hs -> do+            let cs' = zip [i..j] . map Text.decodeUtf16BE $ hs+            go (pred count) rs (cs <> Map.fromList cs') +  go n mempty mempty+ codeRangesParser :: Parser [(ByteString, ByteString)] codeRangesParser = do   n <- skipTillParser $ do     n <- P.decimal     P.skipSpace-    _ <- P.string "begincodespacerange"+    void $ P.string "begincodespacerange"     return n    replicateM n $ do     P.skipSpace-    _ <- P.char '<'-    i <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'+    i <- parseHex     P.skipSpace-    _ <- P.char '<'-    j <- P.takeTill (== '>') >>= fromHex-    _ <- P.char '>'+    j <- parseHex     return (i, j) +parseHex :: Parser ByteString+parseHex = do+  void $ P.char '<'+  res <- P.takeTill (== '>') >>= fromHex+  void $ P.char '>'+  return res++parseHexArray :: Parser [ByteString]+parseHexArray = do+  void $ P.char '['+  res <- P.many' $ do+    P.skipSpace+    parseHex+  P.skipSpace+  void $ P.char ']'+  return res++-- XXX: wtf?! fromHex :: Monad m => ByteString -> m ByteString fromHex hex = do   let (str, rest) = Base16.decode $ bsToLower hex@@ -152,7 +175,11 @@     fail $ "Can't decode hex" ++ show rest   return str   where-  bsToLower = BS.map $ fromIntegral . fromEnum . toLower . toEnum . fromIntegral+  bsToLower = BS.map $ fromIntegral+                     . fromEnum+                     . toLower+                     . toEnum+                     . fromIntegral  skipTillParser :: Parser a -> Parser a skipTillParser p = P.choice [
pdf-toolbox-content.cabal view
@@ -1,11 +1,11 @@ name:                pdf-toolbox-content-version:             0.0.3.1+version:             0.0.3.2 synopsis:            A collection of tools for processing PDF files license:             BSD3 license-file:        LICENSE author:              Yuras Shumovich maintainer:          Yuras Shumovich <shumovichy@gmail.com>-copyright:           Copyright (c) Yuras Shumovich 2013-2014+copyright:           Copyright (c) Yuras Shumovich 2013-2015 category:            PDF build-type:          Simple cabal-version:       >=1.8