markitdown-pro 1.1.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.
Files changed (54) hide show
  1. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/PKG-INFO +1 -1
  2. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_doc_intel_wrapper.py +6 -1
  3. markitdown_pro-1.2.3/markitdown_pro/converters/tabular_wrapper.py +31 -0
  4. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/markup_handler.py +1 -1
  5. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/office_handler.py +7 -3
  6. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/pdf_handler.py +3 -3
  7. markitdown_pro-1.2.3/markitdown_pro/handlers/tabular_handler.py +96 -0
  8. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/text_handler.py +1 -1
  9. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/services/azure_doc_intelligence.py +3 -3
  10. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/PKG-INFO +1 -1
  11. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/SOURCES.txt +1 -2
  12. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/setup.py +1 -1
  13. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/handlers/test_markup_handler.py +2 -12
  14. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/handlers/test_text_handler.py +4 -4
  15. markitdown_pro-1.1.2/markitdown_pro/handlers/tabular_handler.py +0 -31
  16. markitdown_pro-1.1.2/tests/handlers/test_office_handler.py +0 -26
  17. markitdown_pro-1.1.2/tests/handlers/test_pdf_handler.py +0 -26
  18. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/README.md +0 -0
  19. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/__init__.py +0 -0
  20. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/common/__init__.py +0 -0
  21. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/common/isolated_worker.py +0 -0
  22. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/common/logger.py +0 -0
  23. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/common/schemas.py +0 -0
  24. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/common/utils.py +0 -0
  25. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/conversion_pipeline.py +0 -0
  26. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/__init__.py +0 -0
  27. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/azure_speech_wrapper.py +0 -0
  28. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/base.py +0 -0
  29. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/gpt_vision_wrapper.py +0 -0
  30. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/markitdown_wrapper.py +0 -0
  31. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/pymupdf_wrapper.py +0 -0
  32. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/unstructured_wrapper.py +0 -0
  33. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/converters/youtube_wrapper.py +0 -0
  34. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/__init__.py +0 -0
  35. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/audio_handler.py +0 -0
  36. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/base_handler.py +0 -0
  37. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/email_handler.py +0 -0
  38. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/epub_handler.py +0 -0
  39. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/image_handler.py +0 -0
  40. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/ipynb_handler.py +0 -0
  41. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/markitdown_handler.py +0 -0
  42. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/handlers/pst_handler.py +0 -0
  43. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/services/__init__.py +0 -0
  44. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/services/azure_speech.py +0 -0
  45. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro/services/openai_services.py +0 -0
  46. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/dependency_links.txt +0 -0
  47. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/requires.txt +0 -0
  48. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/markitdown_pro.egg-info/top_level.txt +0 -0
  49. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/pyproject.toml +0 -0
  50. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/setup.cfg +0 -0
  51. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/handlers/__init__.py +0 -0
  52. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/handlers/test_email_handler.py +0 -0
  53. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/handlers/test_pst_handler.py +0 -0
  54. {markitdown_pro-1.1.2 → markitdown_pro-1.2.3}/tests/test_conversion_pipeline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markitdown-pro
3
- Version: 1.1.2
3
+ Version: 1.2.3
4
4
  Summary: A package that converts almost any file format to Markdown.
5
5
  Author: Developer
6
6
  Classifier: Programming Language :: Python :: 3
@@ -5,9 +5,14 @@ from .base import ConverterWrapper
5
5
 
6
6
 
7
7
  class DocIntelligenceWrapper(ConverterWrapper):
8
+
9
+ SUPPORTED_EXTENSIONS = DocumentIntelligenceHandler.SUPPORTED_EXTENSIONS
10
+
8
11
  def __init__(self):
9
12
  super().__init__("Azure Document Intelligence")
10
13
  self.converter = DocumentIntelligenceHandler()
11
14
 
12
15
  async def convert(self, file_path: str) -> Optional[str]:
13
- return await self.converter.convert_to_md(file_path)
16
+ markdown = await self.converter.convert_to_md(file_path)
17
+ await self.converter.aclose()
18
+ return markdown
@@ -0,0 +1,31 @@
1
+ from typing import Optional
2
+
3
+ from ..common.logger import logger
4
+ from ..common.utils import clean_markdown
5
+ from ..handlers.tabular_handler import TabularHandler
6
+ from .base import ConverterWrapper
7
+
8
+
9
+ class TabularWrapper(ConverterWrapper):
10
+ SUPPORTED_FORMATS = (
11
+ "csv",
12
+ "tsv",
13
+ "xls",
14
+ "xlsx",
15
+ )
16
+
17
+ def __init__(self):
18
+ super().__init__("TabularHandler")
19
+ self.tabular_handler = TabularHandler()
20
+
21
+ async def convert(self, file_path: str) -> Optional[str]:
22
+ logger.debug(f"TabularWrapper: Converting {file_path} to markdown")
23
+ file_extension = file_path.split(".")[-1].lower()
24
+
25
+ if file_extension not in self.SUPPORTED_FORMATS:
26
+ logger.warning(f"TabularWrapper: Unsupported file format: {file_extension}")
27
+ return None
28
+
29
+ markdown = await self.tabular_handler.handle(file_path)
30
+ markdown = clean_markdown(markdown) if markdown else None
31
+ return markdown
@@ -18,7 +18,7 @@ from .base_handler import BaseHandler
18
18
  class MarkupHandler(BaseHandler):
19
19
  """Handler for .html, .xml, .json, .ndjson, .yaml, .yml files."""
20
20
 
21
- extensions = frozenset([".html", ".htm", ".xml", ".json", ".ndjson", ".yaml", ".yml"])
21
+ SUPPORTED_EXTENSIONS = frozenset([".html", ".htm", ".xml", ".json", ".ndjson", ".yaml", ".yml"])
22
22
 
23
23
  async def handle(self, file_path: str, *args, **kwargs) -> Optional[str]:
24
24
  logger.info(f"Processing markup file: {file_path}")
@@ -5,6 +5,7 @@ from ..common.utils import ensure_minimum_content
5
5
  from ..converters.azure_doc_intel_wrapper import DocIntelligenceWrapper
6
6
  from ..converters.base import ConverterWrapper
7
7
  from ..converters.markitdown_wrapper import MarkItDownWrapper
8
+ from ..converters.tabular_wrapper import TabularWrapper
8
9
  from ..converters.unstructured_wrapper import UnstructuredWrapper
9
10
  from .base_handler import BaseHandler
10
11
 
@@ -13,9 +14,10 @@ class OfficeHandler(BaseHandler):
13
14
  """
14
15
  Convert Office documents to Markdown by trying a series of converters in order:
15
16
 
16
- 1) MarkItDown (fast, local parsing for Office formats)
17
- 2) Azure Document Intelligence (cloud extraction + OCR for embedded images)
18
- 3) Unstructured (robust fallback parser)
17
+ 1) TabularHandler (specialized handler for tabular data)
18
+ 2) MarkItDown (fast, local parsing for Office formats)
19
+ 3) Azure Document Intelligence (cloud extraction + OCR for embedded images)
20
+ 4) Unstructured (robust fallback parser)
19
21
 
20
22
  The first converter that returns non-trivial Markdown (as judged by
21
23
  `ensure_minimum_content`) wins. If all fail, `None` is returned.
@@ -34,12 +36,14 @@ class OfficeHandler(BaseHandler):
34
36
  super().__init__(*args, **kwargs)
35
37
 
36
38
  # Ordered, fastest → most comprehensive
39
+ self.tabular = TabularWrapper()
37
40
  self.markitdown = MarkItDownWrapper()
38
41
  self.doc_intelligence = DocIntelligenceWrapper()
39
42
  self.unstructured = UnstructuredWrapper()
40
43
 
41
44
  # (converter, human_readable_name) in the exact order to try
42
45
  self._pipeline: list[tuple[ConverterWrapper, str]] = [
46
+ (self.tabular, "TabularHandler"),
43
47
  (self.markitdown, "MarkItDown"),
44
48
  (self.doc_intelligence, "Azure Document Intelligence"),
45
49
  (self.unstructured, "Unstructured"),
@@ -89,10 +89,10 @@ class PDFHandler(BaseHandler):
89
89
  # Choose pipeline based on detected content type
90
90
  if pdf_type == PDFType.TEXT_ONLY:
91
91
  pipeline = self.text_pipeline
92
- elif pdf_type == PDFType.ALL_IMAGES:
92
+ elif pdf_type == PDFType.ALL_IMAGES or pdf_type == PDFType.TEXT_PLUS_IMAGES:
93
93
  pipeline = self.image_pipeline
94
- elif pdf_type == PDFType.TEXT_PLUS_IMAGES:
95
- pipeline = self.text_pipeline + self.image_pipeline
94
+ # elif pdf_type == PDFType.TEXT_PLUS_IMAGES:
95
+ # pipeline = self.text_pipeline + self.image_pipeline
96
96
  else:
97
97
  # Fallback to text pipeline if detection returned an unexpected value
98
98
  pipeline = self.text_pipeline
@@ -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
@@ -11,7 +11,7 @@ from .base_handler import BaseHandler
11
11
  class TextHandler(BaseHandler):
12
12
  """Handler for .txt, .md, .py, .go, and other text/code files."""
13
13
 
14
- extensions = frozenset([".txt", ".md", ".py", ".go"])
14
+ SUPPORTED_EXTENSIONS = frozenset([".txt", ".md", ".py", ".go"])
15
15
 
16
16
  async def handle(self, file_path: str, *args, **kwargs) -> Optional[str]:
17
17
  logger.info(f"Processing text file: {file_path}")
@@ -59,7 +59,7 @@ class DocumentIntelligenceHandler:
59
59
  ".heic",
60
60
  }
61
61
  )
62
- extensions: frozenset[str] = frozenset(
62
+ SUPPORTED_EXTENSIONS: frozenset[str] = frozenset(
63
63
  list(pdf_extensions) + list(office_extensions) + list(image_extensions)
64
64
  )
65
65
 
@@ -112,7 +112,7 @@ class DocumentIntelligenceHandler:
112
112
  return None
113
113
 
114
114
  ext = file_path.suffix.lower()
115
- if ext not in self.extensions:
115
+ if ext not in self.SUPPORTED_EXTENSIONS:
116
116
  logger.warning(f"DocumentIntelligenceHandler: unsupported extension '{ext}'.")
117
117
  return None
118
118
 
@@ -178,4 +178,4 @@ class DocumentIntelligenceHandler:
178
178
  @classmethod
179
179
  def supports(cls, path: str | Path) -> bool:
180
180
  """Return True if the file extension is supported by this handler."""
181
- return Path(path).suffix.lower() in cls.extensions
181
+ return Path(path).suffix.lower() in cls.SUPPORTED_EXTENSIONS
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markitdown-pro
3
- Version: 1.1.2
3
+ Version: 1.2.3
4
4
  Summary: A package that converts almost any file format to Markdown.
5
5
  Author: Developer
6
6
  Classifier: Programming Language :: Python :: 3
@@ -21,6 +21,7 @@ markitdown_pro/converters/base.py
21
21
  markitdown_pro/converters/gpt_vision_wrapper.py
22
22
  markitdown_pro/converters/markitdown_wrapper.py
23
23
  markitdown_pro/converters/pymupdf_wrapper.py
24
+ markitdown_pro/converters/tabular_wrapper.py
24
25
  markitdown_pro/converters/unstructured_wrapper.py
25
26
  markitdown_pro/converters/youtube_wrapper.py
26
27
  markitdown_pro/handlers/__init__.py
@@ -45,7 +46,5 @@ tests/test_conversion_pipeline.py
45
46
  tests/handlers/__init__.py
46
47
  tests/handlers/test_email_handler.py
47
48
  tests/handlers/test_markup_handler.py
48
- tests/handlers/test_office_handler.py
49
- tests/handlers/test_pdf_handler.py
50
49
  tests/handlers/test_pst_handler.py
51
50
  tests/handlers/test_text_handler.py
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
2
2
 
3
3
  setup(
4
4
  name="markitdown-pro",
5
- version="1.1.2",
5
+ version="1.2.3",
6
6
  author="Developer",
7
7
  description="A package that converts almost any file format to Markdown.",
8
8
  long_description=open("README.md").read(),
@@ -9,25 +9,15 @@ from tests.utils import list_files
9
9
 
10
10
  log = logging.getLogger(__name__)
11
11
 
12
- INCLUDE_EXTENSIONS = [
13
- ".html",
14
- ".htm",
15
- ".xml",
16
- ".json",
17
- ".ndjson",
18
- ".yaml",
19
- ".yml",
20
- ]
21
-
22
12
  TEST_FILES_PATH = data_path()
23
- ALL_FILES = list_files(TEST_FILES_PATH, include_ext=INCLUDE_EXTENSIONS, recursive=True)
13
+ ALL_FILES = list_files(TEST_FILES_PATH, include_ext=MarkupHandler.extensions, recursive=True)
24
14
  log.info(f"Found {len(ALL_FILES)} test files in {TEST_FILES_PATH}.")
25
15
 
26
16
 
27
17
  @pytest.mark.asyncio
28
18
  @pytest.mark.parametrize("file_path", ALL_FILES, ids=[pretty_id(p) for p in ALL_FILES])
29
19
  async def test_files(file_path: Path, markup_handler: MarkupHandler):
30
- log.info(f"Testing file: {file_path}")
20
+ log.info(f"{MarkupHandler.__name__}: Testing file {file_path}")
31
21
 
32
22
  markdown_text = await markup_handler.handle(str(file_path))
33
23
  assert markdown_text is not None, f"Conversion returned None for {file_path.name}"
@@ -9,17 +9,17 @@ from tests.utils import list_files
9
9
 
10
10
  log = logging.getLogger(__name__)
11
11
 
12
- INCLUDE_EXTENSIONS = [".txt", ".md", ".py", ".go"]
13
-
14
12
  TEST_FILES_PATH = data_path()
15
- ALL_FILES = list_files(TEST_FILES_PATH, include_ext=INCLUDE_EXTENSIONS, recursive=True)
13
+ ALL_FILES = list_files(
14
+ TEST_FILES_PATH, include_ext=TextHandler.SUPPORTED_EXTENSIONS, recursive=True
15
+ )
16
16
  log.info(f"Found {len(ALL_FILES)} test files in {TEST_FILES_PATH}.")
17
17
 
18
18
 
19
19
  @pytest.mark.asyncio
20
20
  @pytest.mark.parametrize("file_path", ALL_FILES, ids=[pretty_id(p) for p in ALL_FILES])
21
21
  async def test_files(file_path: Path, text_handler: TextHandler):
22
- log.info(f"Testing file: {file_path}")
22
+ log.info(f"{TextHandler.__name__}: Testing file {file_path}")
23
23
 
24
24
  markdown_text = await text_handler.handle(str(file_path))
25
25
  assert markdown_text is not None, f"Conversion returned None for {file_path.name}"
@@ -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
@@ -1,26 +0,0 @@
1
- import logging
2
- from pathlib import Path
3
-
4
- import pytest
5
-
6
- from markitdown_pro.handlers.office_handler import OfficeHandler
7
- from tests.fixtures import data_path, pretty_id
8
- from tests.utils import list_files
9
-
10
- log = logging.getLogger(__name__)
11
-
12
- INCLUDE_EXTENSIONS = [".docx", ".xlsx", ".pptx"]
13
-
14
- TEST_FILES_PATH = data_path()
15
- ALL_FILES = list_files(TEST_FILES_PATH, include_ext=INCLUDE_EXTENSIONS, recursive=True)
16
- log.info(f"Found {len(ALL_FILES)} test files in {TEST_FILES_PATH}.")
17
-
18
-
19
- @pytest.mark.asyncio
20
- @pytest.mark.parametrize("file_path", ALL_FILES, ids=[pretty_id(p) for p in ALL_FILES])
21
- async def test_files(file_path: Path, office_handler: OfficeHandler):
22
- log.info(f"Testing file: {file_path}")
23
-
24
- markdown_text = await office_handler.handle(str(file_path))
25
- assert markdown_text is not None, f"Conversion returned None for {file_path.name}"
26
- assert isinstance(markdown_text, str), f"Output type is not str for {file_path.name}"
@@ -1,26 +0,0 @@
1
- import logging
2
- from pathlib import Path
3
-
4
- import pytest
5
-
6
- from markitdown_pro.handlers.pdf_handler import PDFHandler
7
- from tests.fixtures import data_path, pretty_id
8
- from tests.utils import list_files
9
-
10
- log = logging.getLogger(__name__)
11
-
12
- INCLUDE_EXTENSIONS = [".pdf"]
13
-
14
- TEST_FILES_PATH = data_path()
15
- ALL_FILES = list_files(TEST_FILES_PATH, include_ext=INCLUDE_EXTENSIONS, recursive=True)
16
- log.info(f"Found {len(ALL_FILES)} test files in {TEST_FILES_PATH}.")
17
-
18
-
19
- @pytest.mark.asyncio
20
- @pytest.mark.parametrize("file_path", ALL_FILES, ids=[pretty_id(p) for p in ALL_FILES])
21
- async def test_files(file_path: Path, pdf_handler: PDFHandler):
22
- log.info(f"Testing file: {file_path}")
23
-
24
- markdown_text = await pdf_handler.handle(str(file_path))
25
- assert markdown_text is not None, f"Conversion returned None for {file_path.name}"
26
- assert isinstance(markdown_text, str), f"Output type is not str for {file_path.name}"
File without changes
File without changes