Commit Graph

101 Commits

Author SHA1 Message Date
Jeremy Singer-Vine 063e2edd75 Fix #659 (PageImage.debug_tablefinder())
Thanks to @rneumann7 for flagging!
2022-05-31 15:45:40 -04:00
Jeremy Singer-Vine ad3df11954 Fix .extract_text(layout=True) for text-less pages
Fixes https://github.com/jsvine/pdfplumber/issues/658

Thanks to @ethanscorey for flagging!
2022-05-27 14:41:57 -04:00
Jeremy Singer-Vine 4deac2522d Add --include/exclude-attrs to CLI & serialization
For `Serializer`, `.to_json(...)` and `.to_csv(...)`, the params are
`include_attrs`, and `exclude_attrs`.
2022-05-14 12:07:44 -04:00
Jeremy Singer-Vine 826e927b7f Remove redundant loading in test_basics.py 2022-05-13 16:42:23 -04:00
Jeremy Singer-Vine 24f3532813 Remove utils.collate_chars(...)
This was the previous name (and then alias) for utils.extract_text(...),
and hasn't been featured in the documentation in a long time.
2022-05-13 16:10:13 -04:00
Jeremy Singer-Vine 58b1ab1b0a Add (experimental) page.search(...) feature
First proposed here: https://github.com/jsvine/pdfplumber/issues/201

Adding this feature involved refactoring and re-engineering a good chunk
of the text-layout-extraction code. As part of that, this commit
introduces two new classes, in utils.py: LayoutEngine and TextLayout.
They should be considered provisional, and may change name/approach in
the future.
2022-05-13 16:04:03 -04:00
Jeremy Singer-Vine ae6f99e691 Add char['matrix'], ctm submodule, and CTM class 2022-05-10 18:09:44 -04:00
Jeremy Singer-Vine 1b7458a795 Tweak test_display.py:test__repr_png_ 2022-05-06 13:54:58 -04:00
Jeremy Singer-Vine feb9d082d7 Add final bits of test coverage
Added weak tests for a couple of hard-to-test visual debugging methods
in display.py.

Also marked an exception-handling block in pdf.py as `pragma: nocover`
because we don't yet have a PDF to test it with, but the logic there is
simple and straightforward.
2022-05-06 10:19:48 -04:00
Jeremy Singer-Vine 9587cc7d22 Add type annotations and refactor accordingly
A fairly large commit, adding type annotations/hints to the entire
library, and refactoring the library accordingly.

Most of the refactoring changes should have no practical effect on
usage, but several others are notable:

- Added `TableSettings` class, a behind-the-scenes handler for managing
  and validating table-extraction settings.
- Renamed the positional argument to `.to_csv(...)` and `.to_json(...)`
  from `types` to `object_types`.
- Tweaked the output of `.to_json(...)` so that, if an object type is
  not present for a given page, it has no key in the page's object
  representation.
- Removed `utils.filter_objects(...)` and move the functionality to
  within the `FilteredPage.objects` property calculation, the only part
  of the library that used it.
- Removed code that sets `pdfminer.pdftypes.STRICT = True` and
  `pdfminer.pdfinterp.STRICT = True`, since that [has now been the
  default for a
  while](https://github.com/pdfminer/pdfminer.six/commit/9439a3a31a347836aad1c1226168156125d9505f).
2022-05-06 09:43:50 -04:00
Jeremy Singer-Vine 3db4bb0614 Tweak test_laparams.py for pdfminer.six==20220319 2022-04-23 16:46:10 -04:00
Jeremy Singer-Vine b21ae179fe Add tests for PR 581
We cannot test whether the file closed successfully, but we can test
that the code reaches that branch of the logic.
2022-01-13 23:21:43 -05:00
Jeremy Singer-Vine 54cbbc5321 Remove deprecated .load method 2021-12-16 22:22:54 -05:00
Jeremy Singer-Vine d72b879665 Enforce import order via isort 2021-12-16 22:22:54 -05:00
Jeremy Singer-Vine aa2d594d3b Raise error if certain table-ex. settings negative 2021-12-03 17:46:59 -05:00
Jeremy Singer-Vine cbb34ce28b Add join_x/y_tolerance to table extract. settings
Now all tolerance settings have x/y versions as well.

This commit also changes `table.merge_edges(...)` behavior when
`join_tolerance` (and `x`/`y` variants) `<= 0`, so that joining is
attempted regardless, to handle cases of overlapping lines.
2021-12-01 23:30:12 -05:00
Jeremy Singer-Vine 7ed4742f8f Add snap_x/y_tolerance to table-extract. settings
Based largely on @dustindall's work in PR #51, adapted to current code.

Also resolves issue #475.
2021-12-01 09:51:20 -05:00
Jeremy Singer-Vine e13e6ce640 Merge pull request #532 from jsvine/feature/layout
Add experimental .extract_text(layout=True)
2021-11-28 13:30:23 -08:00
samkit-jain 608db0225c Fix bug that crashed table extraction when null value provided for (text|intersection)_(x|y)_tolerance keys
Fixes #539
Thanks to @yoavxyoav for reporting
2021-11-22 19:53:03 +05:30
Jeremy Singer-Vine d235d4bbc4 Add experimental .extract_text(layout=True)
See the docstring in utils.words_to_layout for details on the
implementation.

Addresses issue #10 and related issues.
2021-11-02 23:12:17 -04:00
Jeremy Singer-Vine c915a00d09 Merge pull request #520 from jsvine/core/undecimalize
Remove decimalizing (but let CLI adjust precision)
2021-11-02 23:03:02 -04:00
Jeremy Singer-Vine 87b947f8f6 Remove decimalizing (but let CLI adjust precision)
Per discussion at https://github.com/jsvine/pdfplumber/discussions/346
and input from @ramcdona, this commit changes pdfplumber's behavior
regarding floating point numbers. Specifically, it removes all
conversion of floats to Decimal objects. This brings several advantages:

- Increased precision (where applicable)
- Decreased code complexity
- Increased performance (~10% speedup on test suite)
- Increased fidelity to `pdfminer.six` output

These seem to outweigh the disadvantages:

- Some tests break (but have been easily fixed) due to increased
  precision and/or floating point arithmetic artifacts
- Some users' scripts may also break, if they depend on strict equality
  testing, though these *should* also be easily fixable

Because some form of automatic rounding may still be desirable for the
pdfplumber CLI utility, the conversion methods (.to_csv, .to_json) have
been adjusted to accept a `precision` argument.
2021-10-19 21:51:33 -04:00
Jeremy Singer-Vine df98f9cf44 Handle utf-16-encoded annotations (#463)
Thanks to @tungph for the fix proposal.
2021-10-15 09:34:39 -04:00
Jeremy Singer-Vine 4b61c38d3c Upgrade pdfminer.six from 20200517 to 20211012
See pdfminer.six's changelog for details:
https://github.com/pdfminer/pdfminer.six/blob/develop/CHANGELOG.md

... but a key difference is an improvement in how it assigns `line`,
`rect`, and `curve` objects. (Diagonal two-point lines, for instance,
are now `line` objects instead of `curve` objects.)

As a result, this commit also adjusts some of the tests, where the
pre-20211012 versions had been incorrectly assigning lines as `LTCurve`
objects.
2021-10-15 08:53:39 -04:00
bobluda 6cea72da22 Add test and pdf for mixed strategy table extraction 2021-07-11 23:59:27 +02:00
Jeremy Singer-Vine 83dd31f7dc Add test for extract_table(s) re. text extraction 2021-05-08 17:42:12 -04:00
Jeremy Singer-Vine 237742039d Add --laparams to CLI (and make related tweaks)
This commit adds an `--laparams` flag to the pdfplumber CLI, giving it
more feature parity with the core library. To do so, it makes some
internal changes to `convert.py`, including changing the list of objects
to convert from *a predefined default list* to *all types extracted*.
2021-04-08 09:43:33 -04:00
Jeremy Singer-Vine 13b20cec79 Even if laparams is set, don't extract anno objs
pdfminer.six's `LTAnno` objects are not PDF annotations (which we
already provide access to via `.annots`, regardless of whether
`laparams` is set), but rather layout annotations. Per pdfminer.six
codebase:

> Note that, while a LTChar object has actual boundaries, LTAnno objects
> does not, as these are "virtual" characters, inserted by a layout
> analyzer according to the relationship between two characters (e.g. a
> space).

Because they have no boundaries, they cause problems for pdfplumber,
which expects bounding-box coordinates for all objects. See, e.g.,
issue #383, which this commit should fix.
2021-03-19 19:12:52 -04:00
Alexander Regueiro cbfb60640a Added test for issue #381 2021-03-19 18:48:25 +00:00
Jeremy Singer-Vine 7e2dc7cf75 Re-add textboxhorizontal/etc. when laparams (#359)
This commit reinstates access to higher-level layout objects (such as
`textboxhorizontal`) when `laparams` is passed to
`pdfplumber.open(...)`. Had been removed in `0.5.24` via 1f87898.

Also adds a test for this behavior.
2021-02-26 18:53:11 -05:00
Samkit Jain a17c5a72b6 Sort tables extracted on a page by their top position
Fixes #336
h/t @gqh1995 for reporting
2021-01-21 20:05:29 +05:30
Jeremy Singer-Vine b4b0282730 Make tests flake8-compatible 2020-12-16 22:29:51 -05:00
Jeremy Singer-Vine 5c62be2e16 Format all tests with psf/black 2020-12-16 22:19:17 -05:00
Samkit Jain 02656b29c8 Update tests to bump up test coverage 2020-12-08 22:48:37 +05:30
Samkit Jain 4ccf8cff67 Resolve lint issues and remove unused imports 2020-11-29 16:29:14 +05:30
Samkit Jain 2d9415cdd0 Recursively parse metadata values to handle nested PDFObjRef objects
Fixes #316
2020-11-29 15:41:01 +05:30
Samkit Jain 9f0a1ad7cd Treat invalid/unparseable metadata values as warnings
Certain invalid values if parseable don't throw a warning and only unparseable (always invalid) throw
2020-11-26 21:58:49 +05:30
Jeremy Singer-Vine 408605f01a Prevent .open(...) from closing ext. file objects
Fixes #312. Now only closes pdfplumber-created streams, not file objects
passed to pdfplumber.open(...).
2020-11-12 23:02:08 -05:00
Samkit Jain 3030765036 Add test for issue #297
h/t @prgx-csmith01 for providing the PDF
2020-10-30 12:47:27 +05:30
Jeremy Singer-Vine f665863daf Fix test_table.py ValueError tests
They were erroring on wrong aspect, because PDF object was being passed
instead of Page object.
2020-10-20 09:42:23 -04:00
Jeremy Singer-Vine bc407790f1 Decimalize "simple" explicit_h/v_lines descs (#290)
... in TableFinder. This way, you can pass ints/floats without
pre-converting them to Decimal objects.
2020-10-20 09:41:49 -04:00
Samkit Jain b132d45db5 Fix bug in dedup_chars() in which ._objects was accessed before assignment
Fixes #293
2020-10-20 17:02:07 +05:30
Jeremy Singer-Vine 04fd56ac40 Add utils/page.dedupe_chars(...) (#71 + #280)
h/t @xv44586 for the initial inspiration 👍

These new methods return a version of the chars/page with duplicate
chars — those sharing the same text, fontname, size, and positioning
(within `tolerance` x/y) as other characters — removed.
2020-10-03 12:06:48 -04:00
Jeremy Singer-Vine d6309a9b47 Add "direction" attribute to extracted words
"direction" == 1 when upright words go LTR and non-upright words go TTB,
and -1 when the opposite is true. This attribute should help in reusing
the results of `.extract_words` in other functions, so that the user
knows how the extracted word corresponds to the word's layout on the
page.
2020-08-30 22:30:14 -04:00
Jeremy Singer-Vine 84f91811df Rework .extract_words and add use_text_flow param
Taking @samkit-jain's smart question about sort-order into account, this
commit reworks `.extract_words`, making the sorting more explicit, and
adding an option to *not* sort, via `use_text_flow=True`, which follows
the original PDF's text flow, rather than presorting all characters top-down,
left-right.

To do so required rethinking the word-delineation logic,
which in turn motivated a shift toward a more object-oriented approach
(especially to keep track of settings without passing them from function
to function). Now `.extract_text`'s logic is encapsulated in a new class,
`TextExtractor`.
2020-08-30 18:36:03 -04:00
Jeremy Singer-Vine c8b200ee7c Refactor .extract_words and allow attrib-grouping
This commit refactors and hopefully makes clearer the logic in
utils.extract_words. It also adds a new parameter, `extra_attrs`, which
allows the user to pass a list of attributes on which to group all
characters.

For instance, passing `extra_attrs=["fontname", "size"]` will not allow
characters with different font names or sizes to become part of the same
word. As a benefit, those resulting word dicts will contain `"fontname"`
and `"size"` attributes — providing a long-requested feature (cf. issue
2020-08-29 16:05:31 -04:00
Jeremy Singer-Vine 6233bbd6ed Speed up test_ca_warn_report:test_objects
The same goals can be acheived by just testing the first page, instead
of the entire PDF, trimming approximately 20% off the total test suite's
execution time, although YMMV.
2020-08-29 13:35:47 -04:00
Jeremy Singer-Vine 917467a10c Remove test_issues.py:test_pr_77 to speed up tests
The test, responding to PR #77, was particularly slow and the
accompanying PDF somewhat large. Now that the fixes to the issues
identified in the PR are fairly tightly integrated into pdfplumber, we
can remove the tests with reasonable confidence, speeding up development
time.
2020-08-29 13:31:42 -04:00
Jeremy Singer-Vine 8e74cb9553 Remove reference/access to .figures
Per diagram and explanation in [1], LTFigure is just a layout-estimated
collation of LTCurve objects. For consistency with the rest of
pdfplumber, removing it from the list of parsed/accessible objects,
although we still do process the curves within each figure.

[1] https://github.com/pdfminer/pdfminer.six/blob/develop/docs/source/topic/converting_pdf_to_text.rst
2020-08-26 08:49:30 -04:00
Jeremy Singer-Vine a5e7d7fa52 Remove pandas from dev requirements and tests
Results in needing one more # pragma: nocover statement, but on a
simple line of code. See PR #253 for details and motivation.
2020-08-15 12:03:34 -04:00