diff --git a/pdfplumber/container.py b/pdfplumber/container.py index ca5a92c..a626084 100644 --- a/pdfplumber/container.py +++ b/pdfplumber/container.py @@ -112,6 +112,7 @@ class Container(object): precision: Optional[int] = None, indent: Optional[int] = None, ) -> Optional[str]: + data = self.to_dict(object_types) serialized = Serializer( diff --git a/pdfplumber/convert.py b/pdfplumber/convert.py index 0e4e54f..5c285d0 100644 --- a/pdfplumber/convert.py +++ b/pdfplumber/convert.py @@ -66,6 +66,7 @@ class Serializer: include_attrs: Optional[List[str]] = None, exclude_attrs: Optional[List[str]] = None, ): + self.precision = precision self.attr_filter = get_attr_filter( include_attrs=include_attrs, exclude_attrs=exclude_attrs diff --git a/pdfplumber/display.py b/pdfplumber/display.py index 15dd3d6..f8caa5c 100644 --- a/pdfplumber/display.py +++ b/pdfplumber/display.py @@ -41,6 +41,7 @@ def get_page_image( password: Optional[str], antialias: bool = False, ) -> PIL.Image.Image: + src: Union[pathlib.Path, BufferedReader, BytesIO] # If we are working with a file object saved to disk @@ -356,6 +357,7 @@ class PageImage: x_tolerance: T_num = utils.DEFAULT_X_TOLERANCE, y_tolerance: T_num = utils.DEFAULT_Y_TOLERANCE, ) -> "PageImage": + words = self.page.extract_words( x_tolerance=x_tolerance, y_tolerance=y_tolerance ) @@ -368,6 +370,7 @@ class PageImage: fill: T_color = (255, 0, 0, int(255 / 4)), stroke_width: int = DEFAULT_STROKE_WIDTH, ) -> "PageImage": + self.draw_rects( self.page.chars, stroke=stroke, fill=fill, stroke_width=stroke_width ) diff --git a/pdfplumber/pdf.py b/pdfplumber/pdf.py index f322cc9..aaf50e3 100644 --- a/pdfplumber/pdf.py +++ b/pdfplumber/pdf.py @@ -72,6 +72,7 @@ class PDF(Container): repair: bool = False, gs_path: Optional[Union[str, pathlib.Path]] = None, ) -> "PDF": + stream: Union[BufferedReader, BytesIO] if repair: diff --git a/pdfplumber/repair.py b/pdfplumber/repair.py index e06abe9..a7a7b90 100644 --- a/pdfplumber/repair.py +++ b/pdfplumber/repair.py @@ -10,6 +10,7 @@ def _repair( password: Optional[str] = None, gs_path: Optional[Union[str, pathlib.Path]] = None, ) -> BytesIO: + executable = gs_path or shutil.which("gs") or shutil.which("gswin32c") if executable is None: # pragma: nocover raise Exception( diff --git a/pdfplumber/table.py b/pdfplumber/table.py index 6d0fd8e..28e5435 100644 --- a/pdfplumber/table.py +++ b/pdfplumber/table.py @@ -286,6 +286,7 @@ def intersections_to_cells(intersections: T_intersections) -> List[T_bbox]: and edge_connects(bottom_right, right_pt) and edge_connects(bottom_right, below_pt) ): + return (pt[0], pt[1], bottom_right[0], bottom_right[1]) return None @@ -396,6 +397,7 @@ class Table(object): return rows def extract(self, **kwargs: Any) -> List[List[Optional[str]]]: + chars = self.page.chars table_arr = [] diff --git a/pdfplumber/utils/clustering.py b/pdfplumber/utils/clustering.py index 0ce7cd6..961ab31 100644 --- a/pdfplumber/utils/clustering.py +++ b/pdfplumber/utils/clustering.py @@ -45,6 +45,7 @@ def cluster_objects( tolerance: T_num, preserve_order: bool = False, ) -> List[List[R]]: + if not callable(key_fn): key_fn = itemgetter(key_fn) diff --git a/pdfplumber/utils/text.py b/pdfplumber/utils/text.py index 6318a32..366eea2 100644 --- a/pdfplumber/utils/text.py +++ b/pdfplumber/utils/text.py @@ -72,6 +72,7 @@ class TextMap: return_chars: bool = True, main_group: int = 0, ) -> List[Dict[str, Any]]: + if isinstance(pattern, Pattern): if regex is False: raise ValueError( @@ -346,8 +347,8 @@ class WordExtractor: word[key] = ordered_chars[0][key] return word - - def set_tolerances_from_ratio(self, t: T_obj, axis_range: Iterable = "x"): + + def set_tolerances_from_ratio(self, t: T_obj, axis_range: Iterable='x'): """ If there is a `tolerance_ratio` for any axis, overrides the tolerance with ratio * size of `t`. Allows for dynamic tolerances to react to different text sizes within a single call. @@ -358,9 +359,11 @@ class WordExtractor: for i in axis_range: if self.__getattribute__(f"{i}_tolerance_ratio") is not None: self.__setattr__( - f"{i}_tolerance", - set_tolerance(t, self.__getattribute__(f"{i}_tolerance_ratio")), - ) + f"{i}_tolerance", + set_tolerance( + t, self.__getattribute__(f"{i}_tolerance_ratio") + ) + ) def char_begins_new_word( self, @@ -604,6 +607,5 @@ def dedupe_chars(chars: T_obj_list, tolerance: T_num = 1) -> T_obj_list: deduped = yield_unique_chars(chars) return sorted(deduped, key=chars.index) - def set_tolerance(t, tolerance_ratio): - return tolerance_ratio * (t["bottom"] - t["top"]) + return tolerance_ratio*(t['bottom'] - t['top']) \ No newline at end of file diff --git a/tests/test_ca_warn_report.py b/tests/test_ca_warn_report.py index c8984b8..5448f4e 100644 --- a/tests/test_ca_warn_report.py +++ b/tests/test_ca_warn_report.py @@ -40,6 +40,7 @@ class Test(unittest.TestCase): assert len(p.images) def test_parse(self): + rect_x0_clusters = utils.cluster_list( [r["x0"] for r in self.pdf.pages[1].rects], tolerance=3 ) diff --git a/tests/test_issues.py b/tests/test_issues.py index fdc519f..614b4c2 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -51,12 +51,14 @@ class Test(unittest.TestCase): """ for cl in checklines: + if ( checkbox["height"] > (RECT_HEIGHT - RECT_TOLERANCE) and (checkbox["height"] < RECT_HEIGHT + RECT_TOLERANCE) and (checkbox["width"] < RECT_WIDTH + RECT_TOLERANCE) and (checkbox["width"] < RECT_WIDTH + RECT_TOLERANCE) ): + xmatch = False ymatch = False diff --git a/tests/test_utils.py b/tests/test_utils.py index 50d78d3..7898bcc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -66,11 +66,9 @@ class Test(unittest.TestCase): def test_x_tolerance_ratio(self): pdf = pdfplumber.open(os.path.join(HERE, "pdfs/issue-987-test.pdf")) - assert pdf.pages[0].extract_text() == "Big Te xt\nSmall Text" - assert pdf.pages[0].extract_text(x_tolerance=4) == "Big Te xt\nSmallText" - assert ( - pdf.pages[0].extract_text(x_tolerance_ratio=0.15) == "Big Text\nSmall Text" - ) + assert pdf.pages[0].extract_text() == 'Big Te xt\nSmall Text' + assert pdf.pages[0].extract_text(x_tolerance=4) == 'Big Te xt\nSmallText' + assert pdf.pages[0].extract_text(x_tolerance_ratio=0.15) == 'Big Text\nSmall Text' def test_extract_words(self): path = os.path.join(HERE, "pdfs/issue-192-example.pdf") @@ -99,6 +97,7 @@ class Test(unittest.TestCase): def test_extract_words_punctuation(self): path = os.path.join(HERE, "pdfs/test-punkt.pdf") with pdfplumber.open(path) as pdf: + wordsA = pdf.pages[0].extract_words(split_at_punctuation=True) wordsB = pdf.pages[0].extract_words(split_at_punctuation=False) wordsC = pdf.pages[0].extract_words(