All notable changes to this project will be documented in this file. The format is based on Keep a Changelog.
- Change the (still experimental)
Page/utils.extract_text(layout=True)approach so that it pads, to the degree necessary, the ends of lines with spaces and the end of the text with blank lines to acheive better mimicry of page layout. (d3662de) - Refactor handling of
ptsattribute and, in doing so, deprecate thecurve_obj["points"]attribute, and fixPageImage.draw_line(...)'s handling of diagonal lines. (216bedd) - Breaking change: In
Page.extract_table[s](...),keep_blank_charsmust now be passed astext_keep_blank_chars, for consistency's sake. (c4e1b29)
- Add
Page.extract_table[s](...)support for allPage.extract_text(...)keyword arguments. (c4e1b29) - Add
heightandwidthkeyword arguemnts toPage.to_image(...). (#798 + 93f7dbd) - Add
layout_width,layout_width_chars,layout_height, andlayout_width_charsparameters toPage/utils.extract_text(layout=True). (d3662de) - Add CITATION.cff. (#755) [h/t @joaoccruz]
- Fix simple edge-case for when page rotation is (incorrectly) set to
None. (#811) [h/t @toshi1127]
- Convert
utils.pyintoutils/submodules. Retains same interface, just an improvement in organization. (6351d97) - Fix typing hints to include io.BytesIO. (d4107f6) [h/t @conitrade-as]
- Refactor text-extraction utilities, paving way for better consistency across various entrypoints to text extraction (e.g., via
utils.extract_text(...), viaPage.extract_text(...), viaPage.extract_table(...)). (3424b57)
- Bump pinned
pdfminer.sixversion to20221105. (e63a038)
- Restore
textattribute to.textboxhorizontal/etc., regression introduced in9587cc7/v0.6.2. (8a0c126) - Fix
lru_cacheusage, which are discouraged for class methods due to garbage-collection issues. (e3142a0)
- Upgrade
nbexecdevelopment requirement from0.1.0to0.2.0. (30dac25)
- Fixed issue where
py.typedfile was not included in PyPi distribution. (#698 + #703 + 6908487) [h/t @jhonatan-lopes] - Reinstated the ability to call
utils.cluster_objects(...)with any hashable value (str,int,tuple, etc.) as thekey_fnparameter, reverting breaking change in 58b1ab1. (#691 + 1e97656) [h/t @jfuruness]
- Add
utils.outside_bbox(...)andPage.outside_bbox(...)method, which are the inverse ofutils.within_bbox(...)andPage.within_bbox(...). (#369 + 3ab1cc4) - Add
strict=True/Falseparameter toPage.crop(...),Page.within_bbox(...), andPage.outside_bbox(...); default isTrue, whileFalsebypasses thetest_proposed_bbox(...)check. (#421 + 71ad60f) - Add more guidance to exception when
.to_image(...)raisesPIL.Image.DecompressionBombError. (#413 + b6ff9e8)
- Fix
PageImageconversions for PDFs withcmykcolorspaces; convert them torgbearlier in the process. (28330da)
- Quick fix for transparency issue in visual debugging mode. (b98dd7c)
- Add
split_at_punctuationparameter to.extract_words(...)and.extract_text(...). (#682) [h/t @lolipopshock] - Add README.md link to @hbh112233abc's Chinese translation of README.md. (#674)
- Change
.to_image(...)'s approach, preferring to composite with a white background instead of removing the alpha channel. (1cd1f9a)
- Fix bug in
LayoutEngine.calculate(...)when processing char objects with len>1 representations, such as ligatures. (#683)
- Fix bug when calling
PageImage.debug_tablefinder()(i.e., with no parameters). (#659 + 063e2ed) [h/t @rneumann7]
- Add
Makefiletarget forexamples, as well as dev requirements to support re-running the example notebooks automatically. (ef065a7)
- Add
"matrix"property tocharobjects, representing the current transformation matrix. (ae6f99e) - Add
pdfplumber.ctmsubmodule with classCTM, to calculate scale, skew, and translation of a current transformation matrix obtained from achar's"matrix"property. (ae6f99e) - Add
page.search(...), an experimental feature that allows you to search a page's text via regular expressions and non-regex strings, returning the text, any regex matches, the bounding box coordinates, and the char objects themselves. (#201 + 58b1ab1) - Add
--include-attrs/--exclude-attrsto CLI (and corresponding params to.to_json(...),.to_csv(...), andSerializer. (4deac25) - Add
py.typedfor PEP561 compatibility and detection of typing hints by mypy. (ca795d1) [h/t @jhonatan-lopes]
- Bump pinned
pdfminer.sixversion to20220524. (486cea8)
- Remove
utils.collate_chars(...), the old name (and then alias) forutils.extract_text(...). (24f3532) - Remove
utils._itemgetter(...), an internal-use method previously used byutils.cluster_objects(...). (58b1ab1)
- Fix
IndexErrorbug for.extract_text(layout=True)on pages without text. (#658 + ad3df11) [h/t @ethanscorey]
- Add type annotations, and refactor parts of the library accordingly. (9587cc7)
- Add enforcement of type annotations via
mypy --strict. (cdfdb87) - Add final bits of test coverage. (feb9d08)
- Add
TableSettingsclass, a behind-the-scenes handler for managing and validating table-extraction settings. (9587cc7)
- Rename the positional argument to
.to_csv(...)and.to_json(...)fromtypestoobject_types. (9587cc7) - Tweak 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. (9587cc7)
- Remove
utils.filter_objects(...)and move the functionality to within theFilteredPage.objectsproperty calculation, the only part of the library that used it. (9587cc7) - Remove code that sets
pdfminer.pdftypes.STRICT = Trueandpdfminer.pdfinterp.STRICT = True, since that has now been the default for a while. (9587cc7)
- Bump pinned
pdfminer.sixversion to20220319. (e434ed0) - Bump minimum
Pillowversion to>=9.1. (d88eff1) - Drop support for Python 3.6 (EOL Dec. 2021) (a32473e)
- If
pdfplumber.open(...)opens a file but apdfminer.pdfparser.PSExceptionis raised during the process,pdfplumbernow makes sure to close that file. (#581 + (#578) [h/t @johnhuge] - Fix incompatibility with
Pillow>=9.1. (#637)
- Add
.extract_text(layout=True), an experimental feature which attempts to mimic the structural layout of the text on the page. (#10) - Add
utils.merge_bboxes(bboxes), which returns the smallest bounding box that contains all bounding boxes in thebboxesargument. (f8d5e70) - Add
--precisionargument to CLI (#520) - Add
snap_x_toleranceandsnap_y_toleranceto table extraction settings. (#51 + #475) [h/t @dustindall] - Add
join_x_toleranceandjoin_y_toleranceto table extraction settings. (cbb34ce)
- Upgrade
pdfminer.sixfrom20200517to20211012; see that library's changelog for details, but a key difference is an improvement in how it assignsline,rect, andcurveobjects. (Diagonal two-point lines, for instance, are nowlineobjects instead ofcurveobjects.) (#515) - Remove Decimal-ization of parsed object attributes, which are now represented with as much precision as is returned by
pdfminer.six(#346 + #520) .extract_text(...)returns""instead ofNonewhen character list is empty. (#482 + cb9900b) [h/t @tungph].extract_words(...)now includesdoctopamong the attributes it returns for each word. (66fef89)- Change behavior of horizontal
text_strategy, so that it uses the top and bottom of every word, not just the top of every word and the bottom of the last. (#467 + #466 + #265) [h/t @bobluda + @samkit-jain] - Change
table.merge_edges(...)behavior whenjoin_tolerance(andx/yvariants)<= 0, so that joining is attempted regardless, to handle cases of overlapping lines. (cbb34ce) - Raise error if certain table-extraction settings are negative. (aa2d594)
- Fix slowdown in
.extract_words(...)/WordExtractor.iter_chars_to_words(...)on very long words, caused by repeatedly re-calculating bounding box. (#483) - Handle
UnicodeDecodeErrorwhen trying to decode utf-16-encoded annotations (#463) [h/t @tungph] - Fix crash when extracting tables with null values in
(text|intersection)_(x|y)_tolerancesettings. (#539) [h/t @yoavxyoav]
- Remove
pdfplumber.load(...)method, which has been deprecated since0.5.23(54cbbc5)
- Add
CONTRIBUTING.md(#428) - Enforce import order via
isort(d72b879) - Update Pillow and Wand versions in
requirements.txt(cae6924) - Update all dependency versions in
requirements-dev.txt(2f7e7ee)
- Add
--laparamsflag to CLI. (#407)
- Change
.convert_csv(...)to order objects first by page number, rather than object type. (#407) - Change
.convert_csv(...),.convert_json(...), and CLI so that, by default, they returning all available object types, rather than those in a predefined default list. (#407)
- Fix
.extract_text(...)so that it can accept generator objects as its main parameter. (#385) [h/t @alexreg] - Fix page-parsing so that
LTAnnoobjects (which have no bounding-box coordinates) are not extracted. (Was only an issue when settinglaparams.) (#388) - Fix
Page.extract_table(...)so that it honors text tolerance settings (#415) [h/t @trifling]
- Fix regression (introduced in
0.5.26/b1849f4) in closing files opened byPDF.open - Reinstate access to higher-level layout objects (such as
textboxhorizontal) whenlaparamsis passed topdfplumber.open(...). Had been removed in0.5.24via 1f87898. (#359 + #364)
- Add a
python setup.py build sdisttest to main GitHub action. (#365)
- Add
Page.close/__enter__/__exit__methods, by generalizing that behavior through theContainerclass (b1849f4)
- Change handling of floating point numbers; no longer convert them to
Decimalobjects and do not round them - Change
TableFinderto return tables in order of topmost-and-then-leftmost, rather than leftmost-and-then-topmost (#336) - Change
Page.to_image()'s handling of alpha layer, to remove aliasing artifacts (#340) [h/t @arlyon]
- Enforce
psf/blackandflake8ontests/(#327
- Add new boolean argument
strict_metadata(defaultFalse) topdfplumber.open(...)method for handling metadata resolution failures (f2c510d)
- Fix metadata extraction to handle integer/floating-point values (cb32478) (#297)
- Fix metadata extraction to handle nested metadata values (2d9415) (#316)
- Explicitly load text as utf-8 in
setup.py(7854328) (#304) - Fix
pdfplumber.open(...)so that it does not close file objects passed to it (408605f) (#312)
- Added
extra_attrs=[...]parameter to.extract_text(...)(c8b200e) (#28) - Added
utils/page.dedupe_chars(...)(04fd56a + b132d45) (#71)
- Change character attribute
uprightfrominttobool(per originalpdfminer.sixrepresentation) (1f87898) - Remove access and reference to
Container.figures, given that they are not fundamental objects (8e74cb9)
- Decimalize "simple"
explicit_horizontal_lines/explicit_vertical_linesdescs passed toTableFindermethods (bc40779) (#290)
- Refactor/simplify
Page.process_objects(1f87898),utils.extract_words(c8b200e), andconvert.serialize(a74d3bc) - Remove
test_issues.py:test_pr_77(917467a) and narrowtest_ca_warn_report:test_objects(6233bbd) to speed up tests
- Add
utils.resolve(non-recursive .resolve_all) (7a90630) - Add
page.annotsandpage.hyperlinks, replacing non-functionalpage.annos, and mirroring pdfminer's language ("annot" vs. "anno"). (aa03961) - Add
page/pdf.to_jsonandpage/pdf.to_csv(cbc91c6) - Add
relative=True/Falseparameter to.cropand.within_bbox; those methods also now raise exceptions for invalid and out-of-page bounding boxes. (047ad34) [h/t @samkit-jain]
- Remove
pdfminer.from_pathandpdfminer.loadas deprecated; nowpdfminer.openis the canonical way to load a PDF. (00e789b) - Simplify the logic in "text" table-finding strategies; in edge cases, may result in changes to results. (d224202)
- Drop support for Python 3.5 (baf1033)
- Fix
.extract_words, which had been returning incorrect results whenhorizontal_ltr = False(d16aa13) - Fix
utils.resize_object, which had been failing in various permutations (d16aa13) - Fix
lines_stricttable-finding strategy, which a typo had prevented from being usable (f0c9b85) - Fix
utils.resolve_allto guard against two known sources of infinite recursion (cbc91c6)
- Rename default branch to "stable," to clarify its purpose
- Reformat code with psf/black (1258e09)
- Add code linting via psf/black and flake8 (1258e09)
- Switch from nosetests to pytest (1ac16dd)
- Switch from pipenv to standard requirements.txt + python -m venv (48eaa51)
- Add GitHub action for tests + codecov (b148fd1)
- Add Makefile for building development virtual environment and running tests (4c69c58)
- Add badges to README.md (9e42dc3)
- Add Trove classifiers for Python versions to setup.py (6946e8d)
- Add MANIFEST.in (eafc15c)
- Add GitHub issue templates (c4156d6)
- Remove
pandasfrom dev requirements and tests (a5e7d7f)
- Upgraded
pdfminer.sixrequirement to==20200517(cddbff7) [h/t @youngquan]
- Add support for
non_stroking_colorattribute oncharobjects (0254da3) [h/t @idan-david]
- Fix
Page.extract_table(...)to returnNoneinstead of crashing when no table is found (d64afa8) [h/t @stucka]
- Fix
.get_page_imageto prefer paths over streams, when possible (ab957de) [h/t @ubmarco] - Local-fix pdfminer.six's
.resolve_allto handle tuples and simplify (85f422d)
- Remove support for Python 2 and Python <3.3
- Add
utils.decimalizeperformance improvement (830d117) [h/t @ubmarco]
- Fix un-referenced method when using "text" table-finding strategy (2a0c4a2)
- Add missing object type
rect_edgetoobj_to_edges()(0edc6bf)
- Allow
rectandcurveobjects also to be passed to "explicit_..._lines" setting when table-finding. (And disallow other types of dicts to be passed.)
- Fix
utils.extract_textbug introduced in prior version
- Fix and simplify obj-in-bbox logic (see commit 25672961)
- Improve/fix the way
utils.extract_texthandles vertical text (see commit 8a5d858b) [h/t @dwalton76] - Have
Page.to_imageuse bytes stream instead of file path (Issue #124 / PR #179) [h/t @cheungpat] - Fix issue #176, in which
Page.extract_tablesdid not pass kwargs toTable.extract[h/t @jsfenfen]
- Prevent custom LAParams from raising exception (Issue #168 / PR #169) [h/t @frascuchon]
- Add
sixas explicit dependency (for now)
- Upgrade
pdfminer.sixrequirement to==20200104 - Upgrade
pillowrequirement>=7.0.0 - Remove Python 2.7 and 3.4 from
toxtests
- Fix sorting bug in
page.extract_table() - Fix support for password-protected PDFs (PR #138)
- Fixed PDF object resolution for rotation (PR #136)
cdecimalsupport for Python 2- Support for password-protected PDFs
- Caching for
.decimalize()method
- Upgrade to
pdfminer.six==20181108 - Make whitespace checking more robust (PR #88)
- Fix issue #75 (
.to_image()custom arguments) - Fix issue raised in PR #77 (PDFObjRef resolution), and general class of problems
- Fix issue #90, and general class of problems, by explicitly typecasting each kind of PDF Object
- Fix bug in which, when calling get_page_image(...), the alpha channel could make the whole page black out.
- Fix issue #67, in which bool-type metadata were handled incorrectly
- Fix issue #53, in which non-decimalize-able (non_)stroking_color properties were raising errors.
.travis.yml, but failing on.to_image()
- Move from defunct
pycryptotopycryptodome - Update
pdfminer.sixto20170720
- Fix issue #41, in which PDF-object-referenced cropboxes/mediaboxes weren't being fully resolved.
- Access to
__version__from main namespace
- Fix issue #33, by checking
decode_text's argument type
- Pin
pdfminer.sixto version20151013(for now), fixing incompatibility
- Allow
import pdfplumbereven if ImageMagick not installed.
- Access to
curvepoints. (E.g.,page.curves[0]["points"].) - Ability for
.draw_lineto drawcurvepoints.
- Disaggregated "min_words_vertical" (default: 3) and "min_words_horizontal" (default: 1), removing "text_word_threshold".
- Internally, made
utils.decimalizea bit more robust; now throws errors on non-decimalizable items. - Now explicitly ignoring some (obscure)
pdfminerobject attributes. - Raw input for
.draw_linefrom a bounding box to((x, y), (x, y)), for consistency withcurve["points"]and withPillow's underlying method.
- Fixed typo bug when
.rect_edgesis called before.edges
- Quick-draw
PageImagemethods:.draw_vline,.draw_vlines,.draw_hline, and.draw_hlines. - Boolean parameter
keep_blank_charsfor.extract_words(...)andTableFindersettings.
- Increased default
text_toleranceandintersection_toleranceTableFinder values from 1 to 3.
- Properly handle conversion of PDFs with transparency to
pillowimages. - Properly handle
pandasDataFrames as inputs to multi-draw commands (e.g.,PageImage.draw_rects(...)).
- Visual debugging features, via
Page.to_image(...)andPageImage. (Introduceswandandpillowas package requirements.) - More powerful options for extracting data from tables. See changes below.
- Entirely overhaul the table-extraction methods. Now based on Anssi Nurminen's master's thesis.
- Disentangle
.cropfrom.intersects_bboxand.within_bbox. - Change default
x_toleranceandy_tolerancefor word extraction from5to3
- Fix bug stemming from non-decimalized page heights. [h/t @jsfenfen]
- Provide access to
Page.page_number
- Use
.page_numberinstead of.page_idas primary identifier. [h/t @jsfenfen] - Change default
x_toleranceandy_tolerancefor word extraction from0to5
- Provide proper support for rotated pages
- Fix bug stemming from when metadata includes a PostScript literal. [h/t @boblannon]
Whoops.
- When extracting table cells, use chars' midpoints instead of top-points.
- Fix find_gutters — should ignore
" "chars