Add comprehensive format integrity tests for various converters

This commit is contained in:
Your Name 2026-01-23 23:15:36 +08:00
parent 47968f6c80
commit 80ab233d15
8 changed files with 1384 additions and 192 deletions

View file

@ -87,8 +87,9 @@ export async function convert(
const runMinerU = (useTableMode: boolean): Promise<void> => {
return new Promise((resolve, reject) => {
// Build MinerU command arguments
// MinerU CLI: mineru -p <input> -o <output_dir> -m auto
const args = ["-p", filePath, "-o", mineruOutputDir, "-m", "auto"];
// MinerU CLI: mineru -p <input> -o <output_dir> -m pipeline
// 注意:使用 pipeline 模式而非 auto避免 VLM 模型未配置的問題
const args = ["-p", filePath, "-o", mineruOutputDir, "-m", "pipeline"];
// 表格模式支援(可能與某些 vLLM 版本不相容)
if (useTableMode) {

View file

@ -18,12 +18,18 @@ import type { ExecFileFn } from "./types";
* - deu: 德文
* - fra: 法文
*
* UI PDFMathTranslate
* pdf-en, pdf-zh-TW, pdf-ja
* UI
* - pdf-ocr: 自動檢測語言
* - pdf-en, pdf-zh-TW, pdf-ja
*
*
* 使 Tesseract eng+chi_tra+chi_sim+jpn+kor+deu+fra
*
*/
// 內建支援的 OCR 語言(與 PDFMathTranslate 風格一致)
// 內建支援的 OCR 語言
const SUPPORTED_LANGUAGES = [
"ocr", // 自動檢測(多語言)- 推薦
"en", // English
"zh-TW", // 繁體中文
"zh", // 簡體中文
@ -35,6 +41,10 @@ const SUPPORTED_LANGUAGES = [
// Tesseract 語言代碼映射UI 代碼 → Tesseract 代碼)
const LANG_MAP: Record<string, string> = {
// 自動檢測模式:使用所有已安裝的語言包
// 順序:英文優先(最常見),然後是 CJK 語言,最後是歐洲語言
ocr: "eng+chi_tra+chi_sim+jpn+kor+deu+fra",
auto: "eng+chi_tra+chi_sim+jpn+kor+deu+fra",
en: "eng",
"zh-TW": "chi_tra",
zh: "chi_sim",
@ -53,6 +63,11 @@ export const properties = {
},
};
// 建立大小寫不敏感的語言映射查找表
const LANG_MAP_LOWER: Record<string, string> = Object.fromEntries(
Object.entries(LANG_MAP).map(([k, v]) => [k.toLowerCase(), v]),
);
/**
* convertTo OCR
* @param convertTo "pdf-en" "pdf-zh-TW"
@ -60,14 +75,14 @@ export const properties = {
*/
function extractOcrLanguage(convertTo: string): string {
// convertTo 格式: pdf-<lang>
const match = convertTo.match(/^pdf-(.+)$/);
const match = convertTo.match(/^pdf-(.+)$/i);
if (!match || !match[1]) {
throw new Error(`Invalid convertTo format: ${convertTo}. Expected pdf-<lang>`);
}
const uiLang = match[1];
// 轉換為 Tesseract 語言代碼
const tessLang = LANG_MAP[uiLang] || uiLang.replace(/-/g, "_");
// 轉換為 Tesseract 語言代碼(大小寫不敏感查找)
const tessLang = LANG_MAP_LOWER[uiLang.toLowerCase()] || uiLang.replace(/-/g, "_");
return tessLang;
}
@ -111,7 +126,13 @@ function runOcrMyPdf(
// 階段 2準備 OCR 參數
console.log(`[OCRmyPDF] 📋 階段 2/5準備 OCR 參數`);
console.log(`[OCRmyPDF] ✅ OCR 語言: ${lang}`);
const isMultiLang = lang.includes("+");
if (isMultiLang) {
console.log(`[OCRmyPDF] ✅ OCR 模式: 多語言自動檢測`);
console.log(`[OCRmyPDF] ✅ 語言包: ${lang.split("+").join(", ")}`);
} else {
console.log(`[OCRmyPDF] ✅ OCR 語言: ${lang}`);
}
const args = [
"-l",

View file

@ -44,7 +44,7 @@ const tools = [
formatter: (s: string) => s.split("\n")[0],
},
{
cmd: "magick --version",
cmd: "convert --version",
name: "ImageMagick",
errorMsg: "ImageMagick is not installed.",
formatter: (s: string) => s.split("\n")[0]?.replace("Version: ", ""),
@ -98,10 +98,10 @@ const tools = [
formatter: (s: string) => s.split("\n")[0],
},
{
cmd: "heif-info -v",
cmd: "dpkg -l libheif1 | tail -1 | awk '{print $3}'",
name: "libheif",
errorMsg: "libheif is not installed",
formatter: (s: string) => `libheif v${s.split("\n")[0]}`,
formatter: (s: string) => `libheif v${s.trim()}`,
},
{
cmd: "potrace -v",
@ -116,10 +116,13 @@ const tools = [
formatter: (s: string) => s.split("\n")[0],
},
{
cmd: "msgconvert --version",
cmd: "which msgconvert && dpkg -l libemail-outlook-message-perl | tail -1 | awk '{print $3}'",
name: "msgconvert",
errorMsg: "msgconvert (libemail-outlook-message-perl) is not installed",
formatter: (s: string) => s.split("\n")[0],
formatter: (s: string) => {
const lines = s.split("\n").filter((l) => l.trim());
return `msgconvert v${lines[lines.length - 1] || "unknown"}`;
},
},
{
cmd: "bun -v",