MarkItDown

Stars

Microsoft 开源的轻量级 Python 文件转换工具,把 PDF、Word、PowerPoint、Excel、图片、音频、HTML、压缩包和网页等内容统一转换为适合 LLM 与文本分析流水线消费的 Markdown。

Document → MarkdownPython · File URILLM Data Pipelines
FILE URI · WINDOWS PATH NORMALIZATION

先解码盘符,再决定它是不是绝对路径

百分号编码改变了盘符被看见的时机;路径转换必须在解码之后识别 Windows drive,并在绝对化之前移除多余的前导分隔符。

INPUT · FILE URIfile:///C%3A/Temp/example.md
%3Apercent-encoded colon
parsed.path = /C%3A/Temp/example.md
BEFORE · DETECT TOO EARLY
  1. 01DOS drive checkmiss
  2. 02url2pathname()/C:/...
  3. 03abspath()prepend C:
C:\C:\Temp\example.mdINVALID ARGUMENT
AFTER · DECODE, THEN NORMALIZEpath = url2pathname(parsed.path)
Windows/ or \path[2] = :
path = path[1:] → abspath(path)C:\Temp\example.md

POSIX unchanged · UNC unchanged

重复盘符

编码冒号绕过早期 DOS Drive 检查

Windows 下的 `file:///C%3A/Temp/example.md` 会在盘符冒号仍处于百分号编码状态时进入路径转换。旧实现先尝试识别 DOS 盘符,再由 `url2pathname()` 解码;识别阶段看不到 `C:`,解码后路径仍带前导分隔符,随后 `abspath()` 又补上当前盘符,最终得到 `C:\C:\Temp\example.md` 并以 `OSError: Invalid argument` 终止转换。

修复边界

只匹配 Windows 的 /C:/ 路径形态

问题不在于所有绝对路径都应去掉首字符,而在于解码后才出现的 Windows 盘符语法。修复必须发生在 `url2pathname()` 之后、`abspath()` 之前,并同时满足三个条件:运行于 Windows、路径以 `/` 或 `\` 开头、紧随其后的第二个字符位置是盘符冒号。这样才能只处理 `/C:/...`,而不改变 POSIX 根路径、UNC 网络路径或普通相对路径。

转换顺序

Decode、Normalize、Abspath 各司其职

先保存 `url2pathname(parsed.path)` 的结果;仅当 `os.name == "nt"`、首字符为路径分隔符且 `path[2:3] == ":"` 时移除一个前导分隔符,再交给 `os.path.abspath()`。回归测试通过 `ntpath`、Windows 版 `url2pathname` 与隔离的 `os` 替身,在任意 CI 平台复现 Windows 路径语义,并断言编码 URI 精确解析为 `C:\Temp\example.md`。

路径兼容

编码 URI 恢复,POSIX 与 UNC 保持不变

百分号编码与未编码的 Windows 盘符 URI 现在会收敛到同一个本地路径,`convert_uri()` 不再因重复盘符而在打开文件前失败;POSIX 与 UNC 路径保持原有行为。合并版本通过 337 项测试、4 项跳过,并完成类型检查、全仓预提交检查与三项合并检查。