doocus first ver
This commit is contained in:
57
doocus/extractors/tabular.py
Normal file
57
doocus/extractors/tabular.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
Tabular-family extractor: csv.
|
||||
|
||||
Renders to a markdown table (capped preview) with row/column metadata. Uses only
|
||||
the stdlib so it always works.
|
||||
"""
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
from .base import ExtractionResult
|
||||
|
||||
EXTRACTOR_ID = "tabular/csv@1"
|
||||
MAX_PREVIEW_ROWS = 200
|
||||
|
||||
|
||||
def _md_table(rows: list) -> str:
|
||||
if not rows:
|
||||
return ""
|
||||
width = max(len(r) for r in rows)
|
||||
rows = [r + [""] * (width - len(r)) for r in rows]
|
||||
header, body = rows[0], rows[1:]
|
||||
|
||||
def esc(c: str) -> str:
|
||||
return str(c).replace("|", "\\|").replace("\n", " ")
|
||||
|
||||
lines = ["| " + " | ".join(esc(c) for c in header) + " |",
|
||||
"| " + " | ".join(["---"] * width) + " |"]
|
||||
for r in body:
|
||||
lines.append("| " + " | ".join(esc(c) for c in r) + " |")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def extract(source: Path, options: dict) -> ExtractionResult:
|
||||
warnings = []
|
||||
with open(source, newline="", encoding="utf-8", errors="replace") as f:
|
||||
sample = f.read(8192)
|
||||
f.seek(0)
|
||||
try:
|
||||
dialect = csv.Sniffer().sniff(sample) if sample.strip() else csv.excel
|
||||
except csv.Error:
|
||||
dialect = csv.excel
|
||||
rows = list(csv.reader(f, dialect))
|
||||
|
||||
total = len(rows)
|
||||
cols = max((len(r) for r in rows), default=0)
|
||||
preview = rows[: MAX_PREVIEW_ROWS + 1] # +1 for header
|
||||
if total > MAX_PREVIEW_ROWS + 1:
|
||||
warnings.append(f"table has {total} rows; previewed first {MAX_PREVIEW_ROWS}")
|
||||
|
||||
content = _md_table(preview)
|
||||
metadata = {
|
||||
"rows": max(total - 1, 0),
|
||||
"columns": cols,
|
||||
"header": rows[0] if rows else [],
|
||||
}
|
||||
return ExtractionResult(content=content, metadata=metadata,
|
||||
warnings=warnings, extractor=EXTRACTOR_ID)
|
||||
Reference in New Issue
Block a user