158 lines
4.1 KiB
Python
158 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
MarkItDown 文档转换工具封装
|
||
支持各种格式转换为 Markdown
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import subprocess
|
||
from pathlib import Path
|
||
from typing import Optional
|
||
|
||
|
||
def convert_file(input_path: str, output_path: Optional[str] = None) -> str:
|
||
"""
|
||
将文件转换为 Markdown
|
||
|
||
Args:
|
||
input_path: 输入文件路径
|
||
output_path: 输出文件路径(可选,默认输出到同目录同名.md)
|
||
|
||
Returns:
|
||
输出文件路径
|
||
"""
|
||
input_file = Path(input_path)
|
||
|
||
if not input_file.exists():
|
||
raise FileNotFoundError(f"文件不存在: {input_path}")
|
||
|
||
# 如果没有指定输出路径,使用同名.md
|
||
if output_path is None:
|
||
output_file = input_file.with_suffix('.md')
|
||
else:
|
||
output_file = Path(output_path)
|
||
|
||
# 调用 markitdown
|
||
cmd = ['markitdown', str(input_file), '-o', str(output_file)]
|
||
|
||
try:
|
||
result = subprocess.run(
|
||
cmd,
|
||
capture_output=True,
|
||
text=True,
|
||
timeout=300 # 5分钟超时
|
||
)
|
||
|
||
if result.returncode == 0:
|
||
print(f"✅ 转换成功: {input_file.name} -> {output_file.name}")
|
||
return str(output_file)
|
||
else:
|
||
print(f"❌ 转换失败: {result.stderr}")
|
||
return None
|
||
|
||
except subprocess.TimeoutExpired:
|
||
print("❌ 转换超时")
|
||
return None
|
||
except Exception as e:
|
||
print(f"❌ 转换异常: {e}")
|
||
return None
|
||
|
||
|
||
def convert_to_text(input_path: str) -> str:
|
||
"""
|
||
将文件转换为 Markdown 文本(不保存文件)
|
||
|
||
Args:
|
||
input_path: 输入文件路径
|
||
|
||
Returns:
|
||
Markdown 文本内容
|
||
"""
|
||
input_file = Path(input_path)
|
||
|
||
if not input_file.exists():
|
||
raise FileNotFoundError(f"文件不存在: {input_path}")
|
||
|
||
cmd = ['markitdown', str(input_file)]
|
||
|
||
try:
|
||
result = subprocess.run(
|
||
cmd,
|
||
capture_output=True,
|
||
text=True,
|
||
timeout=300
|
||
)
|
||
|
||
if result.returncode == 0:
|
||
return result.stdout
|
||
else:
|
||
print(f"❌ 转换失败: {result.stderr}")
|
||
return ""
|
||
|
||
except Exception as e:
|
||
print(f"❌ 转换异常: {e}")
|
||
return ""
|
||
|
||
|
||
def batch_convert(directory: str, pattern: str = "*") -> list:
|
||
"""
|
||
批量转换目录中的文件
|
||
|
||
Args:
|
||
directory: 目录路径
|
||
pattern: 文件匹配模式(如 "*.pdf")
|
||
|
||
Returns:
|
||
成功转换的文件列表
|
||
"""
|
||
dir_path = Path(directory)
|
||
|
||
if not dir_path.exists():
|
||
raise FileNotFoundError(f"目录不存在: {directory}")
|
||
|
||
files = list(dir_path.glob(pattern))
|
||
converted = []
|
||
|
||
print(f"找到 {len(files)} 个文件,开始转换...")
|
||
|
||
for file in files:
|
||
if file.is_file():
|
||
output = convert_file(str(file))
|
||
if output:
|
||
converted.append(output)
|
||
|
||
print(f"\n✅ 成功转换 {len(converted)}/{len(files)} 个文件")
|
||
return converted
|
||
|
||
|
||
def main():
|
||
"""命令行入口"""
|
||
import argparse
|
||
|
||
parser = argparse.ArgumentParser(description='文档转 Markdown 工具')
|
||
parser.add_argument('input', help='输入文件路径')
|
||
parser.add_argument('-o', '--output', help='输出文件路径(可选)')
|
||
parser.add_argument('-t', '--text', action='store_true', help='仅输出文本,不保存文件')
|
||
parser.add_argument('-b', '--batch', help='批量转换目录')
|
||
parser.add_argument('-p', '--pattern', default='*', help='批量转换时的文件匹配模式')
|
||
|
||
args = parser.parse_args()
|
||
|
||
if args.batch:
|
||
# 批量模式
|
||
batch_convert(args.batch, args.pattern)
|
||
elif args.text:
|
||
# 仅输出文本
|
||
text = convert_to_text(args.input)
|
||
print(text)
|
||
else:
|
||
# 单文件转换
|
||
output = convert_file(args.input, args.output)
|
||
if output:
|
||
print(f"输出文件: {output}")
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|