mirror of
https://github.com/jsvine/pdfplumber.git
synced 2026-08-29 16:40:24 +08:00
141 lines
5.4 KiB
Python
141 lines
5.4 KiB
Python
#!/usr/bin/env python
|
|
import logging
|
|
import os
|
|
import unittest
|
|
|
|
import pdfplumber
|
|
|
|
logging.disable(logging.ERROR)
|
|
|
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
|
class Test(unittest.TestCase):
|
|
@classmethod
|
|
def setup_class(self):
|
|
path = os.path.join(HERE, "pdfs/issue-71-duplicate-chars.pdf")
|
|
self.pdf = pdfplumber.open(path)
|
|
|
|
@classmethod
|
|
def teardown_class(self):
|
|
self.pdf.close()
|
|
|
|
def test_extract_table(self):
|
|
page = self.pdf.pages[0]
|
|
table_without_drop_duplicates = page.extract_table()
|
|
table_with_drop_duplicates = page.dedupe_chars().extract_table()
|
|
last_line_without_drop = table_without_drop_duplicates[1][1].split("\n")[-1]
|
|
last_line_with_drop = table_with_drop_duplicates[1][1].split("\n")[-1]
|
|
|
|
assert (
|
|
last_line_without_drop
|
|
== "微微软软 培培训训课课程程:: 名名模模意意义义一一些些有有意意义义一一些些"
|
|
)
|
|
assert last_line_with_drop == "微软 培训课程: 名模意义一些有意义一些"
|
|
|
|
def test_extract_words(self):
|
|
page = self.pdf.pages[0]
|
|
x0 = 440.143
|
|
x1_without_drop = 534.992
|
|
x1_with_drop = 534.719
|
|
top_windows = 791.849
|
|
top_linux = 794.357
|
|
bottom = 802.961
|
|
last_words_without_drop = page.extract_words()[-1]
|
|
last_words_with_drop = page.dedupe_chars().extract_words()[-1]
|
|
|
|
assert round(last_words_without_drop["x0"], 3) == x0
|
|
assert round(last_words_without_drop["x1"], 3) == x1_without_drop
|
|
assert round(last_words_without_drop["top"], 3) in (top_windows, top_linux)
|
|
assert round(last_words_without_drop["bottom"], 3) == bottom
|
|
assert last_words_without_drop["upright"] == 1
|
|
assert (
|
|
last_words_without_drop["text"]
|
|
== "名名模模意意义义一一些些有有意意义义一一些些"
|
|
)
|
|
|
|
assert round(last_words_with_drop["x0"], 3) == x0
|
|
assert round(last_words_with_drop["x1"], 3) == x1_with_drop
|
|
assert round(last_words_with_drop["top"], 3) in (top_windows, top_linux)
|
|
assert round(last_words_with_drop["bottom"], 3) == bottom
|
|
assert last_words_with_drop["upright"] == 1
|
|
assert last_words_with_drop["text"] == "名模意义一些有意义一些"
|
|
|
|
def test_extract_text(self):
|
|
page = self.pdf.pages[0]
|
|
last_line_without_drop = page.extract_text().split("\n")[-1]
|
|
last_line_with_drop = page.dedupe_chars().extract_text().split("\n")[-1]
|
|
|
|
assert (
|
|
last_line_without_drop
|
|
== "微微软软 培培训训课课程程:: 名名模模意意义义一一些些有有意意义义一一些些"
|
|
)
|
|
assert last_line_with_drop == "微软 培训课程: 名模意义一些有意义一些"
|
|
|
|
def test_extract_text2(self):
|
|
path = os.path.join(HERE, "pdfs/issue-71-duplicate-chars-2.pdf")
|
|
pdf = pdfplumber.open(path)
|
|
page = pdf.pages[0]
|
|
|
|
assert (
|
|
page.dedupe_chars().extract_text(y_tolerance=6).splitlines()[4]
|
|
== "UE 8. Circulation - Métabolismes"
|
|
)
|
|
|
|
def test_extra_attrs(self):
|
|
path = os.path.join(HERE, "pdfs/issue-1114-dedupe-chars.pdf")
|
|
pdf = pdfplumber.open(path)
|
|
page = pdf.pages[0]
|
|
|
|
def dup_chars(s: str) -> str:
|
|
return "".join((char if char == " " else char + char) for char in s)
|
|
|
|
ground_truth = (
|
|
("Simple", False, False),
|
|
("Duplicated", True, True),
|
|
("Font", "fontname", True),
|
|
("Size", "size", True),
|
|
("Italic", "fontname", True),
|
|
("Weight", "fontname", True),
|
|
("Horizontal shift", False, "HHoorrizizoonntatal ls shhifitft"),
|
|
("Vertical shift", False, True),
|
|
)
|
|
gt = []
|
|
for text, should_dedup, dup_text in ground_truth:
|
|
if isinstance(dup_text, bool):
|
|
if dup_text:
|
|
dup_text = dup_chars(text)
|
|
else:
|
|
dup_text = text
|
|
gt.append((text, should_dedup, dup_text))
|
|
|
|
keys_list = ["no_dedupe", (), ("size",), ("fontname",), ("size", "fontname")]
|
|
for keys in keys_list:
|
|
if keys != "no_dedupe":
|
|
filtered_page = page.dedupe_chars(tolerance=2, extra_attrs=keys)
|
|
else:
|
|
filtered_page = page
|
|
for i, line in enumerate(
|
|
filtered_page.extract_text(y_tolerance=5).splitlines()
|
|
):
|
|
text, should_dedup, dup_text = gt[i]
|
|
if keys == "no_dedupe":
|
|
should_dedup = False
|
|
if isinstance(should_dedup, str):
|
|
if should_dedup in keys:
|
|
fail_msg = (
|
|
f"{should_dedup} is not required to match "
|
|
"so it should be duplicated"
|
|
)
|
|
assert line == dup_text, fail_msg
|
|
else:
|
|
fail_msg = (
|
|
"Should not be duplicated "
|
|
f"when requiring matching {should_dedup}"
|
|
)
|
|
assert line == text, fail_msg
|
|
elif should_dedup:
|
|
assert line == text
|
|
else:
|
|
assert line == dup_text
|