Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -831,6 +831,46 @@ def directionalize_amount_headers(md: str) -> str:
|
|
| 831 |
)
|
| 832 |
|
| 833 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 834 |
def _strip_trailing_money_tokens(rest: str, max_take: int = 2) -> Tuple[str, List[str]]:
|
| 835 |
"""Strip 1–2 currency tokens from the right of *rest*; return (description, tokens oldest-first)."""
|
| 836 |
cur = rest.rstrip()
|
|
@@ -1004,6 +1044,7 @@ def light_stabilize_markdown(page_md: str) -> str:
|
|
| 1004 |
merged = close_unclosed_html("\n\n".join(out_blocks))
|
| 1005 |
merged = mask_non_monetary_long_numbers(merged)
|
| 1006 |
merged = directionalize_amount_headers(merged)
|
|
|
|
| 1007 |
merged = repair_thead_cell_semantics(merged)
|
| 1008 |
merged = stabilize_table_markup(merged, rounds=4)
|
| 1009 |
merged = strip_degenerate_html_tables(merged)
|
|
@@ -1750,6 +1791,7 @@ def run_ocr(uploaded_file):
|
|
| 1750 |
if merged and merged != "(No content)" and not merged.lstrip().startswith("Error:"):
|
| 1751 |
merged = mask_non_monetary_long_numbers(merged)
|
| 1752 |
merged = directionalize_amount_headers(merged)
|
|
|
|
| 1753 |
merged = normalize_ambiguous_amount_balance_tables(merged)
|
| 1754 |
merged = normalize_amount_only_transaction_tables(merged)
|
| 1755 |
merged = stabilize_table_markup(merged, rounds=4)
|
|
|
|
| 831 |
)
|
| 832 |
|
| 833 |
|
| 834 |
+
def directionalize_amount_headers_by_nearby_context(md: str) -> str:
|
| 835 |
+
"""
|
| 836 |
+
Use nearby narrative labels around each table (outside HTML cells) to set
|
| 837 |
+
Amount->Credit/Debit when the table itself is ambiguous.
|
| 838 |
+
"""
|
| 839 |
+
if not md or "<table" not in md.lower():
|
| 840 |
+
return md
|
| 841 |
+
|
| 842 |
+
credit_hint_re = re.compile(
|
| 843 |
+
r"\b(all\s+credit\s+activity|credit\s+activity|deposits?|credits?|money\s+in)\b",
|
| 844 |
+
re.IGNORECASE,
|
| 845 |
+
)
|
| 846 |
+
debit_hint_re = re.compile(
|
| 847 |
+
r"\b(all\s+debit\s+activity|debit\s+activity|withdrawals?|debits?|checks?|money\s+out)\b",
|
| 848 |
+
re.IGNORECASE,
|
| 849 |
+
)
|
| 850 |
+
|
| 851 |
+
table_re = re.compile(r"<table\b[^>]*>.*?</table>", re.IGNORECASE | re.DOTALL)
|
| 852 |
+
out_parts: List[str] = []
|
| 853 |
+
last_end = 0
|
| 854 |
+
for tm in table_re.finditer(md):
|
| 855 |
+
out_parts.append(md[last_end:tm.start()])
|
| 856 |
+
tbl = tm.group(0)
|
| 857 |
+
|
| 858 |
+
left = re.sub(r"<[^>]+>", " ", md[max(0, tm.start() - 700): tm.start()])
|
| 859 |
+
right = re.sub(r"<[^>]+>", " ", md[tm.end(): min(len(md), tm.end() + 250)])
|
| 860 |
+
ctx = f"{left} {right}"
|
| 861 |
+
is_credit = bool(credit_hint_re.search(ctx))
|
| 862 |
+
is_debit = bool(debit_hint_re.search(ctx))
|
| 863 |
+
if is_credit ^ is_debit:
|
| 864 |
+
w = "Credit" if is_credit else "Debit"
|
| 865 |
+
tbl = re.sub(r"(<th\b[^>]*>\s*)amount(\s*</th>)", rf"\1{w}\2", tbl, flags=re.IGNORECASE)
|
| 866 |
+
tbl = re.sub(r"(<td\b[^>]*>\s*)amount(\s*</td>)", rf"\1{w}\2", tbl, flags=re.IGNORECASE)
|
| 867 |
+
|
| 868 |
+
out_parts.append(tbl)
|
| 869 |
+
last_end = tm.end()
|
| 870 |
+
out_parts.append(md[last_end:])
|
| 871 |
+
return "".join(out_parts)
|
| 872 |
+
|
| 873 |
+
|
| 874 |
def _strip_trailing_money_tokens(rest: str, max_take: int = 2) -> Tuple[str, List[str]]:
|
| 875 |
"""Strip 1–2 currency tokens from the right of *rest*; return (description, tokens oldest-first)."""
|
| 876 |
cur = rest.rstrip()
|
|
|
|
| 1044 |
merged = close_unclosed_html("\n\n".join(out_blocks))
|
| 1045 |
merged = mask_non_monetary_long_numbers(merged)
|
| 1046 |
merged = directionalize_amount_headers(merged)
|
| 1047 |
+
merged = directionalize_amount_headers_by_nearby_context(merged)
|
| 1048 |
merged = repair_thead_cell_semantics(merged)
|
| 1049 |
merged = stabilize_table_markup(merged, rounds=4)
|
| 1050 |
merged = strip_degenerate_html_tables(merged)
|
|
|
|
| 1791 |
if merged and merged != "(No content)" and not merged.lstrip().startswith("Error:"):
|
| 1792 |
merged = mask_non_monetary_long_numbers(merged)
|
| 1793 |
merged = directionalize_amount_headers(merged)
|
| 1794 |
+
merged = directionalize_amount_headers_by_nearby_context(merged)
|
| 1795 |
merged = normalize_ambiguous_amount_balance_tables(merged)
|
| 1796 |
merged = normalize_amount_only_transaction_tables(merged)
|
| 1797 |
merged = stabilize_table_markup(merged, rounds=4)
|