Commit Graph

153 Commits

Author SHA1 Message Date
Jeremy Singer-Vine fff846b073 Merge pull request #1041 from afriedman412/x_tolerance_ratio
Add `x_tolerance_ratio` param to `extract_text` and similar functions
2023-11-09 15:18:27 -05:00
Jeremy Singer-Vine 35ed9e0695 Merge pull request #963 from dhdaines/structure_tree
Support for PDF 1.3 logical structure
2023-11-09 15:08:09 -05:00
Jeremy Singer-Vine 0145647c58 Add x_tolerance_ratio test for extract_words(...) 2023-11-08 15:36:42 -05:00
Andy Friedman 1359fad7c0 adding x_tolerance_ratio functionality 2023-11-04 16:33:11 -04:00
Andy Friedman 9af84e2b5e Revert "linting"
This reverts commit c2564653e8.
2023-11-02 11:27:35 -04:00
Andy Friedman c2564653e8 linting 2023-11-01 16:13:56 -04:00
Andy Friedman 5a85ab7a0c add x_tolerance_ratio 2023-11-01 13:54:10 -04:00
Jeremy Singer-Vine 0bfffc2448 Fix Page.get_textmap caching for extra_attrs=[...]
... by preconverting list kwargs to tuples.
2023-10-27 10:53:17 -04:00
David Huggins-Daines ed707a7ec6 fix: respect use_text_flow in extract_text (fixes #982) 2023-09-06 15:51:50 -04:00
David Huggins-Daines 036044d92e fix: handle more MCR/OBJR madness 2023-09-05 23:47:23 -04:00
David Huggins-Daines 14f9a67c66 fix: complete coverage and fix handling of OBJR/MCR 2023-09-05 23:03:17 -04:00
David Huggins-Daines 8d485c38cd test: trivial synthetic pdf for completing structure coverage 2023-09-05 23:03:03 -04:00
David Huggins-Daines 183d5a840b feat: add --structure-text, like pdfinfo -struct-text (but better) 2023-08-19 10:00:28 -06:00
David Huggins-Daines 3c83366d9d feat: extract structure tree from pages or documents 2023-08-19 09:49:48 -06:00
David Huggins-Daines 142fc90cc5 Support for marked content section IDs (#961) 2023-08-19 11:29:21 -04:00
Jeremy Singer-Vine f6887b5b33 Add gs_path argument to .open(...) & .repair(...) 2023-08-06 17:24:00 -04:00
Jeremy Singer-Vine 30a52cb0ed Add PDF.path & fix .to_image() for zipped files
These are related changes, since the previous approach of using
`PDF.stream.name` to distinguish between on-path and filelike-object PDFs
doesn't work for zipped files (and possibly other filelike-objects that
have a `name` property).
2023-07-29 14:30:00 -04:00
Jeremy Singer-Vine 7af3d0fa96 Merge pull request #946 from dhdaines/iterable_geometry
Accept Iterable for geometry utils (fixes #945)
2023-07-28 14:46:16 -04:00
David Huggins-Daines 72c3a0efde fix: isort 2023-07-25 16:10:46 -04:00
David Huggins-Daines 53bee23e5a feat: accept Iterable for geometry utils.
Note: this removes the fragile-looking type manipulation in intersects_bbox as
making it work with iterables is very ugly and I am not convinced of its
usefulness
2023-07-24 10:15:34 -04:00
Jeremy Singer-Vine 7e2893106e Add antialias parameter to Page.to_image(...)
... and associated methods. Thanks to @cmdlineluser for flagging.

For details, see:
https://github.com/jsvine/pdfplumber/discussions/899#discussioncomment-6464765
2023-07-19 08:56:18 -04:00
Jeremy Singer-Vine b5c268d756 Fix PNG size tests for other platforms 2023-07-16 17:51:53 -04:00
Jeremy Singer-Vine db6ae97bfb Add pdfplumber.repair(...) and .open(repair=True)
This commit adds convenience methods to repair PDFs on the fly and/or to
write repaired PDFs to disk.

Currently, this does so via Ghostscript using the method we've asked
many users to try by following the instructions at
https://superuser.com/questions/278562/how-can-i-fix-repair-a-corrupted-pdf-file

Now, hopefully, this saves folks a few steps.
2023-07-16 17:07:42 -04:00
Jeremy Singer-Vine b0493732c4 Replace Wand with pypdfium2 for page.to_image(...)
This commit swaps out Wand (and its non-Python dependencies ImageMagick
and Ghostscript) for pypdfium2 for PageImage rendering. This has some
advantages:

- Less finicky: Wand often caused users problems, due to "MagickWand
  shared library not found" and "PolicyError: not authorized `PDF'"
  issues. By contrast, pypdfium2 seems (at least at first) to more
  self-contained and not require any system-tweaking.
- Faster: pypdfium2 appears to render images more quickly than Wand (see
  @cmdlineuser's tests in #899)
- More flexible: pypdfium2 appears to generate images with greater color
  depth; by default, pdfplumber quantizes those images so that they
  save/display compactly (in fact, with smaller file sizes than the
  previous code), this commit also adds parameters to retain all/more of
  the original, more detailed colors.

Thanks to @cmdlineuser in #899 for the suggestion.
2023-07-16 10:46:40 -04:00
Jeremy Singer-Vine 6d62054ffa Remove vestigial 'font' and 'name' properties 2023-07-14 12:01:28 -04:00
Jeremy Singer-Vine 97ca4b0bf3 Extract and handle patterns + (some) color spaces
Inspired by https://github.com/jsvine/pdfplumber/issues/828

The PDF reference allows for "colors" to be defined as a series of
numbers and/or (much less commonly) patterns.

(See p. 288 and section 4.6 here:
https://ghostscript.com/~robin/pdf_reference17.pdf)

This commit separates out the pattern component of colors into their own
attributes, `stroking_pattern` and `non_stroking_pattern` so that they
don't muddle the interpretation of standard colors' tuple-of-numbers
representation.

This commit also adds code that attempts to fetch the `ncs`/`scs` color
space of each object. Due to current limitations of pdfminer.six,
however, the only such color space immediately available is the `ncs`
(non-stroking color space) property of char objects.
2023-07-04 11:24:55 -04:00
Jeremy Singer-Vine 57d51bb5f4 Normalize color representation (#917)
This commit normalizes the type representation of `stroking_color` and
`non_stroking_color` values. Thanks to @dhdaines for pointing out this
inconsistency.

Previously, `pdfplumber` passed along `pdfminer.six`'s colors without
normalization. Due to quirks in `pdfminer.six`'s color handling, this
meant that those values could be floats, ints, lists, or tuples. This
commit normalizes all color values (when non-None) into n-tuples, where
(val,) represents grayscale colors, (val, val, val) represents RBG, and
(val, val, val, val) represents CMYK colors.

This should solve the consistency issue, although might cause breaking
changes to code that filters for non-tuple values — e.g., `[c for c in
page.chars if c == [1, 0 0]]`. Although breaking changes are unpleasant,
I think the tradeoff for longer-term consistency is worth it.
2023-07-03 22:59:05 -04:00
Jeremy Singer-Vine 0de6da97fd Fix bug for re-crops that use relative=True (#914)
When using relative=True for a re-crop, pdfplumber was passing the wrong
bounding box to the cropping function. This commit fixes that bug and
also refactors CroppedPage.__init__(...) for clarity and consistency's
sake.
2023-07-02 11:49:53 -04:00
Jeremy Singer-Vine 474f74c906 Add another test for use_text_flow 2023-07-01 18:41:58 -04:00
Jeremy Singer-Vine ae676aeacd Add PNG-length alternatives to tests 2023-04-20 06:10:42 -04:00
Jeremy Singer-Vine 86e935d681 By default, expand ligatures into their letters
Addresses issue #598
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine 6f6b465260 Add .curve_edges, use by default in table-detect.
Most of the groundwork was already there to add a PDF/Page.curve_edges
property. And, inspired, by
https://github.com/jsvine/pdfplumber/discussions/858 and related issues,
we now include 0/90/180/270-degree oriented curve segments into the
default table-detection strategy. As before, you can still switch to the
"lines_strict" to use only lines defined as such (rather than also using
rect and curve edges).
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine 4b373977be Add .extract_text_lines & related .search params
Inspired by https://github.com/jsvine/pdfplumber/discussions/852,
it turns out that .search(...) gets us most of the way, already.

Added a few params (`main_group`, `return_groups`, `return_chars`) to
.search(...) to enable this, which also make that method more generally
flexible.
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine ebb93eae15 Simplify char_begins_new_word
Calculating the bounding boxes of the words is, upon reflection and
testing, not necessary. Instead, all we need is the latest character in
the current word.
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine 8368954eaa Handle whitespace-only and empty search results
With regular expressions, patterns made up entirely of optional groups
(e.g., r"(dfsdgfwerw)?") can return match objects that are, effectively,
empty. These were being treated as real search results, and throwing
errors in the process. Now they're being treated as non-results.

Separately but relatedly, whitespace-only searches were throwing errors.
This was due to (a) how PDFs generally represent whitespace (implicitly,
rather than explicit space characters), and (b) how pdfplumber
internally represents those spaces while performing layout analysis.
This caused search results to have no explicit bounding box, throwing
errors. Now, similarly to handling empty search results, we handle
all-whitespace search results by considering them to be non-results.
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine 9441ff7628 Handle bytes-typed fontnames (fixes #461 + #842)
Came across this bit of code, which helps to solve some of the mystery
in issues #461 and #842:

https://git.ghostscript.com/?p=mupdf.git;a=blob;f=source/pdf/pdf-font.c;h=6322cedf2c26cfb312c0c0878d7aff97b4c7470e;hb=HEAD#l774

Now, for every char's fontname, we:

- Check whether its a `str` or `byte`
    - If the latter, we check whether it's one of the well-known codes from
      the link above
        - If so, we use that (preserving the part, if present, before
          the `+`)
        - If not, we just cast to str
2023-04-13 08:13:16 -04:00
Jeremy Singer-Vine 93f7dbd1a2 Add width & height kwargs to .to_image() #798 2023-02-13 18:49:18 -05:00
Jeremy Singer-Vine c4e1b294bb Allow *all* extract_text kwargs for tables
Any `text_`-prefixed table extraction setting now automatically gets
passed to `.extract_text(...)` via `table.extract(...)`.

This introduces one minor but breaking change, which is that
`keep_blank_chars` (previously, a valid table extraction setting) now
needs to be passed as `text_keep_blank_chars`.
2023-02-13 17:51:33 -05:00
Jeremy Singer-Vine d3662dec06 Mimic text layout better by padding right/bottom
Adds `layout_width` and `layout_height` to `utils.extract_text`, set to
page width and height by default on `page.extract_text`.
2023-02-13 17:38:40 -05:00
Jeremy Singer-Vine 3424b57612 Refactor text-extraction utilities 2023-02-07 17:06:59 -05:00
Jeremy Singer-Vine 216bedd00a Refactor handling of pts attribute
In doing so, deprecate the `curve_obj["points"]` attribute, and fix
`PageImage.draw_line(...)`'s handling of diagonal lines.
2023-02-03 14:27:36 -05:00
Jeremy Singer-Vine 8a0c12652c Restore "text" attr to .textboxhorizontal/etc.
Fix regression introduced in 9587cc7 / v0.6.2.
2022-11-22 12:24:10 -05:00
Jeremy Singer-Vine 1e976568d9 Reallow non-callable key_fn in .cluster_objects()
Resolves https://github.com/jsvine/pdfplumber/issues/691

Thanks to @jfuruness for flagging.
2022-10-01 09:35:42 -04:00
Jeremy Singer-Vine 3ab1cc4377 Add utils/Page.outside_bbox(...)
See https://github.com/jsvine/pdfplumber/issues/369
2022-07-20 17:10:35 -04:00
Jeremy Singer-Vine b6ff9e8761 Add note to PIL.Image.DecompressionBombError msgs
See https://github.com/jsvine/pdfplumber/issues/413
2022-07-20 15:18:25 -04:00
Jeremy Singer-Vine 71ad60f891 Add strict=True/False to .crop/within_bbox(...)
See https://github.com/jsvine/pdfplumber/issues/421
2022-07-20 15:16:03 -04:00
Jeremy Singer-Vine b98dd7caff Quick fix for image transparency issue 2022-07-18 10:35:35 -04:00
Jeremy Singer-Vine 1a07638ff1 Update test for alt. PNG repr size 2022-07-17 22:58:54 -04:00
Jeremy Singer-Vine 1cd1f9aea9 Change .to_image(...)'s approach ...
... preferring to composite with a white background instead of removing
the alpha channel. This seems to more reliably produce high-quality
conversions (easier to read, fewer conversion artifacts) than either the
prior or other previous approaches.
2022-07-17 22:45:59 -04:00
Jeremy Singer-Vine 35fd4298bc Add test_extract_text_punctuation 2022-07-17 12:51:07 -04:00