import os from pathlib import Path from typing import Callable, Dict, Any import markdown import fitz from docx import Document from bs4 import BeautifulSoup class DocumentConverter: def convert(self, input_path:str, output_path:str, options:Dict[str,Any]|None=None, progress_callback:Callable|None=None)->bool: try: input_ext = Path(input_path).suffix.lower() output_ext = Path(output_path).suffix.lower() self._update(progress_callback, 10) Path(output_path).parent.mkdir(parents=True, exist_ok=True) success = False # TXT if input_ext == ".txt" and output_ext == ".pdf": success = self.txt_to_pdf(input_path, output_path) elif input_ext == ".txt" and output_ext == ".html": success = self.txt_to_html(input_path, output_path) elif input_ext == ".txt" and output_ext == ".md": success = self.txt_to_md(input_path, output_path) # MD elif input_ext == ".md" and output_ext == ".html": success = self.md_to_html(input_path, output_path) elif input_ext == ".md" and output_ext == ".txt": success = self.md_to_text(input_path, output_path) # HTML elif input_ext == ".html" and output_ext == ".txt": success = self.html_to_text(input_path, output_path) elif input_ext == ".html" and output_ext == ".md": success = self.html_to_md(input_path, output_path) # DOCX elif input_ext == ".docx" and output_ext == ".txt": success = self.docx_to_text(input_path, output_path) # PDF elif input_ext == ".pdf" and output_ext == ".txt": success = self.pdf_to_text(input_path, output_path) elif input_ext == ".pdf" and output_ext == ".html": success = self.pdf_to_html(input_path, output_path) else: raise ValueError(f"Unsupported conversion: {input_ext} -> {output_ext}") self._update(progress_callback, 100) return success except Exception as e: print(f"Document conversion error: {e}") return False def txt_to_pdf(self, input_path, output_path): pdf = fitz.open() page = pdf.new_page() text = Path(input_path).read_text( encoding="utf-8", errors="ignore" ) page.insert_text((72, 72), text[:5000]) pdf.save(output_path) return True def txt_to_html(self, input_path, output_path): text = Path(input_path).read_text( encoding="utf-8", errors="ignore" ) html = f"
{text}"
Path(output_path).write_text(
html,
encoding="utf-8"
)
return True
def txt_to_md(self, input_path, output_path):
text = Path(input_path).read_text(
encoding="utf-8",
errors="ignore"
)
Path(output_path).write_text(
text,
encoding="utf-8"
)
return True
def md_to_html(self, input_path, output_path):
md = Path(input_path).read_text(
encoding="utf-8",
errors="ignore"
)
html = markdown.markdown(md)
Path(output_path).write_text(
html,
encoding="utf-8"
)
return True
def md_to_text(self, input_path, output_path):
md = Path(input_path).read_text(
encoding="utf-8",
errors="ignore"
)
html = markdown.markdown(md)
soup = BeautifulSoup(html, "html.parser")
Path(output_path).write_text(
soup.get_text(),
encoding="utf-8"
)
return True
def html_to_text(self, input_path, output_path):
html = Path(input_path).read_text(
encoding="utf-8",
errors="ignore"
)
soup = BeautifulSoup(html, "html.parser")
Path(output_path).write_text(
soup.get_text(),
encoding="utf-8"
)
return True
def html_to_md(self, input_path, output_path):
html = Path(input_path).read_text(
encoding="utf-8",
errors="ignore"
)
soup = BeautifulSoup(html, "html.parser")
text = soup.get_text()
Path(output_path).write_text(
text,
encoding="utf-8"
)
return True
def docx_to_text(self, input_path, output_path):
doc = Document(input_path)
text = "\n".join(
[p.text for p in doc.paragraphs]
)
Path(output_path).write_text(
text,
encoding="utf-8"
)
return True
def pdf_to_text(self, input_path, output_path):
doc = fitz.open(input_path)
text = ""
for page in doc:
text += page.get_text()
Path(output_path).write_text(
text,
encoding="utf-8"
)
return True
def pdf_to_html(self, input_path, output_path):
doc = fitz.open(input_path)
html = ""
for page in doc:
html += page.get_text("html")
Path(output_path).write_text(
html,
encoding="utf-8"
)
return True
def _update(self, callback, value):
try:
if callback:
callback(value)
except:
pass