From 5e2206bae76fe4b98f353676fdb37d8092a305e4 Mon Sep 17 00:00:00 2001 From: Dima Kuznetsov Date: Sat, 20 Feb 2021 02:55:35 +0200 Subject: [PATCH] Allow --sidecar along --pages (#735) --- src/ocrmypdf/_pipeline.py | 26 +++++++++-- src/ocrmypdf/_validation.py | 2 - tests/test_pipeline.py | 87 +++++++++++++++++++++++++++++++++++++ tests/test_validation.py | 2 - 4 files changed, 110 insertions(+), 7 deletions(-) diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py index 28ddf6e2..3ca5e97f 100644 --- a/src/ocrmypdf/_pipeline.py +++ b/src/ocrmypdf/_pipeline.py @@ -808,11 +808,27 @@ def optimize_pdf(input_file: Path, context: PdfContext): return output_file +def enumerate_compress_ranges(iterable): + skipped_from = None + for index, txt_file in enumerate(iterable): + index += 1 + if txt_file: + if skipped_from is not None: + yield (skipped_from, index - 1), None + skipped_from = None + yield (index, index), txt_file + else: + if skipped_from is None: + skipped_from = index + if skipped_from is not None: + yield (skipped_from, index), None + + def merge_sidecars(txt_files: Iterable[Optional[Path]], context: PdfContext): output_file = context.get_path('sidecar.txt') with open(output_file, 'w', encoding="utf-8") as stream: - for page_num, txt_file in enumerate(txt_files): - if page_num != 0: + for (frm, to), txt_file in enumerate_compress_ranges(txt_files): + if frm != 1: stream.write('\f') # Form feed between pages if txt_file: with open(txt_file, 'r', encoding="utf-8") as in_: @@ -825,7 +841,11 @@ def merge_sidecars(txt_files: Iterable[Optional[Path]], context: PdfContext): else: stream.write(txt) else: - stream.write(f'[OCR skipped on page {(page_num + 1)}]') + if frm != to: + pages = f'{frm}-{to}' + else: + pages = f'{frm}' + stream.write(f'[OCR skipped on page(s) {pages}]') return output_file diff --git a/src/ocrmypdf/_validation.py b/src/ocrmypdf/_validation.py index a6ee9a08..2e2cd529 100644 --- a/src/ocrmypdf/_validation.py +++ b/src/ocrmypdf/_validation.py @@ -184,8 +184,6 @@ def check_options_ocr_behavior(options): ) if exclusive_options >= 2: raise BadArgsError("Choose only one of --force-ocr, --skip-text, --redo-ocr.") - if options.pages and options.sidecar: - raise BadArgsError("--pages and --sidecar are mutually exclusive") if options.pages: options.pages = _pages_from_ranges(options.pages) diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index 64254e84..becef2c4 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -61,3 +61,90 @@ def test_dpi_needed(image, text, vector, result, rgb_image, outdir): assert _pipeline.get_canvas_square_dpi(pi[0], mock) == result assert _pipeline.get_page_square_dpi(pi[0], mock) == result + + +@pytest.mark.parametrize( + # Name for nicer -v output + 'name,input,output', + ( + ( + 'empty_input', + # Input: + (), + # Output: + (), + ), + ( + 'no_values', + # Input: + ('', '', '', '', ''), + # Output: + ( + ((1, 5), None), + ), + ), + ( + 'no_empty_values', + # Input: + ('v', 'w', 'x', 'y', 'z'), + # Output: + ( + ((1, 1), 'v'), + ((2, 2), 'w'), + ((3, 3), 'x'), + ((4, 4), 'y'), + ((5, 5), 'z'), + ), + ), + ( + 'skip_head', + # Input: + ('', '', 'x', 'y', 'z'), + # Output: + ( + ((1, 2), None), + ((3, 3), 'x'), + ((4, 4), 'y'), + ((5, 5), 'z'), + ), + ), + ( + 'skip_tail', + # Input: + ('x', 'y', 'z', '', ''), + # Output: + ( + ((1, 1), 'x'), + ((2, 2), 'y'), + ((3, 3), 'z'), + ((4, 5), None), + ), + ), + ( + 'range_in_middle', + # Input: + ('x', '', '', '', 'y'), + # Output: + ( + ((1, 1), 'x'), + ((2, 4), None), + ((5, 5), 'y'), + ), + ), + ( + 'range_in_middle_2', + # Input: + ('x', '', '', 'y', '', '', '', 'z'), + # Output: + ( + ((1, 1), 'x'), + ((2, 3), None), + ((4, 4), 'y'), + ((5, 7), None), + ((8, 8), 'z'), + ), + ), + ), +) +def test_enumerate_compress_ranges(name, input, output): + assert output == tuple(_pipeline.enumerate_compress_ranges(input)) \ No newline at end of file diff --git a/tests/test_validation.py b/tests/test_validation.py index f7ce5286..6eb53e48 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -90,8 +90,6 @@ def test_mutex_options(): vd.check_options_ocr_behavior(make_opts(redo_ocr=True, skip_text=True)) with pytest.raises(BadArgsError): vd.check_options_ocr_behavior(make_opts(redo_ocr=True, force_ocr=True)) - with pytest.raises(BadArgsError): - vd.check_options_ocr_behavior(make_opts(pages='1-3', sidecar='file.txt')) def test_optimizing(caplog):