diff --git a/pkgs/development/python-modules/ocrmypdf/paths.patch b/pkgs/development/python-modules/ocrmypdf/paths.patch index db61e5bd328b..164b7f66a4dc 100644 --- a/pkgs/development/python-modules/ocrmypdf/paths.patch +++ b/pkgs/development/python-modules/ocrmypdf/paths.patch @@ -1,8 +1,8 @@ diff --git a/src/ocrmypdf/_exec/ghostscript.py b/src/ocrmypdf/_exec/ghostscript.py -index b48f2080..beabcf4b 100644 +index eaa48117..30201d97 100644 --- a/src/ocrmypdf/_exec/ghostscript.py +++ b/src/ocrmypdf/_exec/ghostscript.py -@@ -35,7 +35,7 @@ COLOR_CONVERSION_STRATEGIES = frozenset( +@@ -31,7 +31,7 @@ COLOR_CONVERSION_STRATEGIES = frozenset( ] ) # Ghostscript executable - gswin32c is not supported @@ -12,7 +12,7 @@ index b48f2080..beabcf4b 100644 log = logging.getLogger(__name__) diff --git a/src/ocrmypdf/_exec/jbig2enc.py b/src/ocrmypdf/_exec/jbig2enc.py -index 736de67e..d8c24ebd 100644 +index 1c6dd5fe..b689a091 100644 --- a/src/ocrmypdf/_exec/jbig2enc.py +++ b/src/ocrmypdf/_exec/jbig2enc.py @@ -15,7 +15,7 @@ from ocrmypdf.subprocess import get_version, run @@ -24,7 +24,16 @@ index 736de67e..d8c24ebd 100644 except CalledProcessError as e: # TeX Live for Windows provides an incompatible jbig2.EXE which may # be on the PATH. -@@ -32,7 +32,7 @@ def available(): +@@ -33,7 +33,7 @@ def available(): + + def convert_group(cwd, infiles, out_prefix, threshold): + args = [ +- 'jbig2', ++ '@jbig2@', + '-b', + out_prefix, + '--symbol-mode', # symbol mode (lossy) +@@ -50,7 +50,7 @@ def convert_group(cwd, infiles, out_prefix, threshold): def convert_single(cwd, infile, outfile, threshold): @@ -56,10 +65,10 @@ index 5b8600d0..fcad771b 100644 '--skip-if-larger', '--quality', diff --git a/src/ocrmypdf/_exec/tesseract.py b/src/ocrmypdf/_exec/tesseract.py -index d41a0af7..b189b0de 100644 +index 102bdab8..bfef4400 100644 --- a/src/ocrmypdf/_exec/tesseract.py +++ b/src/ocrmypdf/_exec/tesseract.py -@@ -116,7 +116,7 @@ class TesseractVersion(Version): +@@ -95,7 +95,7 @@ class TesseractVersion(Version): def version() -> Version: @@ -68,7 +77,7 @@ index d41a0af7..b189b0de 100644 def has_thresholding() -> bool: -@@ -134,7 +134,7 @@ def get_languages() -> set[str]: +@@ -113,7 +113,7 @@ def get_languages() -> set[str]: msg += output return msg @@ -77,7 +86,7 @@ index d41a0af7..b189b0de 100644 try: proc = run( args_tess, -@@ -156,7 +156,7 @@ def get_languages() -> set[str]: +@@ -135,7 +135,7 @@ def get_languages() -> set[str]: def tess_base_args(langs: list[str], engine_mode: int | None) -> list[str]: diff --git a/pkgs/development/python-modules/ocrmypdf_16/default.nix b/pkgs/development/python-modules/ocrmypdf_16/default.nix new file mode 100644 index 000000000000..a700f0bd8358 --- /dev/null +++ b/pkgs/development/python-modules/ocrmypdf_16/default.nix @@ -0,0 +1,113 @@ +{ + lib, + buildPythonPackage, + deprecation, + fetchFromGitHub, + fpdf2, + ghostscript_headless, + hatch-vcs, + hatchling, + hypothesis, + img2pdf, + jbig2enc, + packaging, + pdfminer-six, + pillow-heif, + pikepdf, + pillow, + pluggy, + pngquant, + pydantic, + pypdfium2, + pytest-xdist, + pytestCheckHook, + rich, + reportlab, + replaceVars, + tesseract, + uharfbuzz, + unpaper, + installShellFiles, +}: + +buildPythonPackage rec { + pname = "ocrmypdf"; + version = "16.13.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "ocrmypdf"; + repo = "OCRmyPDF"; + tag = "v${version}"; + # The content of .git_archival.txt is substituted upon tarball creation, + # which creates indeterminism if master no longer points to the tag. + # See https://github.com/ocrmypdf/OCRmyPDF/issues/841 + postFetch = '' + rm "$out/.git_archival.txt" + ''; + hash = "sha256-xxVtncIQ72echi0VogfgqwfB8IA7JEKVUV2lmL1coeU="; + }; + + patches = [ + ./use-pillow-heif.patch + (replaceVars ./paths.patch { + gs = lib.getExe ghostscript_headless; + jbig2 = lib.getExe jbig2enc; + pngquant = lib.getExe pngquant; + tesseract = lib.getExe tesseract; + unpaper = lib.getExe unpaper; + }) + ]; + + build-system = [ + hatch-vcs + hatchling + ]; + + nativeBuildInputs = [ installShellFiles ]; + + dependencies = [ + deprecation + fpdf2 + img2pdf + packaging + pdfminer-six + pillow-heif + pikepdf + pillow + pluggy + pydantic + pypdfium2 + rich + uharfbuzz + ]; + + nativeCheckInputs = [ + hypothesis + pytest-xdist + pytestCheckHook + reportlab + ]; + + pythonImportsCheck = [ "ocrmypdf" ]; + + postInstall = '' + installShellCompletion --cmd ocrmypdf \ + --bash misc/completion/ocrmypdf.bash \ + --fish misc/completion/ocrmypdf.fish + ''; + + meta = { + homepage = "https://github.com/ocrmypdf/OCRmyPDF"; + description = "Adds an OCR text layer to scanned PDF files, allowing them to be searched"; + license = with lib.licenses; [ + mpl20 + mit + ]; + maintainers = with lib.maintainers; [ + dotlambda + ]; + changelog = "https://github.com/ocrmypdf/OCRmyPDF/blob/${src.tag}/docs/release_notes.md"; + mainProgram = "ocrmypdf"; + }; +} diff --git a/pkgs/development/python-modules/ocrmypdf_16/paths.patch b/pkgs/development/python-modules/ocrmypdf_16/paths.patch new file mode 100644 index 000000000000..164b7f66a4dc --- /dev/null +++ b/pkgs/development/python-modules/ocrmypdf_16/paths.patch @@ -0,0 +1,119 @@ +diff --git a/src/ocrmypdf/_exec/ghostscript.py b/src/ocrmypdf/_exec/ghostscript.py +index eaa48117..30201d97 100644 +--- a/src/ocrmypdf/_exec/ghostscript.py ++++ b/src/ocrmypdf/_exec/ghostscript.py +@@ -31,7 +31,7 @@ COLOR_CONVERSION_STRATEGIES = frozenset( + ] + ) + # Ghostscript executable - gswin32c is not supported +-GS = 'gswin64c' if os.name == 'nt' else 'gs' ++GS = '@gs@' + + + log = logging.getLogger(__name__) +diff --git a/src/ocrmypdf/_exec/jbig2enc.py b/src/ocrmypdf/_exec/jbig2enc.py +index 1c6dd5fe..b689a091 100644 +--- a/src/ocrmypdf/_exec/jbig2enc.py ++++ b/src/ocrmypdf/_exec/jbig2enc.py +@@ -15,7 +15,7 @@ from ocrmypdf.subprocess import get_version, run + + def version() -> Version: + try: +- version = get_version('jbig2', regex=r'jbig2enc (\d+(\.\d+)*).*') ++ version = get_version('@jbig2@', regex=r'jbig2enc (\d+(\.\d+)*).*') + except CalledProcessError as e: + # TeX Live for Windows provides an incompatible jbig2.EXE which may + # be on the PATH. +@@ -33,7 +33,7 @@ def available(): + + def convert_group(cwd, infiles, out_prefix, threshold): + args = [ +- 'jbig2', ++ '@jbig2@', + '-b', + out_prefix, + '--symbol-mode', # symbol mode (lossy) +@@ -50,7 +50,7 @@ def convert_group(cwd, infiles, out_prefix, threshold): + + + def convert_single(cwd, infile, outfile, threshold): +- args = ['jbig2', '--pdf', '-t', str(threshold), infile] ++ args = ['@jbig2@', '--pdf', '-t', str(threshold), infile] + with open(outfile, 'wb') as fstdout: + proc = run(args, cwd=cwd, stdout=fstdout, stderr=PIPE) + proc.check_returncode() +diff --git a/src/ocrmypdf/_exec/pngquant.py b/src/ocrmypdf/_exec/pngquant.py +index 5b8600d0..fcad771b 100644 +--- a/src/ocrmypdf/_exec/pngquant.py ++++ b/src/ocrmypdf/_exec/pngquant.py +@@ -15,7 +15,7 @@ from ocrmypdf.subprocess import get_version, run + + + def version() -> Version: +- return Version(get_version('pngquant', regex=r'(\d+(\.\d+)*).*')) ++ return Version(get_version('@pngquant@', regex=r'(\d+(\.\d+)*).*')) + + + def available(): +@@ -37,7 +37,7 @@ def quantize(input_file: Path, output_file: Path, quality_min: int, quality_max: + """ + with open(input_file, 'rb') as input_stream: + args = [ +- 'pngquant', ++ '@pngquant@', + '--force', + '--skip-if-larger', + '--quality', +diff --git a/src/ocrmypdf/_exec/tesseract.py b/src/ocrmypdf/_exec/tesseract.py +index 102bdab8..bfef4400 100644 +--- a/src/ocrmypdf/_exec/tesseract.py ++++ b/src/ocrmypdf/_exec/tesseract.py +@@ -95,7 +95,7 @@ class TesseractVersion(Version): + + + def version() -> Version: +- return TesseractVersion(get_version('tesseract', regex=r'tesseract\s(.+)')) ++ return TesseractVersion(get_version('@tesseract@', regex=r'tesseract\s(.+)')) + + + def has_thresholding() -> bool: +@@ -113,7 +113,7 @@ def get_languages() -> set[str]: + msg += output + return msg + +- args_tess = ['tesseract', '--list-langs'] ++ args_tess = ['@tesseract@', '--list-langs'] + try: + proc = run( + args_tess, +@@ -135,7 +135,7 @@ def get_languages() -> set[str]: + + + def tess_base_args(langs: list[str], engine_mode: int | None) -> list[str]: +- args = ['tesseract'] ++ args = ['@tesseract@'] + if langs: + args.extend(['-l', '+'.join(langs)]) + if engine_mode is not None: +diff --git a/src/ocrmypdf/_exec/unpaper.py b/src/ocrmypdf/_exec/unpaper.py +index a5a92f4c..6cf56eb3 100644 +--- a/src/ocrmypdf/_exec/unpaper.py ++++ b/src/ocrmypdf/_exec/unpaper.py +@@ -48,7 +48,7 @@ class UnpaperImageTooLargeError(Exception): + + + def version() -> Version: +- return Version(get_version('unpaper', regex=r'(?m).*?(\d+(\.\d+)(\.\d+)?)')) ++ return Version(get_version('@unpaper@', regex=r'(?m).*?(\d+(\.\d+)(\.\d+)?)')) + + + @contextmanager +@@ -70,7 +70,7 @@ def _setup_unpaper_io(input_file: Path) -> Iterator[tuple[Path, Path, Path]]: + def run_unpaper( + input_file: Path, output_file: Path, *, dpi: DecFloat, mode_args: list[str] + ) -> None: +- args_unpaper = ['unpaper', '-v', '--dpi', str(round(dpi, 6))] + mode_args ++ args_unpaper = ['@unpaper@', '-v', '--dpi', str(round(dpi, 6))] + mode_args + + with _setup_unpaper_io(input_file) as (input_png, output_pnm, tmpdir): + # To prevent any shenanigans from accepting arbitrary parameters in diff --git a/pkgs/development/python-modules/ocrmypdf_16/use-pillow-heif.patch b/pkgs/development/python-modules/ocrmypdf_16/use-pillow-heif.patch new file mode 100644 index 000000000000..0137ea02453d --- /dev/null +++ b/pkgs/development/python-modules/ocrmypdf_16/use-pillow-heif.patch @@ -0,0 +1,26 @@ +diff --git a/pyproject.toml b/pyproject.toml +index 2caa0e75..f6fcf60a 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -16,7 +16,7 @@ dependencies = [ + "img2pdf>=0.5", + "packaging>=20", + "pdfminer.six>=20220319", +- "pi-heif", # Heif image format - maintainers: if this is removed, it will NOT break ++ "pillow-heif", # Heif image format - maintainers: if this is removed, it will NOT break + "pikepdf>=10", + "Pillow>=10.0.1", + "pluggy>=1", +diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py +index 90524d58..0be5a0f8 100644 +--- a/src/ocrmypdf/_pipeline.py ++++ b/src/ocrmypdf/_pipeline.py +@@ -42,7 +42,7 @@ from ocrmypdf.pdfinfo import Colorspace, Encoding, PageInfo, PdfInfo + from ocrmypdf.pluginspec import OrientationConfidence + + try: +- from pi_heif import register_heif_opener ++ from pillow_heif import register_heif_opener + except ImportError: + + def register_heif_opener(): diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 30338cfb5c1d..ecfe48679990 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -11206,6 +11206,10 @@ self: super: with self; { ocrmypdf = callPackage ../development/python-modules/ocrmypdf { tesseract = pkgs.tesseract5; }; + ocrmypdf_16 = callPackage ../development/python-modules/ocrmypdf_16 { + tesseract = pkgs.tesseract5; + }; + od = callPackage ../development/python-modules/od { }; odc-geo = callPackage ../development/python-modules/odc-geo { };