Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fca0c71dc | ||
|
|
944d99bdc1 | ||
|
|
5bb6e1c5d7 | ||
|
|
8d7a8f0f98 | ||
|
|
b9dd0a5e3c | ||
|
|
6949ad2c5d | ||
|
|
b3324c3b4e | ||
|
|
b38cac6931 | ||
|
|
bb4c47e707 | ||
|
|
5e1e2497ab | ||
|
|
cd910fbf21 | ||
|
|
1225269a4b |
+32
-10
@@ -19,8 +19,10 @@ jobs:
|
||||
test_linux:
|
||||
name: Test ${{ matrix.os }} with Python ${{ matrix.python }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
strategy:
|
||||
matrix:
|
||||
experimental: [false]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
python: "3.10"
|
||||
@@ -34,6 +36,9 @@ jobs:
|
||||
tesseract5: true
|
||||
- os: ubuntu-latest
|
||||
python: "pypy3.10"
|
||||
- os: ubuntu-22.04
|
||||
python: "3.13"
|
||||
experimental: true
|
||||
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
@@ -49,6 +54,7 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: "pip"
|
||||
allow-prereleases: ${{ matrix.experimental }}
|
||||
|
||||
- name: Install Tesseract 5
|
||||
if: matrix.tesseract5
|
||||
@@ -258,29 +264,45 @@ jobs:
|
||||
|
||||
create_release:
|
||||
name: Create GitHub release
|
||||
needs: [wheel_sdist_linux, test_linux, test_macos, test_windows]
|
||||
needs: [upload_pypi]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
|
||||
permissions:
|
||||
# Required to create a release
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- name: Create Release
|
||||
id: create-release
|
||||
uses: shogo82148/actions-create-release@v1
|
||||
|
||||
- name: Upload Assets
|
||||
uses: shogo82148/actions-upload-release-asset@v1
|
||||
- name: Sign the dists with Sigstore
|
||||
uses: sigstore/gh-action-sigstore-python@v2.1.1
|
||||
with:
|
||||
upload_url: ${{ steps.create-release.outputs.upload_url }}
|
||||
asset_path: |
|
||||
./dist/*.whl
|
||||
inputs: >-
|
||||
./dist/*.tar.gz
|
||||
./dist/*.whl
|
||||
|
||||
- name: Create GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: >-
|
||||
gh release create
|
||||
'${{ github.ref_name }}'
|
||||
--repo '${{ github.repository }}'
|
||||
--notes ""
|
||||
|
||||
- name: Upload artifact signatures to GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
# Upload to GitHub Release using the `gh` CLI.
|
||||
# `dist/` contains the built packages, and the
|
||||
# sigstore-produced signatures and certificates.
|
||||
run: >-
|
||||
gh release upload
|
||||
'${{ github.ref_name }}' dist/**
|
||||
--repo '${{ github.repository }}'
|
||||
|
||||
docker_ubuntu:
|
||||
name: Build Ubuntu-based Docker image
|
||||
|
||||
@@ -44,3 +44,4 @@ docs/_build/
|
||||
docs/_static/
|
||||
docs/_templates/
|
||||
docs/Makefile
|
||||
src/ocrmypdf/_version.py
|
||||
+1
-1
@@ -135,7 +135,7 @@ Users may need to customize the script to meet their requirements.
|
||||
"OCR_ON_SUCCESS_ARCHIVE", "This will move the processed original file to ``OCR_ARCHIVE_DIRECTORY`` if the exit code is 0 (OK). Note that ``OCR_ON_SUCCESS_DELETE`` takes precedence over this option, i.e. if both options are set, the input file will be deleted."
|
||||
"OCR_OUTPUT_DIRECTORY_YEAR_MONTH", "This will place files in the output in ``{output}/{year}/{month}/{filename}``"
|
||||
"OCR_DESKEW", "Apply deskew to crooked input PDFs"
|
||||
"OCR_JSON_SETTINGS", "A JSON string specifying any other arguments for ``ocrmypdf.ocr``, e.g. ``'OCR_JSON_SETTINGS={""rotate_pages"": true}'``."
|
||||
"OCR_JSON_SETTINGS", "A JSON string specifying any other arguments for ``ocrmypdf.ocr``, e.g. ``'OCR_JSON_SETTINGS={""rotate_pages"": true, ""optimize"": "3"}'``."
|
||||
"OCR_POLL_NEW_FILE_SECONDS", "Polling interval"
|
||||
"OCR_LOGLEVEL", "Level of log messages to report"
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ OCRmyPDF is includes in MacPorts:
|
||||
sudo port install ocrmypdf
|
||||
|
||||
Note that while this will install tesseract you will need to install
|
||||
the appropriate tesseract `language ports <https://ports.macports.org/search/?selected_facets=categories_exact%3Atextproc&installed_file=&q=tesseract&name=on>`__.
|
||||
the appropriate tesseract `language ports <https://ports.macports.org/search/?selected_facets=categories_exact%3Atextproc&installed_file=&q=tesseract&name=on>`__.
|
||||
|
||||
Manual installation on macOS
|
||||
----------------------------
|
||||
@@ -640,8 +640,7 @@ environment:
|
||||
|
||||
pip install git+https://github.com/ocrmypdf/OCRmyPDF.git
|
||||
|
||||
Or, to install in `development
|
||||
mode <https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#working-in-development-mode>`__,
|
||||
Or, to install in editable mode
|
||||
allowing customization of OCRmyPDF, use the ``-e`` flag:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -38,12 +38,13 @@ on ARM and x86_64. Performance may be poor on other processor architectures.
|
||||
Versioning scheme
|
||||
-----------------
|
||||
|
||||
OCRmyPDF uses setuptools-scm for versioning, which derives the version from
|
||||
OCRmyPDF uses hatch-vcs for versioning, which derives the version from
|
||||
Git as a single source of truth. This may be unsuitable for some distributions, e.g.
|
||||
to indicate that your distribution modifies OCRmyPDF in some way.
|
||||
|
||||
You can patch the ``__version__`` variable in ``src/ocrmypdf/_version.py`` if
|
||||
necessary.
|
||||
necessary, or set the environment variable ``SETUPTOOLS_SCM_PRETEND_VERSION``
|
||||
to the required version, if you need to override versioning for some reason.
|
||||
|
||||
jbig2enc
|
||||
--------
|
||||
|
||||
+9
-12
@@ -29,6 +29,9 @@ conventions. Note that: plugins installed with as setuptools entrypoints are
|
||||
not checked currently, because OCRmyPDF assumes you may not want to enable
|
||||
plugins for all files.
|
||||
|
||||
See [OCRmyPDF-EasyOCR](https://github.com/ocrmypdf/OCRmyPDF-EasyOCR) for an
|
||||
example of a straightforward, fully working plugin.
|
||||
|
||||
Script plugins
|
||||
==============
|
||||
|
||||
@@ -70,14 +73,15 @@ similar to ``pytest`` packages such as ``pytest-cov`` (the package) and
|
||||
module), just like pytest plugins. At the same time, please make it clear
|
||||
that your package is not official.
|
||||
|
||||
Setuptools plugins
|
||||
==================
|
||||
Plugins
|
||||
=======
|
||||
|
||||
You can also create a plugin that OCRmyPDF will always automatically load if both are
|
||||
installed in the same virtual environment, using a setuptools entrypoint.
|
||||
installed in the same virtual environment, using a project entrypoint.
|
||||
OCRmyPDF uses the entrypoint namespace "ocrmypdf".
|
||||
|
||||
Your package's ``pyproject.toml`` would need to contain the following, for a plugin
|
||||
named ``ocrmypdf-exampleplugin``:
|
||||
For example, ``pyproject.toml`` would need to contain the following, for a plugin named
|
||||
``ocrmypdf-exampleplugin``:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
@@ -87,13 +91,6 @@ named ``ocrmypdf-exampleplugin``:
|
||||
[project.entry-points."ocrmypdf"]
|
||||
exampleplugin = "exampleplugin.pluginmodule"
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
# equivalent setup.cfg
|
||||
[options.entry_points]
|
||||
ocrmypdf =
|
||||
exampleplugin = exampleplugin.pluginmodule
|
||||
|
||||
Plugin requirements
|
||||
===================
|
||||
|
||||
|
||||
@@ -30,6 +30,17 @@ OCRmyPDF typically supports the three most recent Python versions.
|
||||
|
||||
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
|
||||
|
||||
v16.5.0
|
||||
=======
|
||||
|
||||
- Fixed issue with interpreting PDFs that have images with array masks.
|
||||
:issue:`1377`
|
||||
- Enabled testing on Python 3.13.
|
||||
- Fixed a test that did not work correctly but still passed. :issue:`1382`
|
||||
- Improved "PDF/A conversion failed" warning message to better describe implications.
|
||||
- Updated documentation to better explain OCR_JSON_SETTINGS in batch processing.
|
||||
- Build backend changed from setuptools to hatchling.
|
||||
|
||||
v16.4.3
|
||||
=======
|
||||
|
||||
|
||||
+7
-9
@@ -1,8 +1,8 @@
|
||||
# SPDX-FileCopyrightText: 2022 James R. Barlow
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
[build-system]
|
||||
requires = ["setuptools >= 61", "setuptools_scm[toml] >= 7.0.5", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
requires = ["hatchling", "hatch-vcs"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "ocrmypdf"
|
||||
@@ -46,6 +46,7 @@ keywords = ["PDF", "OCR", "optical character recognition", "PDF/A", "scanning"]
|
||||
Documentation = "https://ocrmypdf.readthedocs.io/"
|
||||
Source = "https://github.com/ocrmypdf/OCRmyPDF"
|
||||
Tracker = "https://github.com/ocrmypdf/OCRmyPDF/issues"
|
||||
Changelog = "https://github.com/ocrmypdf/OCRmyPDF/docs/release_notes.rst"
|
||||
|
||||
[project.optional-dependencies]
|
||||
docs = ["sphinx", "sphinx-issues", "sphinx-rtd-theme"]
|
||||
@@ -67,14 +68,11 @@ webservice = ["Flask>=2.0.1"]
|
||||
[project.scripts]
|
||||
ocrmypdf = "ocrmypdf.__main__:run"
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
ocrmypdf = ["data/sRGB.icc", "py.typed"]
|
||||
[tool.hatch.version]
|
||||
source = "vcs"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
namespaces = false
|
||||
|
||||
[tool.setuptools_scm]
|
||||
[tool.hatch.build.hooks.vcs]
|
||||
version-file = "src/ocrmypdf/_version.py"
|
||||
|
||||
[tool.distutils.bdist_wheel]
|
||||
python-tag = "py310"
|
||||
|
||||
@@ -9,11 +9,12 @@ from pluggy import HookimplMarker as _HookimplMarker
|
||||
|
||||
from ocrmypdf import helpers, hocrtransform, pdfa, pdfinfo
|
||||
from ocrmypdf._concurrent import Executor
|
||||
from ocrmypdf._defaults import PROGRAM_NAME
|
||||
from ocrmypdf._jobcontext import PageContext, PdfContext
|
||||
from ocrmypdf._pipelines._common import (
|
||||
configure_debug_logging,
|
||||
)
|
||||
from ocrmypdf._version import PROGRAM_NAME, __version__
|
||||
from ocrmypdf._version import __version__
|
||||
from ocrmypdf.api import (
|
||||
Verbosity,
|
||||
configure_logging,
|
||||
@@ -37,7 +38,6 @@ from ocrmypdf.pluginspec import OcrEngine, OrientationConfidence
|
||||
|
||||
hookimpl = _HookimplMarker('ocrmypdf')
|
||||
|
||||
|
||||
__all__ = [
|
||||
'__version__',
|
||||
'BadArgsError',
|
||||
|
||||
@@ -6,3 +6,5 @@ DEFAULT_LANGUAGE = 'eng'
|
||||
|
||||
# Default rotation threshold
|
||||
DEFAULT_ROTATE_PAGES_THRESHOLD = 14.0
|
||||
|
||||
PROGRAM_NAME = 'OCRmyPDF'
|
||||
|
||||
@@ -15,8 +15,8 @@ from pikepdf import Dictionary, Name, Pdf
|
||||
from pikepdf import __version__ as PIKEPDF_VERSION
|
||||
from pikepdf.models.metadata import PdfMetadata, encode_pdf_date
|
||||
|
||||
from ocrmypdf._defaults import PROGRAM_NAME
|
||||
from ocrmypdf._jobcontext import PdfContext
|
||||
from ocrmypdf._version import PROGRAM_NAME
|
||||
from ocrmypdf._version import __version__ as OCRMYPF_VERSION
|
||||
from ocrmypdf.languages import iso_639_2_from_3
|
||||
|
||||
|
||||
@@ -441,7 +441,8 @@ def report_output_pdf(options, start_input_file, optimize_messages) -> ExitCode:
|
||||
log.info("Output file is a %s (as expected)", pdfa_info['conformance'])
|
||||
else:
|
||||
log.warning(
|
||||
"Output file is okay but is not PDF/A (seems to be %s)",
|
||||
"Output file is a valid PDF, but conversion to PDF/A did not "
|
||||
"succeed (issue: %s)",
|
||||
pdfa_info['conformance'],
|
||||
)
|
||||
return ExitCode.pdfa_conversion_failed
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022 James R. Barlow
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
"""Get version by introspecting package information.
|
||||
|
||||
OCRmyPDF uses setuptools_scm to derive version from git tags.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from importlib.metadata import version as _package_version
|
||||
|
||||
PROGRAM_NAME = 'ocrmypdf'
|
||||
|
||||
# Official PEP 396
|
||||
__version__ = _package_version('ocrmypdf')
|
||||
+1
-1
@@ -10,7 +10,7 @@ from collections.abc import Callable, Mapping
|
||||
from typing import Any, TypeVar
|
||||
|
||||
from ocrmypdf._defaults import DEFAULT_ROTATE_PAGES_THRESHOLD
|
||||
from ocrmypdf._version import PROGRAM_NAME as _PROGRAM_NAME
|
||||
from ocrmypdf._defaults import PROGRAM_NAME as _PROGRAM_NAME
|
||||
from ocrmypdf._version import __version__ as _VERSION
|
||||
|
||||
T = TypeVar('T', int, float)
|
||||
|
||||
@@ -382,8 +382,12 @@ class ImageInfo:
|
||||
self._height = max(smask.get(Name.Height, 0), self._height)
|
||||
if (mask := pim.obj.get(Name.Mask, None)) is not None:
|
||||
# If the image has a /Mask entry, it has an explicit mask.
|
||||
self._width = max(mask.get(Name.Width, 0), self._width)
|
||||
self._height = max(mask.get(Name.Height, 0), self._height)
|
||||
# /Mask can be a Stream or an Array. If it's a Stream,
|
||||
# use its /Width and /Height if they are larger than the main
|
||||
# image's.
|
||||
if isinstance(mask, Stream):
|
||||
self._width = max(mask.get(Name.Width, 0), self._width)
|
||||
self._height = max(mask.get(Name.Height, 0), self._height)
|
||||
|
||||
# If /ImageMask is true, then this image is a stencil mask
|
||||
# (Images that draw with this stencil mask will have a reference to
|
||||
|
||||
@@ -239,7 +239,9 @@ def make_rotate_test(imagefile, outdir, prefix, image_angle, page_angle):
|
||||
@pytest.mark.parametrize('image_angle', (0, 90, 180, 270))
|
||||
def test_rotate_page_level(image_angle, page_angle, resources, outdir, caplog):
|
||||
reference = make_rotate_test(resources / 'typewriter.png', outdir, 'ref', 0, 0)
|
||||
test = make_rotate_test(resources, outdir, 'test', image_angle, page_angle)
|
||||
test = make_rotate_test(
|
||||
resources / 'typewriter.png', outdir, 'test', image_angle, page_angle
|
||||
)
|
||||
out = test.with_suffix('.out.pdf')
|
||||
|
||||
exitcode = run_ocrmypdf_api(
|
||||
|
||||
Reference in New Issue
Block a user