secondary splitters
This commit is contained in:
1 parent
705db1068f
commit
f978310c4c
3 files changed
+179
-64
No files matched your search
@@ -28,8 +28,13 @@ from copienator import (
|
|||||||
from copienator.platform import launch_pdf_arranger
|
from copienator.platform import launch_pdf_arranger
|
||||||
from copienator.copy_errors import marked_copy_paths
|
from copienator.copy_errors import marked_copy_paths
|
||||||
|
|
||||||
# Keep the new shortcut available with older personal configuration files.
|
# Keep new shortcuts available with older personal configuration files.
|
||||||
PAGE_SPLITTER_KB = {"reverse_pages": "i", **PAGE_SPLITTER_KB}
|
PAGE_SPLITTER_KB = {
|
||||||
|
"reverse_pages": "i",
|
||||||
|
"add_secondary_splitter": "<Insert>",
|
||||||
|
"delete_secondary_splitter": "<Delete>",
|
||||||
|
**PAGE_SPLITTER_KB,
|
||||||
|
}
|
||||||
|
|
||||||
# --- Constants ---
|
# --- Constants ---
|
||||||
# Conversion factor: 1 cm to points (1 inch = 2.54 cm, 72 points = 1 inch)
|
# Conversion factor: 1 cm to points (1 inch = 2.54 cm, 72 points = 1 inch)
|
||||||
@@ -166,10 +171,11 @@ class PDFPreviewer:
|
|||||||
|
|
||||||
# Dynamic instructions text
|
# Dynamic instructions text
|
||||||
instructions = (
|
instructions = (
|
||||||
f"{fmt('move_left')} / {fmt('move_right')} : Move line 1cm left/right\n"
|
f"{fmt('move_left')} / {fmt('move_right')} : Move active line 0.5cm left/right\n"
|
||||||
f"'{fmt('rotate_page')}': Rotate page 180°, '{fmt('rotate_all_pages')}' : rotate all pages, '{fmt('rotate_all_files')}' : rotate all files\n"
|
f"'{fmt('rotate_page')}': Rotate page 180°, '{fmt('rotate_all_pages')}' : rotate all pages, '{fmt('rotate_all_files')}' : rotate all files\n"
|
||||||
f"{fmt('keep_left')} {fmt('next_page')} {fmt('discard_page')} {fmt('keep_right')} {fmt('keep_as_is')}: keep left, next page, keep none, keep right, keep as is\n"
|
f"{fmt('keep_left')} {fmt('next_page')} {fmt('discard_page')} {fmt('keep_right')} {fmt('keep_as_is')}: keep left, next page, keep none, keep right, keep as is\n"
|
||||||
f"{fmt('send_end')}: send page to end, '{fmt('arranger')}': pdf arranger, '{fmt('restart_file')}': restart file, '{fmt('prev_file')}': previous file\n"
|
f"{fmt('send_end')}: send page to end, '{fmt('arranger')}': pdf arranger, '{fmt('restart_file')}': restart file, '{fmt('prev_file')}': previous file\n"
|
||||||
|
f"{fmt('add_secondary_splitter')}: add secondary line, {fmt('delete_secondary_splitter')}: delete newest (arrows move newest; orange = active)\n"
|
||||||
f"'{fmt('reverse_pages')}': reverse page order and restart from the new first page\n"
|
f"'{fmt('reverse_pages')}': reverse page order and restart from the new first page\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -185,6 +191,8 @@ class PDFPreviewer:
|
|||||||
|
|
||||||
# --- Bindings ---
|
# --- Bindings ---
|
||||||
action_map = {
|
action_map = {
|
||||||
|
"add_secondary_splitter": self.add_secondary_splitter,
|
||||||
|
"delete_secondary_splitter": self.delete_secondary_splitter,
|
||||||
"move_left": self.move_line_left,
|
"move_left": self.move_line_left,
|
||||||
"move_right": self.move_line_right,
|
"move_right": self.move_line_right,
|
||||||
"rotate_page": self.rotate_page,
|
"rotate_page": self.rotate_page,
|
||||||
@@ -248,6 +256,7 @@ class PDFPreviewer:
|
|||||||
page = self.doc.load_page(self.current_page_index)
|
page = self.doc.load_page(self.current_page_index)
|
||||||
self.current_line_x = page.rect.width / 2
|
self.current_line_x = page.rect.width / 2
|
||||||
self.current_rotation = 0
|
self.current_rotation = 0
|
||||||
|
self.secondary_splitters = []
|
||||||
|
|
||||||
def load_page(self):
|
def load_page(self):
|
||||||
"""Loads and displays the current page on the canvas, scaled to fit."""
|
"""Loads and displays the current page on the canvas, scaled to fit."""
|
||||||
@@ -290,7 +299,14 @@ class PDFPreviewer:
|
|||||||
draw = ImageDraw.Draw(img)
|
draw = ImageDraw.Draw(img)
|
||||||
# The line position is scaled by the same zoom factor
|
# The line position is scaled by the same zoom factor
|
||||||
line_x_scaled = self.current_line_x * self.current_zoom
|
line_x_scaled = self.current_line_x * self.current_zoom
|
||||||
draw.line([(line_x_scaled, 0), (line_x_scaled, pix.height)], fill="red", width=3)
|
draw.line([(line_x_scaled, 0), (line_x_scaled, pix.height)],
|
||||||
|
fill="red" if self.secondary_splitters else "orange", width=3)
|
||||||
|
for index, position in enumerate(self.secondary_splitters):
|
||||||
|
x = position * self.current_zoom
|
||||||
|
active = index == len(self.secondary_splitters) - 1
|
||||||
|
draw.line([(x, 0), (x, pix.height)],
|
||||||
|
fill="orange" if active else "cyan", width=3)
|
||||||
|
draw.text((x + 5, 8), str(index + 1), fill="orange" if active else "cyan")
|
||||||
|
|
||||||
|
|
||||||
# --- Display on Canvas ---
|
# --- Display on Canvas ---
|
||||||
@@ -335,17 +351,33 @@ class PDFPreviewer:
|
|||||||
self._initialize_current_page_settings()
|
self._initialize_current_page_settings()
|
||||||
self.load_page()
|
self.load_page()
|
||||||
|
|
||||||
def move_line_left(self, event=None):
|
def add_secondary_splitter(self, event=None):
|
||||||
"""Moves the split line to the left."""
|
"""Start a new line in the widest remaining interval of this page."""
|
||||||
self.current_line_x = max(0, self.current_line_x - CM_TO_POINTS / 2)
|
width = self.doc.load_page(self.current_page_index).rect.width
|
||||||
|
boundaries = sorted({0, width, self.current_line_x, *self.secondary_splitters})
|
||||||
|
left, right = max(zip(boundaries, boundaries[1:]), key=lambda pair: pair[1] - pair[0])
|
||||||
|
self.secondary_splitters.append((left + right) / 2)
|
||||||
self.load_page()
|
self.load_page()
|
||||||
|
|
||||||
def move_line_right(self, event=None):
|
def delete_secondary_splitter(self, event=None):
|
||||||
"""Moves the split line to the right."""
|
if self.secondary_splitters:
|
||||||
page = self.doc.load_page(self.current_page_index)
|
self.secondary_splitters.pop()
|
||||||
self.current_line_x = min(page.rect.width, self.current_line_x + CM_TO_POINTS / 2)
|
|
||||||
self.load_page()
|
self.load_page()
|
||||||
|
|
||||||
|
def _move_active_line(self, delta):
|
||||||
|
width = self.doc.load_page(self.current_page_index).rect.width
|
||||||
|
if self.secondary_splitters:
|
||||||
|
self.secondary_splitters[-1] = min(width, max(0, self.secondary_splitters[-1] + delta))
|
||||||
|
else:
|
||||||
|
self.current_line_x = min(width, max(0, self.current_line_x + delta))
|
||||||
|
self.load_page()
|
||||||
|
|
||||||
|
def move_line_left(self, event=None):
|
||||||
|
self._move_active_line(-CM_TO_POINTS / 2)
|
||||||
|
|
||||||
|
def move_line_right(self, event=None):
|
||||||
|
self._move_active_line(CM_TO_POINTS / 2)
|
||||||
|
|
||||||
def rotate_page(self, event=None):
|
def rotate_page(self, event=None):
|
||||||
"""Toggles the page rotation between 0 and 180 degrees."""
|
"""Toggles the page rotation between 0 and 180 degrees."""
|
||||||
self.current_rotation = 180 if self.current_rotation == 0 else 0
|
self.current_rotation = 180 if self.current_rotation == 0 else 0
|
||||||
@@ -388,6 +420,7 @@ class PDFPreviewer:
|
|||||||
"""Saves the settings for the current page and moves to the next."""
|
"""Saves the settings for the current page and moves to the next."""
|
||||||
self.page_settings.append({
|
self.page_settings.append({
|
||||||
"line_x": self.current_line_x,
|
"line_x": self.current_line_x,
|
||||||
|
"secondary_splitters": list(self.secondary_splitters),
|
||||||
"rotation": self.current_rotation,
|
"rotation": self.current_rotation,
|
||||||
"keep": keep
|
"keep": keep
|
||||||
})
|
})
|
||||||
@@ -477,50 +510,32 @@ class PDFPreviewer:
|
|||||||
line_x = settings['line_x']
|
line_x = settings['line_x']
|
||||||
rotation_settings = settings['rotation']
|
rotation_settings = settings['rotation']
|
||||||
keep = settings['keep']
|
keep = settings['keep']
|
||||||
rotation = (page.rotation + rotation_settings +
|
# Bake source rotation and the preview's extra rotation into content,
|
||||||
self.file_rotation + self.global_rotation) % 360
|
# so all cut coordinates refer to the displayed page.
|
||||||
|
page.remove_rotation()
|
||||||
|
page.set_rotation((rotation_settings + self.file_rotation + self.global_rotation) % 360)
|
||||||
|
page.remove_rotation()
|
||||||
|
width, height = page.rect.width, page.rect.height
|
||||||
|
sides = []
|
||||||
if keep == "as_is":
|
if keep == "as_is":
|
||||||
doc_full = pymupdf.open()
|
sides.append((0, width, self.split_filename_left(i)))
|
||||||
page_full = doc_full.new_page(width=page.rect.width, height=page.rect.height)
|
|
||||||
page_full.show_pdf_page(page_full.rect, self.doc, i)
|
|
||||||
page_full.set_rotation(rotation)
|
|
||||||
|
|
||||||
output_path_full = self.split_filename_left(i)
|
|
||||||
doc_full.save(output_path_full)
|
|
||||||
doc_full.close()
|
|
||||||
continue # Skip left/right generation
|
|
||||||
|
|
||||||
# --- Create Left Part ---
|
|
||||||
if rotation == 0:
|
|
||||||
rect_left = pymupdf.Rect(0, 0, line_x, page.rect.height)
|
|
||||||
else:
|
else:
|
||||||
rect_left = pymupdf.Rect(page.rect.width-line_x, 0, page.rect.width, page.rect.height)
|
if keep in {"both", "left"} and line_x > 0:
|
||||||
|
sides.append((0, line_x, self.split_filename_left(i)))
|
||||||
|
if keep in {"both", "right"} and line_x < width:
|
||||||
|
sides.append((line_x, width, self.split_filename_right(i)))
|
||||||
|
|
||||||
if (keep == "both" or keep == "left") and line_x > 0:
|
for left, right, output_path in sides:
|
||||||
|
cuts = settings.get("secondary_splitters", [])
|
||||||
doc_left = pymupdf.open()
|
boundaries = [left, *sorted({x for x in cuts if left < x < right}), right]
|
||||||
page_left = doc_left.new_page(width=rect_left.width, height=rect_left.height)
|
# Each side is a multi-page PDF, keeping its subpages together
|
||||||
page_left.show_pdf_page(page_left.rect, self.doc, i, clip=rect_left)
|
# when the existing booklet ordering moves this side.
|
||||||
page_left.set_rotation(rotation)
|
with pymupdf.open() as output:
|
||||||
|
for x0, x1 in zip(boundaries, boundaries[1:]):
|
||||||
output_path_left = self.split_filename_left(i)
|
clip = pymupdf.Rect(x0, 0, x1, height)
|
||||||
doc_left.save(output_path_left)
|
target = output.new_page(width=clip.width, height=clip.height)
|
||||||
doc_left.close()
|
target.show_pdf_page(target.rect, self.doc, i, clip=clip)
|
||||||
|
output.save(output_path)
|
||||||
# --- Create Right Part ---
|
|
||||||
if rotation == 0:
|
|
||||||
rect_right = pymupdf.Rect(line_x, 0, page.rect.width, page.rect.height)
|
|
||||||
else:
|
|
||||||
rect_right = pymupdf.Rect(0, 0, page.rect.width-line_x, page.rect.height)
|
|
||||||
if (keep == "both" or keep == "right") and line_x < page.rect.width:
|
|
||||||
doc_right = pymupdf.open()
|
|
||||||
page_right = doc_right.new_page(width=rect_right.width, height=rect_right.height)
|
|
||||||
page_right.show_pdf_page(page_right.rect, self.doc, i, clip=rect_right)
|
|
||||||
page_right.set_rotation(rotation)
|
|
||||||
output_path_right = self.split_filename_right(i)
|
|
||||||
doc_right.save(output_path_right)
|
|
||||||
doc_right.close()
|
|
||||||
|
|
||||||
self.doc.close()
|
self.doc.close()
|
||||||
print(f"\nProcessing complete. Files are in '{self.split_dir}' directory.")
|
print(f"\nProcessing complete. Files are in '{self.split_dir}' directory.")
|
||||||
@@ -531,6 +546,11 @@ class PDFPreviewer:
|
|||||||
ps = self.page_settings
|
ps = self.page_settings
|
||||||
ri = 0
|
ri = 0
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
|
def copy_side(source, destination):
|
||||||
|
if os.path.isfile(source):
|
||||||
|
shutil.copy2(source, destination)
|
||||||
|
|
||||||
while i < len(ps):
|
while i < len(ps):
|
||||||
psk = ps[i]['keep']
|
psk = ps[i]['keep']
|
||||||
|
|
||||||
@@ -539,32 +559,32 @@ class PDFPreviewer:
|
|||||||
|
|
||||||
# 1. Page de garde (Extérieur Droit)
|
# 1. Page de garde (Extérieur Droit)
|
||||||
if ps[i]['keep'] in ["both", "right"]:
|
if ps[i]['keep'] in ["both", "right"]:
|
||||||
shutil.copy2(self.split_filename_right(i), self.reorder_filename(ri))
|
copy_side(self.split_filename_right(i), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
|
|
||||||
# 2. Intérieur Gauche
|
# 2. Intérieur Gauche
|
||||||
if ps[i+1]['keep'] in ["both", "left"]:
|
if ps[i+1]['keep'] in ["both", "left"]:
|
||||||
shutil.copy2(self.split_filename_left(i+1), self.reorder_filename(ri))
|
copy_side(self.split_filename_left(i+1), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
|
|
||||||
# 3. Intérieur Droit
|
# 3. Intérieur Droit
|
||||||
if ps[i+1]['keep'] in ["both", "right"]:
|
if ps[i+1]['keep'] in ["both", "right"]:
|
||||||
shutil.copy2(self.split_filename_right(i+1), self.reorder_filename(ri))
|
copy_side(self.split_filename_right(i+1), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
|
|
||||||
# 4. Dos de la copie (Extérieur Gauche)
|
# 4. Dos de la copie (Extérieur Gauche)
|
||||||
if ps[i]['keep'] in ["both", "left"]:
|
if ps[i]['keep'] in ["both", "left"]:
|
||||||
shutil.copy2(self.split_filename_left(i), self.reorder_filename(ri))
|
copy_side(self.split_filename_left(i), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
|
|
||||||
i += 2
|
i += 2
|
||||||
else:
|
else:
|
||||||
# Si c'est une page simple (ou as_is)
|
# Si c'est une page simple (ou as_is)
|
||||||
if psk in ["left", "both", "as_is"]:
|
if psk in ["left", "both", "as_is"]:
|
||||||
shutil.copy2(self.split_filename_left(i), self.reorder_filename(ri))
|
copy_side(self.split_filename_left(i), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
if psk in ["right", "both"]:
|
if psk in ["right", "both"]:
|
||||||
shutil.copy2(self.split_filename_right(i), self.reorder_filename(ri))
|
copy_side(self.split_filename_right(i), self.reorder_filename(ri))
|
||||||
ri += 1
|
ri += 1
|
||||||
i += 1
|
i += 1
|
||||||
# def reorder_pdfs(self):
|
# def reorder_pdfs(self):
|
||||||
@@ -577,25 +597,25 @@ class PDFPreviewer:
|
|||||||
# # Si c'est une copie double
|
# # Si c'est une copie double
|
||||||
# if (ps[i]['keep'] == "both" or ps[i]['keep'] == "right") \
|
# if (ps[i]['keep'] == "both" or ps[i]['keep'] == "right") \
|
||||||
# and i < len(ps)-1 and (ps[i+1]['keep'] != "right"):
|
# and i < len(ps)-1 and (ps[i+1]['keep'] != "right"):
|
||||||
# shutil.copy2(self.split_filename_right(i), self.reorder_filename(ri))
|
# copy_side(self.split_filename_right(i), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# if ps[i+1]['keep'] != "none":
|
# if ps[i+1]['keep'] != "none":
|
||||||
# shutil.copy2(self.split_filename_left(i+1), self.reorder_filename(ri))
|
# copy_side(self.split_filename_left(i+1), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# if ps[i+1]['keep'] != "left":
|
# if ps[i+1]['keep'] != "left":
|
||||||
# shutil.copy2(self.split_filename_right(i+1), self.reorder_filename(ri))
|
# copy_side(self.split_filename_right(i+1), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# if ps[i]['keep'] == "both":
|
# if ps[i]['keep'] == "both":
|
||||||
# shutil.copy2(self.split_filename_left(i), self.reorder_filename(ri))
|
# copy_side(self.split_filename_left(i), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# i += 2
|
# i += 2
|
||||||
# else:
|
# else:
|
||||||
# psk = ps[i]['keep']
|
# psk = ps[i]['keep']
|
||||||
# if psk == "left" or psk == "both" or psk == "as_is":
|
# if psk == "left" or psk == "both" or psk == "as_is":
|
||||||
# shutil.copy2(self.split_filename_left(i), self.reorder_filename(ri))
|
# copy_side(self.split_filename_left(i), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# if psk == "right" or psk == "both":
|
# if psk == "right" or psk == "both":
|
||||||
# shutil.copy2(self.split_filename_right(i), self.reorder_filename(ri))
|
# copy_side(self.split_filename_right(i), self.reorder_filename(ri))
|
||||||
# ri += 1
|
# ri += 1
|
||||||
# i += 1
|
# i += 1
|
||||||
|
|
||||||
|
|||||||
@@ -49,9 +49,12 @@ THINKING_LEVEL_FLASH = "medium"
|
|||||||
# Modèle pour des choses dures
|
# Modèle pour des choses dures
|
||||||
MODEL_PRO_ID = "gemini-3.8-flash"
|
MODEL_PRO_ID = "gemini-3.8-flash"
|
||||||
THINKING_LEVEL_PRO = "medium"
|
THINKING_LEVEL_PRO = "medium"
|
||||||
|
# THINKING_LEVEL_PRO = "high"
|
||||||
# MODEL_PRO_ID = "gemini-3.1-pro-preview"
|
# MODEL_PRO_ID = "gemini-3.1-pro-preview"
|
||||||
|
|
||||||
PAGE_SPLITTER_KB = {
|
PAGE_SPLITTER_KB = {
|
||||||
|
"add_secondary_splitter": "<Insert>", # Current page only; arrows move newest
|
||||||
|
"delete_secondary_splitter": "<Delete>", # Remove newest secondary splitter
|
||||||
"move_left": "<Left>",
|
"move_left": "<Left>",
|
||||||
"move_right": "<Right>",
|
"move_right": "<Right>",
|
||||||
"rotate_page": "r",
|
"rotate_page": "r",
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
import pymupdf
|
||||||
|
|
||||||
|
from copienator.commands.page_splitter import CM_TO_POINTS, PDFPreviewer
|
||||||
|
|
||||||
|
|
||||||
|
class SecondarySplitterTests(unittest.TestCase):
|
||||||
|
def preview(self):
|
||||||
|
preview = PDFPreviewer.__new__(PDFPreviewer)
|
||||||
|
preview.doc = pymupdf.open()
|
||||||
|
self.addCleanup(lambda: None if preview.doc.is_closed else preview.doc.close())
|
||||||
|
for number in range(2):
|
||||||
|
page = preview.doc.new_page(width=400, height=100)
|
||||||
|
for column in range(4):
|
||||||
|
page.insert_text((column * 100 + 30, 50), f'{number}{column}')
|
||||||
|
preview.current_page_index = 0
|
||||||
|
preview.file_rotation = preview.global_rotation = 0
|
||||||
|
preview.page_settings = []
|
||||||
|
preview.load_page = Mock()
|
||||||
|
preview._initialize_current_page_settings()
|
||||||
|
return preview
|
||||||
|
|
||||||
|
def export(self, preview):
|
||||||
|
with tempfile.TemporaryDirectory() as directory:
|
||||||
|
preview.base_name = 'copy'
|
||||||
|
preview.split_dir = Path(directory) / 'split'
|
||||||
|
preview.reorder_dir = Path(directory) / 'reorder'
|
||||||
|
preview.final_file = Path(directory) / 'result.pdf'
|
||||||
|
preview.output_dir = None
|
||||||
|
preview.split_pdf()
|
||||||
|
preview.reorder_pdfs()
|
||||||
|
preview.concate_files()
|
||||||
|
with pymupdf.open(preview.final_file) as output:
|
||||||
|
return [(page.get_text().strip(), page.rect.width) for page in output]
|
||||||
|
|
||||||
|
def settings(self, keep='both', cuts=None, rotation=0, line=200):
|
||||||
|
return dict(keep=keep, secondary_splitters=cuts or [], rotation=rotation, line_x=line)
|
||||||
|
|
||||||
|
def test_newest_line_moves_and_deletes_and_settings_are_page_local(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.add_secondary_splitter()
|
||||||
|
self.assertEqual(preview.secondary_splitters, [100])
|
||||||
|
preview.add_secondary_splitter()
|
||||||
|
self.assertEqual(preview.secondary_splitters, [100, 300])
|
||||||
|
preview.move_line_left()
|
||||||
|
self.assertAlmostEqual(preview.secondary_splitters[-1], 300 - CM_TO_POINTS / 2)
|
||||||
|
self.assertEqual(preview.current_line_x, 200)
|
||||||
|
preview.delete_secondary_splitter()
|
||||||
|
preview.move_line_right()
|
||||||
|
self.assertAlmostEqual(preview.secondary_splitters[-1], 100 + CM_TO_POINTS / 2)
|
||||||
|
saved = preview.secondary_splitters.copy()
|
||||||
|
preview.confirm_and_next_page()
|
||||||
|
self.assertEqual(preview.page_settings[0]['secondary_splitters'], saved)
|
||||||
|
self.assertEqual(preview.secondary_splitters, [])
|
||||||
|
preview.delete_secondary_splitter()
|
||||||
|
preview.move_line_left()
|
||||||
|
self.assertAlmostEqual(preview.current_line_x, 200 - CM_TO_POINTS / 2)
|
||||||
|
|
||||||
|
def test_subpages_replace_each_side_in_booklet_order(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.page_settings = [self.settings(cuts=[300, 100]), self.settings(cuts=[100, 300])]
|
||||||
|
self.assertEqual(self.export(preview), [(label, 100) for label in ['02', '03', '10', '11', '12', '13', '00', '01']])
|
||||||
|
|
||||||
|
def test_discarded_sides_and_duplicate_boundary_cuts(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.page_settings = [self.settings('left', [0, 100, 100, 200, 300, 400]), self.settings('none', [100])]
|
||||||
|
self.assertEqual(self.export(preview), [('00', 100), ('01', 100)])
|
||||||
|
|
||||||
|
def test_keep_as_is_ignores_main_splitter_but_applies_secondary_cuts(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.page_settings = [self.settings('as_is', [100, 300]), self.settings('right', [300])]
|
||||||
|
self.assertEqual(self.export(preview), [('00', 100), ('01\n02', 200), ('03', 100), ('12', 100), ('13', 100)])
|
||||||
|
|
||||||
|
def test_rotated_preview_orders_subpages_visually_left_to_right(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.page_settings = [self.settings(cuts=[100, 300], rotation=180), self.settings('none')]
|
||||||
|
self.assertEqual(self.export(preview), [(label, 100) for label in ['01', '00', '03', '02']])
|
||||||
|
|
||||||
|
def test_source_rotation_matches_preview(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.doc[0].set_rotation(180)
|
||||||
|
preview.page_settings = [self.settings(cuts=[100, 300]), self.settings('none')]
|
||||||
|
self.assertEqual(self.export(preview), [(label, 100) for label in ['01', '00', '03', '02']])
|
||||||
|
|
||||||
|
def test_main_splitter_at_edge_does_not_break_reordering(self):
|
||||||
|
preview = self.preview()
|
||||||
|
preview.page_settings = [self.settings(cuts=[100, 200, 300], line=0), self.settings('none')]
|
||||||
|
self.assertEqual(self.export(preview), [(label, 100) for label in ['00', '01', '02', '03']])
|
||||||
Reference in new issue
Block a user