packages feed

hpdft 0.4.6.3 → 0.4.6.4

raw patch · 5 files changed

+56/−3 lines, 5 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ PDF.ContentStream: normalizePdfNumber :: String -> String
+ PDF.ContentStream: parsePdfNumber :: String -> Double
+ PDF.Interpret: normalizePdfNumber :: String -> String
+ PDF.Interpret: parsePdfNumber :: String -> Double

Files

CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog +## 0.4.6.4 (2026-07-06)++### Fixed++- Content-stream number parsing no longer corrupts negative fractions with an omitted integer part (e.g. `-.24` in a `cm` matrix); the previous bug turned them into large integers, broke the CTM, and left geometry/tagged text extraction empty while legacy/TUI output still looked fine.+- Golden fixture `data/fixtures/negative-fraction-ctm.pdf` and unit tests for `normalizePdfNumber` / `parsePdfNumber` in both the geometry and legacy lexers.+ ## 0.4.6.3 (2026-07-06)  ### Added
hpdft.cabal view
@@ -1,6 +1,6 @@ cabal-version:       3.8 name:                hpdft-version:             0.4.6.3+version:             0.4.6.4 synopsis:            PDF parsing library and CLI for text, layout, diff, images, and forms description:     hpdft is a Haskell library and command-line tool for parsing PDF files.
src/PDF/ContentStream.hs view
@@ -3,6 +3,8 @@ module PDF.ContentStream         ( parseStream        , parseColorSpace+       , normalizePdfNumber+       , parsePdfNumber        ) where  import Data.Char (chr, ord)@@ -871,7 +873,7 @@ normalizePdfNumber s   | null s = s   | head s == '.' = '0' : s-  | length s >= 2 && head s == '-' && s !! 1 == '.' = '-' : '0' : drop 2 s+  | length s >= 2 && head s == '-' && s !! 1 == '.' = '-' : '0' : drop 1 s   | otherwise = s  parsePdfNumber :: String -> Double
src/PDF/Interpret.hs view
@@ -17,6 +17,8 @@   , bytesToCodes   , encodingUnicode   , unicodeBytesToCodes+  , normalizePdfNumber+  , parsePdfNumber   ) where  import PDF.Definition@@ -1023,7 +1025,7 @@ normalizePdfNumber s   | null s = s   | head s == '.' = '0' : s-  | length s >= 2 && head s == '-' && s !! 1 == '.' = '-' : '0' : drop 2 s+  | length s >= 2 && head s == '-' && s !! 1 == '.' = '-' : '0' : drop 1 s   | otherwise = s  parsePdfNumber :: String -> Double
test/Unit.hs view
@@ -12,6 +12,8 @@   , encodingUnicode   , unicodeBytesToCodes   )+import qualified PDF.Interpret as Interpret+import qualified PDF.ContentStream as ContentStream import PDF.Layout (LayoutOptions(..), defaultLayoutOptions, needsAozoraBar, aozoraRuby, layoutParagraphs, layoutParagraphsWith, layoutPageText, layoutDocument, sortLinesByReadingOrder, linesFromGlyphs, Line(..)) import PDF.Structure (StructElem(..), StructKid(..), structTree, logicalOrder) import PDF.Document (Document(..), openDocument)@@ -187,6 +189,7 @@           ++ taggedEndToEndResults           ++ textStreamResults           ++ cmapEncodingResults+          ++ normalizePdfNumberResults           ++ tuiScrollResults   let failures = [msg | Fail msg <- results]       passed = length results - length failures@@ -1376,4 +1379,43 @@       , assertBool "bytesToCodes JISmap 2-byte fixed"           (bytesToCodes jfi [0x46, 0x7C, 0x4B, 0x5C] == [0x467C, 0x4B5C])       ]++normalizePdfNumberResults :: [Result]+normalizePdfNumberResults =+  let cases =+        [ (".5", 0.5)+        , ("-.5", -0.5)+        , ("-.23999999", -0.23999999)+        , ("1.5", 1.5)+        , ("-1.5", -1.5)+        , ("5.", 5.0)+        ]+      abnormal =+        [ ""+        , "-"+        , "+"+        , "-.5."+        , "."+        , "-."+        ]+   in [ assertDoubleEq ("Interpret.parsePdfNumber " ++ s) n (Interpret.parsePdfNumber s)+      | (s, n) <- cases+      ]+      ++ [ assertDoubleEq ("ContentStream.parsePdfNumber " ++ s) n (ContentStream.parsePdfNumber s)+         | (s, n) <- cases+         ]+      ++ [ assertBool ("Interpret.parsePdfNumber abnormal " ++ show s)+             (Interpret.parsePdfNumber s `seq` True)+         | s <- abnormal+         ]+      ++ [ assertBool ("ContentStream.parsePdfNumber abnormal " ++ show s)+             (ContentStream.parsePdfNumber s `seq` True)+         | s <- abnormal+         ]+      ++ [ assertTextEq ("Interpret.normalizePdfNumber " ++ s) (T.pack expected) (T.pack (Interpret.normalizePdfNumber s))+         | (s, expected) <- [(".5", "0.5"), ("-.5", "-0.5"), ("-.23999999", "-0.23999999")]+         ]+      ++ [ assertTextEq ("ContentStream.normalizePdfNumber " ++ s) (T.pack expected) (T.pack (ContentStream.normalizePdfNumber s))+         | (s, expected) <- [(".5", "0.5"), ("-.5", "-0.5"), ("-.23999999", "-0.23999999")]+         ]