markitdown-pro 1.2.2__tar.gz → 1.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/PKG-INFO +1 -1
- markitdown_pro-1.2.3/markitdown_pro/handlers/tabular_handler.py +96 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/PKG-INFO +1 -1
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/setup.py +1 -1
- markitdown_pro-1.2.2/markitdown_pro/handlers/tabular_handler.py +0 -31
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/README.md +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/common/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/common/isolated_worker.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/common/logger.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/common/schemas.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/common/utils.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/conversion_pipeline.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_doc_intel_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_speech_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/base.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/gpt_vision_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/markitdown_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/pymupdf_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/tabular_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/unstructured_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/youtube_wrapper.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/audio_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/base_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/email_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/epub_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/image_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/ipynb_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/markitdown_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/markup_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/office_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/pdf_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/pst_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/text_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/services/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/services/azure_doc_intelligence.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/services/azure_speech.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/services/openai_services.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/SOURCES.txt +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/dependency_links.txt +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/requires.txt +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/top_level.txt +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/pyproject.toml +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/setup.cfg +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/handlers/__init__.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/handlers/test_email_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/handlers/test_markup_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/handlers/test_pst_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/handlers/test_text_handler.py +0 -0
- {markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/tests/test_conversion_pipeline.py +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import csv
|
|
3
|
+
import os
|
|
4
|
+
from io import StringIO
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from openpyxl import load_workbook
|
|
8
|
+
|
|
9
|
+
from ..common.logger import logger
|
|
10
|
+
from .base_handler import BaseHandler
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _escape_md_cell(s: str) -> str:
|
|
14
|
+
return s.replace("|", r"\|").replace("\n", " ").replace("\r", " ").strip()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _csv_to_markdown(path: str, delimiter: str) -> str:
|
|
18
|
+
out = StringIO()
|
|
19
|
+
with open(path, "r", newline="", encoding="utf-8") as f:
|
|
20
|
+
reader = csv.reader(f, delimiter=delimiter)
|
|
21
|
+
try:
|
|
22
|
+
header = next(reader)
|
|
23
|
+
except StopIteration:
|
|
24
|
+
return "" # empty file
|
|
25
|
+
header = ["" if h is None else str(h) for h in header]
|
|
26
|
+
out.write("| " + " | ".join(_escape_md_cell(h) for h in header) + " |\n")
|
|
27
|
+
out.write("| " + " | ".join(["---"] * len(header)) + " |\n")
|
|
28
|
+
for row in reader:
|
|
29
|
+
row = ["" if c is None else str(c) for c in row]
|
|
30
|
+
out.write("| " + " | ".join(_escape_md_cell(c) for c in row) + " |\n")
|
|
31
|
+
return out.getvalue()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _xlsx_to_markdown(path: str) -> str:
|
|
35
|
+
wb = load_workbook(filename=path, read_only=True, data_only=True)
|
|
36
|
+
out = StringIO()
|
|
37
|
+
for sheet_name in wb.sheetnames:
|
|
38
|
+
ws = wb[sheet_name]
|
|
39
|
+
out.write(f"\n\n### Sheet: {sheet_name}\n\n")
|
|
40
|
+
rows_iter = ws.iter_rows(values_only=True)
|
|
41
|
+
try:
|
|
42
|
+
header_row = next(rows_iter)
|
|
43
|
+
except StopIteration:
|
|
44
|
+
out.write("_(empty sheet)_\n")
|
|
45
|
+
continue
|
|
46
|
+
if header_row is None:
|
|
47
|
+
out.write("_(empty sheet)_\n")
|
|
48
|
+
continue
|
|
49
|
+
header_vals = ["" if v is None else str(v) for v in header_row]
|
|
50
|
+
out.write("| " + " | ".join(_escape_md_cell(v) for v in header_vals) + " |\n")
|
|
51
|
+
out.write("| " + " | ".join(["---"] * len(header_vals)) + " |\n")
|
|
52
|
+
for row in rows_iter:
|
|
53
|
+
if row is None:
|
|
54
|
+
out.write("| " + " | ".join("" for _ in header_vals) + " |\n")
|
|
55
|
+
continue
|
|
56
|
+
cells = ["" if v is None else str(v) for v in row]
|
|
57
|
+
# pad/truncate to header length so column count stays consistent
|
|
58
|
+
if len(cells) < len(header_vals):
|
|
59
|
+
cells += [""] * (len(header_vals) - len(cells))
|
|
60
|
+
elif len(cells) > len(header_vals):
|
|
61
|
+
cells = cells[: len(header_vals)]
|
|
62
|
+
out.write("| " + " | ".join(_escape_md_cell(v) for v in cells) + " |\n")
|
|
63
|
+
return out.getvalue()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class TabularHandler(BaseHandler):
|
|
67
|
+
"""Handler for .csv, .tsv, .xls, .xlsx files."""
|
|
68
|
+
|
|
69
|
+
extensions = frozenset([".csv", ".tsv", ".xls", ".xlsx"])
|
|
70
|
+
|
|
71
|
+
async def handle(self, file_path: str, *args, **kwargs) -> Optional[str]:
|
|
72
|
+
logger.info(f"Processing tabular file: {file_path}")
|
|
73
|
+
try:
|
|
74
|
+
ext = os.path.splitext(file_path)[1].lower()
|
|
75
|
+
if ext == ".csv":
|
|
76
|
+
md = await asyncio.to_thread(_csv_to_markdown, file_path, ",")
|
|
77
|
+
elif ext == ".tsv":
|
|
78
|
+
md = await asyncio.to_thread(_csv_to_markdown, file_path, "\t")
|
|
79
|
+
elif ext in [".xlsx"]:
|
|
80
|
+
md = await asyncio.to_thread(_xlsx_to_markdown, file_path)
|
|
81
|
+
elif ext in [".xls"]:
|
|
82
|
+
# Fallback: many environments lack a safe streaming .xls reader.
|
|
83
|
+
# If .xls appears, let pandas handle it but still offload to a thread.
|
|
84
|
+
import pandas as pd
|
|
85
|
+
|
|
86
|
+
def _xls_to_md(p: str) -> str:
|
|
87
|
+
df = pd.read_excel(p)
|
|
88
|
+
return df.to_markdown(index=False)
|
|
89
|
+
|
|
90
|
+
md = await asyncio.to_thread(_xls_to_md, file_path)
|
|
91
|
+
else:
|
|
92
|
+
raise RuntimeError("Unsupported tabular format")
|
|
93
|
+
return md or ""
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.error(f"Error processing tabular file {file_path}: {e}")
|
|
96
|
+
return None
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
import pandas as pd
|
|
5
|
-
|
|
6
|
-
from ..common.logger import logger
|
|
7
|
-
from .base_handler import BaseHandler
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class TabularHandler(BaseHandler):
|
|
11
|
-
"""Handler for .csv, .tsv, .xls, .xlsx files."""
|
|
12
|
-
|
|
13
|
-
extensions = frozenset([".csv", ".tsv", ".xls", ".xlsx"])
|
|
14
|
-
|
|
15
|
-
async def handle(self, file_path: str, *args, **kwargs) -> Optional[str]:
|
|
16
|
-
logger.info(f"Processing tabular file: {file_path}")
|
|
17
|
-
try:
|
|
18
|
-
ext = os.path.splitext(file_path)[1].lower()
|
|
19
|
-
if ext in [".csv", ".tsv"]:
|
|
20
|
-
delimiter = "\t" if ext == ".tsv" else ","
|
|
21
|
-
df = pd.read_csv(file_path, delimiter=delimiter)
|
|
22
|
-
elif ext in [".xls", ".xlsx"]:
|
|
23
|
-
df = pd.read_excel(file_path)
|
|
24
|
-
else:
|
|
25
|
-
raise RuntimeError("Unsupported tabular format")
|
|
26
|
-
|
|
27
|
-
md = df.to_markdown(index=False)
|
|
28
|
-
return md
|
|
29
|
-
except Exception as e:
|
|
30
|
-
logger.error(f"Error processing tabular file {file_path}: {e}")
|
|
31
|
-
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_doc_intel_wrapper.py
RENAMED
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_speech_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/gpt_vision_wrapper.py
RENAMED
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/markitdown_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/unstructured_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-1.2.2 → markitdown_pro-1.2.3}/markitdown_pro/services/azure_doc_intelligence.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|