From 981f6dd4c651307bb8e7ed73799dd359a34e413d Mon Sep 17 00:00:00 2001 From: awwaawwa <8493196+awwaawwa@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:39:31 +0800 Subject: [PATCH 1/3] feat: Implement side-by-side PDF generation for translations - Add functionality to create dual-page PDF with original and translated content - Support side-by-side page rendering using PyMuPDF - Implement page width and height calculation for optimal layout - Add support for configurable page order in dual PDF generation --- babeldoc/document_il/backend/pdf_creater.py | 51 +++++++++++++++++---- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/babeldoc/document_il/backend/pdf_creater.py b/babeldoc/document_il/backend/pdf_creater.py index 683119a..3d99658 100644 --- a/babeldoc/document_il/backend/pdf_creater.py +++ b/babeldoc/document_il/backend/pdf_creater.py @@ -385,7 +385,48 @@ def write(self, translation_config: TranslationConfig) -> TranslateResult: f"{basename}{debug_suffix}.{translation_config.lang_out}.dual.pdf", ) translation_config.raise_if_cancelled() - dual = pymupdf.open(self.original_pdf_path) + original_pdf = pymupdf.open(self.original_pdf_path) + translated_pdf = pdf + + # Create a new PDF for side-by-side pages + dual = pymupdf.open() + page_count = min(original_pdf.page_count, translated_pdf.page_count) + + for page_id in range(page_count): + # Get pages from both PDFs + orig_page = original_pdf[page_id] + trans_page = translated_pdf[page_id] + + # Calculate total width and use max height + total_width = orig_page.rect.width + trans_page.rect.width + max_height = max(orig_page.rect.height, trans_page.rect.height) + + # Create new page with combined width + dual_page = dual.new_page(width=total_width, height=max_height) + + # Define rectangles for left and right sides + rect_left = pymupdf.Rect(0, 0, orig_page.rect.width, max_height) + rect_right = pymupdf.Rect( + orig_page.rect.width, + 0, + total_width, + max_height, + ) + + # Show original page on left and translated on right + dual_page.show_pdf_page( + rect_left, + original_pdf, + page_id, + keep_proportion=True, + ) + dual_page.show_pdf_page( + rect_right, + translated_pdf, + page_id, + keep_proportion=True, + ) + if translation_config.debug: translation_config.raise_if_cancelled() try: @@ -395,13 +436,7 @@ def write(self, translation_config: TranslationConfig) -> TranslateResult: "Failed to write debug info to dual PDF", exc_info=True, ) - dual.insert_file(pdf) - page_count = pdf.page_count - for page_id in range(page_count): - if translation_config.dual_translate_first: - dual.move_page(page_count + page_id, page_id * 2) - else: - dual.move_page(page_count + page_id, page_id * 2 + 1) + dual.save( dual_out_path, garbage=3, From cecde9a49b74f812f60a3df6a179c904743aa7ba Mon Sep 17 00:00:00 2001 From: awwaawwa <8493196+awwaawwa@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:43:06 +0800 Subject: [PATCH 2/3] refactor: Enhance dual PDF page rendering configuration - Support configurable page order in dual page generation - Improve flexibility of side-by-side PDF rendering logic --- babeldoc/document_il/backend/pdf_creater.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/babeldoc/document_il/backend/pdf_creater.py b/babeldoc/document_il/backend/pdf_creater.py index 3d99658..6b9ab33 100644 --- a/babeldoc/document_il/backend/pdf_creater.py +++ b/babeldoc/document_il/backend/pdf_creater.py @@ -405,15 +405,20 @@ def write(self, translation_config: TranslationConfig) -> TranslateResult: dual_page = dual.new_page(width=total_width, height=max_height) # Define rectangles for left and right sides - rect_left = pymupdf.Rect(0, 0, orig_page.rect.width, max_height) - rect_right = pymupdf.Rect( - orig_page.rect.width, - 0, - total_width, - max_height, + left_width = ( + orig_page.rect.width + if not translation_config.dual_translate_first + else trans_page.rect.width ) + rect_left = pymupdf.Rect(0, 0, left_width, max_height) + rect_right = pymupdf.Rect(left_width, 0, total_width, max_height) - # Show original page on left and translated on right + # Show pages according to dual_translate_first setting + if translation_config.dual_translate_first: + # Show translated page on left and original on right + rect_left, rect_right = rect_right, rect_left + + # Show original page on left and translated on right (default) dual_page.show_pdf_page( rect_left, original_pdf, From c6450946c443c2e4822f8f8f611ec55d2273383b Mon Sep 17 00:00:00 2001 From: awwaawwa <8493196+awwaawwa@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:47:19 +0800 Subject: [PATCH 3/3] chore: Bump version to 0.1.11 - Update version in pyproject.toml - Update version in uv.lock - Update version in babeldoc/__init__.py - Update version in babeldoc/main.py --- babeldoc/__init__.py | 2 +- babeldoc/main.py | 2 +- pyproject.toml | 4 ++-- uv.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/babeldoc/__init__.py b/babeldoc/__init__.py index 569b121..0c5c300 100644 --- a/babeldoc/__init__.py +++ b/babeldoc/__init__.py @@ -1 +1 @@ -__version__ = "0.1.10" +__version__ = "0.1.11" diff --git a/babeldoc/main.py b/babeldoc/main.py index 8e9cf21..2930f8f 100644 --- a/babeldoc/main.py +++ b/babeldoc/main.py @@ -20,7 +20,7 @@ from babeldoc.translation_config import TranslationConfig logger = logging.getLogger(__name__) -__version__ = "0.1.10" +__version__ = "0.1.11" def create_parser(): diff --git a/pyproject.toml b/pyproject.toml index 308c1b8..5b16c6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "BabelDOC" -version = "0.1.10" +version = "0.1.11" description = "Yet Another Document Translator" license = "AGPL-3.0" readme = "README.md" @@ -124,7 +124,7 @@ dev = [ ] [bumpver] -current_version = "0.1.10" +current_version = "0.1.11" version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]" [bumpver.file_patterns] diff --git a/uv.lock b/uv.lock index d4f69c8..d028f94 100644 --- a/uv.lock +++ b/uv.lock @@ -48,7 +48,7 @@ wheels = [ [[package]] name = "babeldoc" -version = "0.1.10" +version = "0.1.11" source = { editable = "." } dependencies = [ { name = "bitstring" },