feat: 新增 OCRmyPDF 轉換引擎 (v0.1.14)
## 新功能 - OCRmyPDF 轉換引擎:將掃描版 PDF 轉換為可搜尋 PDF - 支援 7 種語言:en, zh-TW, zh, ja, ko, de, fr - 與 PDFMathTranslate 風格一致的 UI 格式 (pdf-<lang>) - 自動偵測頁面方向並旋轉 - 自動校正傾斜 - 跳過已有文字層的頁面 - 詳細的 5 階段處理進度輸出 ## 建置 - Dockerfile:安裝 ocrmypdf 與 Tesseract OCR 語言包 ## 文件 - 更新 OCR 功能文件 - 文件目錄結構改為中文名稱 ## 測試 - 修復 BabelDOC 和 PDFMathTranslate 測試的 OCR mock - 所有 345 個測試通過
This commit is contained in:
parent
f24eec070c
commit
a06df23b1d
53 changed files with 1427 additions and 675 deletions
|
|
@ -67,7 +67,10 @@ describe("BabelDOC converter - Chinese translation", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
// 返回超過 100 個字元,表示 PDF 不需要 OCR
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
babeldocCalled = true;
|
||||
babeldocArgs = args;
|
||||
|
||||
|
|
@ -131,7 +134,9 @@ describe("BabelDOC converter - English translation", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
babeldocArgs = args;
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
|
|
@ -181,7 +186,9 @@ describe("BabelDOC converter - Traditional Chinese", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
babeldocArgs = args;
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
|
|
@ -231,7 +238,9 @@ describe("BabelDOC converter - Output structure", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
const outputPath = args[outputIndex + 1];
|
||||
|
|
@ -267,7 +276,9 @@ describe("BabelDOC converter - Output structure", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
const outputPath = args[outputIndex + 1];
|
||||
|
|
@ -317,7 +328,9 @@ describe("BabelDOC converter - Error handling", () => {
|
|||
_args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
const error = new Error("Translation failed") as ExecFileException;
|
||||
error.code = 1;
|
||||
callback(error, "", "babeldoc: Translation error");
|
||||
|
|
@ -337,7 +350,9 @@ describe("BabelDOC converter - Error handling", () => {
|
|||
_args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
// Don't create output file, simulating failed translation
|
||||
callback(null, "Complete", "");
|
||||
}
|
||||
|
|
@ -376,7 +391,9 @@ describe("BabelDOC converter - Markdown output format", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
babeldocArgs = args;
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
|
|
@ -428,7 +445,9 @@ describe("BabelDOC converter - HTML output format", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "babeldoc") {
|
||||
if (cmd === "pdftotext") {
|
||||
callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", "");
|
||||
} else if (cmd === "babeldoc") {
|
||||
babeldocArgs = args;
|
||||
const outputIndex = args.indexOf("-o");
|
||||
if (outputIndex !== -1 && args[outputIndex + 1]) {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ describe("PDFMathTranslate converter - Chinese translation", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
pdf2zhCalled = true;
|
||||
pdf2zhArgs = args;
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ describe("PDFMathTranslate converter - English translation", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
pdf2zhArgs = args;
|
||||
const outputDirIndex = args.indexOf("-o");
|
||||
if (outputDirIndex !== -1 && args[outputDirIndex + 1]) {
|
||||
|
|
@ -165,7 +165,7 @@ describe("PDFMathTranslate converter - Japanese translation", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
pdf2zhArgs = args;
|
||||
const outputDirIndex = args.indexOf("-o");
|
||||
if (outputDirIndex !== -1 && args[outputDirIndex + 1]) {
|
||||
|
|
@ -214,7 +214,7 @@ describe("PDFMathTranslate converter - Traditional Chinese", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
pdf2zhArgs = args;
|
||||
const outputDirIndex = args.indexOf("-o");
|
||||
if (outputDirIndex !== -1 && args[outputDirIndex + 1]) {
|
||||
|
|
@ -264,7 +264,7 @@ describe("PDFMathTranslate converter - Output structure", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
const outputDirIndex = args.indexOf("-o");
|
||||
if (outputDirIndex !== -1 && args[outputDirIndex + 1]) {
|
||||
const outputDir = args[outputDirIndex + 1];
|
||||
|
|
@ -308,7 +308,7 @@ describe("PDFMathTranslate converter - Output structure", () => {
|
|||
args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
const outputDirIndex = args.indexOf("-o");
|
||||
if (outputDirIndex !== -1 && args[outputDirIndex + 1]) {
|
||||
const outputDir = args[outputDirIndex + 1];
|
||||
|
|
@ -362,7 +362,7 @@ describe("PDFMathTranslate converter - Error handling", () => {
|
|||
_args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
const error = new Error("Translation failed") as ExecFileException;
|
||||
callback(error, "", "Error: Translation service unavailable");
|
||||
}
|
||||
|
|
@ -381,7 +381,7 @@ describe("PDFMathTranslate converter - Error handling", () => {
|
|||
_args: string[],
|
||||
callback: (err: ExecFileException | null, stdout: string, stderr: string) => void,
|
||||
) => {
|
||||
if (cmd === "pdf2zh") {
|
||||
if (cmd === "pdftotext") { callback(null, "This is a comprehensive test PDF with more than enough text content to ensure that the OCR detection threshold of 100 characters is exceeded and the PDF is not treated as a scanned document requiring OCR processing.", ""); } else if (cmd === "pdf2zh") {
|
||||
// Don't create any output files
|
||||
callback(null, "Complete", "");
|
||||
} else if (cmd === "tar") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue