Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a613722e96 | ||
|
|
ad0126185f | ||
|
|
be45871d10 | ||
|
|
252221fd8b | ||
|
|
d25c49ba81 | ||
|
|
5112e9e857 | ||
|
|
757b72b0af | ||
|
|
75c5b92cb9 | ||
|
|
d673126994 | ||
|
|
d89a633ba7 | ||
|
|
710d797299 | ||
|
|
fc75254c60 | ||
|
|
f453e94f14 | ||
|
|
8f8aaa93ed | ||
|
|
a90b9e669f | ||
|
|
e4f69cc1d6 | ||
|
|
a5852ba199 | ||
|
|
051b9da991 | ||
|
|
139d9f9841 | ||
|
|
532d65a355 | ||
|
|
9de38afb13 | ||
|
|
913c939dc9 | ||
|
|
9db9a3d6ec | ||
|
|
8423bd549b | ||
|
|
336d274a54 | ||
|
|
906d77b389 | ||
|
|
9416e850ff | ||
|
|
fd3248869c | ||
|
|
2a09a668f6 | ||
|
|
e788dde607 | ||
|
|
173a80864d | ||
|
|
aa115a8be3 | ||
|
|
e0441c4aa1 | ||
|
|
a861c58da2 | ||
|
|
b1306bd7a8 | ||
|
|
3a6eb383dc | ||
|
|
6c942ecefd | ||
|
|
a25f8ecc62 | ||
|
|
e1f4813d94 | ||
|
|
af526f078d | ||
|
|
16438c1312 | ||
|
|
dd6cb7ce20 | ||
|
|
653e2e23df | ||
|
|
a2033698fa | ||
|
|
ec1d585d40 | ||
|
|
a4e1f8e1f3 | ||
|
|
2e155c31bf | ||
|
|
e09ae9c68a | ||
|
|
c5bf1dd90d | ||
|
|
e96770c5e4 | ||
|
|
f4f0f3c022 | ||
|
|
0a42934c08 | ||
|
|
d8f47768f9 | ||
|
|
c9594a4a5f | ||
|
|
873f915212 | ||
|
|
079c162a96 | ||
|
|
25c8c4656f | ||
|
|
ffcae9a1a0 | ||
|
|
6e71fe1186 | ||
|
|
0885799010 | ||
|
|
8ffc99f648 | ||
|
|
2261c51eff | ||
|
|
5c470778a3 | ||
|
|
4124889f36 | ||
|
|
a23c22b0e8 | ||
|
|
dd1f5f7215 | ||
|
|
5e2206bae7 | ||
|
|
079ee86d43 | ||
|
|
3692868004 | ||
|
|
064f935699 | ||
|
|
8770fff968 | ||
|
|
82de78b6b0 | ||
|
|
2a52c6dec2 | ||
|
|
2898879be7 | ||
|
|
18e613657c | ||
|
|
a48ca556c7 | ||
|
|
9cba738b48 | ||
|
|
bccf2f423f | ||
|
|
390fdf8c05 | ||
|
|
166de3086b | ||
|
|
206c675df6 | ||
|
|
6c8f9223e9 | ||
|
|
85c6a974ca | ||
|
|
dccdcfaa91 | ||
|
|
b1da09f141 | ||
|
|
42c84531e4 | ||
|
|
a9ad805347 | ||
|
|
16bda74974 | ||
|
|
d274d88929 | ||
|
|
327df5cbbc | ||
|
|
386cabff00 | ||
|
|
3bd5054634 | ||
|
|
6a8dd65aa2 | ||
|
|
6083b4f0a7 | ||
|
|
1a3ce59476 | ||
|
|
c395436ba3 | ||
|
|
8d23d0b441 | ||
|
|
c6a2716cdb | ||
|
|
5545bae76f | ||
|
|
7bccb8c748 | ||
|
|
173c0d1274 | ||
|
|
6953f32465 | ||
|
|
26b4d9bb4b | ||
|
|
34e564cd7d |
+5
-3
@@ -10,8 +10,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential autoconf automake libtool \
|
||||
libleptonica-dev \
|
||||
zlib1g-dev \
|
||||
python3 \
|
||||
python3-dev \
|
||||
python3-distutils \
|
||||
libffi-dev \
|
||||
libqpdf-dev \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git
|
||||
@@ -62,7 +64,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr-fra \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-spa \
|
||||
unpaper
|
||||
unpaper \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -76,6 +79,5 @@ COPY --from=builder /app/misc/watcher.py /app/
|
||||
COPY --from=builder /app/setup.cfg /app/setup.py /app/README.md /app/
|
||||
COPY --from=builder /app/requirements /app/requirements
|
||||
COPY --from=builder /app/tests /app/tests
|
||||
COPY --from=builder /app/src /app/src
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/ocrmypdf"]
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
name: Test and deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci
|
||||
- release/*
|
||||
tags:
|
||||
- v*
|
||||
paths-ignore:
|
||||
- README*
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test_linux:
|
||||
name: Test ${{ matrix.os }} with Python ${{ matrix.python }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04] #, ubuntu-20.04]
|
||||
python: ["3.6"] #, "3.7", "3.8", "3.9"]
|
||||
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
PYTHON: ${{ matrix.python }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0" # 0=all, needed for setuptools-scm to resolve version tags
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: Install common packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
curl \
|
||||
ghostscript \
|
||||
img2pdf \
|
||||
libffi-dev \
|
||||
liblept5 \
|
||||
libsm6 libxext6 libxrender-dev \
|
||||
pngquant \
|
||||
poppler-utils \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-eng \
|
||||
unpaper \
|
||||
zlib1g
|
||||
|
||||
- name: Install Ubuntu 18.04 packages
|
||||
if: matrix.os == 'ubuntu-18.04'
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libexempi3
|
||||
|
||||
- name: Install Ubuntu 20.04 packages
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libexempi8
|
||||
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install -r requirements/main.txt -r requirements/test.txt .
|
||||
|
||||
- name: Report versions
|
||||
run: |
|
||||
tesseract --version
|
||||
gs --version
|
||||
pngquant --version
|
||||
unpaper --version
|
||||
img2pdf --version
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
python -m pytest --cov-report xml --cov=ocrmypdf --cov=tests/ -n0 tests/
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
files: ./coverage.xml
|
||||
env_vars: OS,PYTHON
|
||||
|
||||
test_macos:
|
||||
name: Test macOS
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest]
|
||||
python: ["3.9"]
|
||||
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
PYTHON: ${{ matrix.python }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0" # 0=all, needed for setuptools-scm to resolve version tags
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: Install Homebrew deps
|
||||
run: |
|
||||
brew update
|
||||
brew install \
|
||||
exempi \
|
||||
ghostscript \
|
||||
jbig2enc \
|
||||
leptonica \
|
||||
openjpeg \
|
||||
pngquant \
|
||||
tesseract
|
||||
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements/main.txt -r requirements/test.txt .
|
||||
|
||||
- name: Report versions
|
||||
run: |
|
||||
tesseract --version
|
||||
gs --version
|
||||
pngquant --version
|
||||
img2pdf --version
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
python -m pytest --cov-report xml --cov=ocrmypdf --cov=tests/ -n0 tests/
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
files: ./coverage.xml
|
||||
env_vars: OS,PYTHON
|
||||
|
||||
test_windows:
|
||||
name: Test Windows
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
python: ["3.9"]
|
||||
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
PYTHON: ${{ matrix.python }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0" # 0=all, needed for setuptools-scm to resolve version tags
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: Install system packages
|
||||
run: |
|
||||
choco install --yes --no-progress --pre tesseract
|
||||
choco install --yes --no-progress ghostscript
|
||||
choco install --yes --no-progress pngquant
|
||||
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements/main.txt -r requirements/test.txt .
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
python -m pytest --cov-report xml --cov=ocrmypdf --cov=tests/ -n0 tests/
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
files: ./coverage.xml
|
||||
env_vars: OS,PYTHON
|
||||
|
||||
wheel_sdist_linux:
|
||||
name: Build sdist and wheels
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0" # 0=all, needed for setuptools-scm to resolve version tags
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: "3.6"
|
||||
|
||||
- name: Make wheels and sdist
|
||||
run: |
|
||||
python -m pip install --upgrade pip wheel
|
||||
python setup.py sdist
|
||||
python setup.py bdist_wheel
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: |
|
||||
./dist/*.whl
|
||||
./dist/*.tar.gz
|
||||
|
||||
upload_pypi:
|
||||
name: Deploy artifacts to PyPI
|
||||
needs: [wheel_sdist_linux, test_linux, test_macos, test_windows]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.TOKEN_PYPI }}
|
||||
# repository_url: https://test.pypi.org/legacy/
|
||||
|
||||
docker:
|
||||
name: Build Docker images
|
||||
needs: [wheel_sdist_linux, test_linux, test_macos, test_windows]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set image tag to release or branch
|
||||
run: echo "DOCKER_IMAGE_TAG=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: If master, set to latest
|
||||
run: echo 'DOCKER_IMAGE_TAG=latest' >> $GITHUB_ENV
|
||||
if: env.DOCKER_IMAGE_TAG == 'master'
|
||||
|
||||
- name: Set Docker Hub repository to username
|
||||
run: echo "DOCKER_REPOSITORY=jbarlow83" >> $GITHUB_ENV
|
||||
|
||||
- name: Set image name
|
||||
run: echo "DOCKER_IMAGE_NAME=ocrmypdf" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0" # 0=all, needed for setuptools-scm to resolve version tags
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: jbarlow83
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Print image tag
|
||||
run: echo "Building image ${DOCKER_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
docker buildx build \
|
||||
--push \
|
||||
--platform linux/arm64/v8,linux/amd64 \
|
||||
--tag "${DOCKER_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}" \
|
||||
--file .docker/Dockerfile .
|
||||
@@ -24,6 +24,7 @@ venv*/
|
||||
/debug_tests.py
|
||||
*.traineddata
|
||||
/private
|
||||
/coverage.xml
|
||||
|
||||
# Package building
|
||||
*.egg-info/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<img src="docs/images/logo.svg" width="240" alt="OCRmyPDF">
|
||||
|
||||
[![Build Status][azure]](https://dev.azure.com/jim0585/ocrmypdf/_build/latest?definitionId=2&branchName=master) [![PyPI version][pypi]](https://pypi.org/project/ocrmypdf/) ![Homebrew version][homebrew] ![ReadTheDocs][docs] ![Python versions][pyversions]
|
||||
[](https://github.com/jbarlow83/OCRmyPDF/actions/workflows/build.yml) [![PyPI version][pypi]](https://pypi.org/project/ocrmypdf/) ![Homebrew version][homebrew] ![ReadTheDocs][docs] ![Python versions][pyversions]
|
||||
|
||||
[azure]: https://dev.azure.com/jim0585/ocrmypdf/_apis/build/status/jbarlow83.OCRmyPDF?branchName=master
|
||||
[travis]: https://travis-ci.org/jbarlow83/OCRmyPDF.svg?branch=master "Travis build status"
|
||||
@@ -59,23 +59,15 @@ I searched the web for a free command line tool to OCR PDF files: I found many,
|
||||
|
||||
Linux, Windows, macOS and FreeBSD are supported. Docker images are also available.
|
||||
|
||||
Users of Debian 9 or later or Ubuntu 16.10 or later may simply
|
||||
|
||||
```bash
|
||||
apt-get install ocrmypdf
|
||||
```
|
||||
|
||||
and users of Fedora 29 or later may simply
|
||||
|
||||
```bash
|
||||
dnf install ocrmypdf
|
||||
```
|
||||
|
||||
and Homebrew users (macOS, Linux, Windows Subsystem for Linux) may simply
|
||||
|
||||
```bash
|
||||
brew install ocrmypdf
|
||||
```
|
||||
| Operating system | Install command |
|
||||
| ----------------------------- | ------------------------------|
|
||||
| Debian, Ubuntu | ``apt install ocrmypdf`` |
|
||||
| Windows Subsystem for Linux | ``apt install ocrmypdf`` |
|
||||
| Fedora | ``dnf install ocrmypdf`` |
|
||||
| macOS | ``brew install ocrmypdf`` |
|
||||
| LinuxBrew | ``brew install ocrmypdf`` |
|
||||
| FreeBSD | ``pkg install py37-ocrmypdf`` |
|
||||
| Conda | ``conda install ocrmypdf`` |
|
||||
|
||||
For everyone else, [see our documentation](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for installation steps.
|
||||
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
trigger:
|
||||
tags:
|
||||
include:
|
||||
- v*
|
||||
branches:
|
||||
include:
|
||||
- "*"
|
||||
exclude:
|
||||
- "travis"
|
||||
|
||||
stages:
|
||||
- stage: "Test"
|
||||
jobs:
|
||||
- job: Windows
|
||||
pool:
|
||||
vmImage: "vs2017-win2016"
|
||||
strategy:
|
||||
matrix:
|
||||
Python36:
|
||||
python.version: "3.6"
|
||||
Python37:
|
||||
python.version: "3.7"
|
||||
Python38:
|
||||
python.version: "3.8"
|
||||
Python39:
|
||||
python.version: "3.9"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "$(python.version)"
|
||||
- pwsh: |
|
||||
choco install --yes --no-progress --pre tesseract
|
||||
choco install --yes --no-progress python3
|
||||
choco install --yes --no-progress ghostscript
|
||||
# choco install --yes --no-progress pngquant
|
||||
displayName: "Install system packages"
|
||||
- pwsh: |
|
||||
refreshenv
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install -r requirements/main.txt -r requirements/test.txt .
|
||||
displayName: "Install Python packages"
|
||||
- pwsh: |
|
||||
refreshenv
|
||||
$env:pathext += ';.py'
|
||||
# -n auto helps Windows
|
||||
python -m pytest -n auto --junitxml=test.xml --cov=ocrmypdf --cov-report=xml
|
||||
displayName: "Test"
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: "test.xml"
|
||||
testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
|
||||
condition: succeededOrFailed()
|
||||
- job: "Ubuntu_1804"
|
||||
pool:
|
||||
vmImage: "ubuntu-18.04"
|
||||
strategy:
|
||||
matrix:
|
||||
Python36:
|
||||
python.version: "3.6"
|
||||
Python37:
|
||||
python.version: "3.7"
|
||||
Python38:
|
||||
python.version: "3.8"
|
||||
Python39:
|
||||
python.version: "3.9"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "$(python.version)"
|
||||
- bash: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
python3-software-properties \
|
||||
curl \
|
||||
ghostscript \
|
||||
img2pdf \
|
||||
libexempi3 \
|
||||
libffi-dev \
|
||||
liblept5 \
|
||||
libsm6 libxext6 libxrender-dev \
|
||||
pngquant \
|
||||
poppler-utils \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-eng \
|
||||
unpaper \
|
||||
zlib1g
|
||||
displayName: "Install system packages"
|
||||
- bash: |
|
||||
curl https://bootstrap.pypa.io/get-pip.py | python3
|
||||
pip3 install -r requirements/main.txt -r requirements/test.txt .
|
||||
displayName: "Install Python packages"
|
||||
- bash: |
|
||||
tesseract --version
|
||||
displayName: "Record versions"
|
||||
- bash: |
|
||||
# -n auto is slower on Linux and breaks on Python 3.8
|
||||
pytest -n0 --junitxml=test.xml --cov=ocrmypdf --cov-report=xml
|
||||
displayName: "Test"
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: "test.xml"
|
||||
testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
|
||||
condition: succeededOrFailed()
|
||||
- job: "Ubuntu_1604"
|
||||
pool:
|
||||
vmImage: "ubuntu-16.04"
|
||||
strategy:
|
||||
matrix:
|
||||
Python36:
|
||||
python.version: "3.6"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "$(python.version)"
|
||||
- bash: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
software-properties-common
|
||||
sudo add-apt-repository -y ppa:alex-p/tesseract-ocr
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
ghostscript \
|
||||
img2pdf \
|
||||
libexempi3 \
|
||||
libffi-dev \
|
||||
liblept5 \
|
||||
libsm6 libxext6 libxrender-dev \
|
||||
pngquant \
|
||||
poppler-utils \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-eng \
|
||||
unpaper \
|
||||
zlib1g
|
||||
displayName: "Install system packages"
|
||||
- bash: |
|
||||
curl https://bootstrap.pypa.io/get-pip.py | python3
|
||||
pip3 install -r requirements/main.txt -r requirements/test.txt .
|
||||
displayName: "Install Python packages"
|
||||
- bash: |
|
||||
tesseract --version
|
||||
displayName: "Record versions"
|
||||
- bash: |
|
||||
# -n auto is slower on Linux and breaks on Python 3.8
|
||||
pytest -n0 --junitxml=test.xml --cov=ocrmypdf --cov-report=xml
|
||||
displayName: "Test"
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: "test.xml"
|
||||
testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
|
||||
condition: succeededOrFailed()
|
||||
- job: "macOS_Mojave"
|
||||
pool:
|
||||
vmImage: "macos-10.14"
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/664
|
||||
# - task: UsePythonVersion@0
|
||||
# inputs:
|
||||
# versionSpec: "$(python.version)"
|
||||
- bash: |
|
||||
brew update
|
||||
brew upgrade python
|
||||
echo "Using `python3 --version`"
|
||||
displayName: "Update brew and Python"
|
||||
- bash: |
|
||||
brew install \
|
||||
exempi \
|
||||
ghostscript \
|
||||
jbig2enc \
|
||||
leptonica \
|
||||
openjpeg \
|
||||
pngquant \
|
||||
tesseract
|
||||
displayName: "Install system packages"
|
||||
- bash: |
|
||||
pip3 install --upgrade pip
|
||||
pip3 install -r requirements/main.txt -r requirements/test.txt .
|
||||
displayName: "Install Python packages"
|
||||
- bash: |
|
||||
tesseract --version
|
||||
displayName: "Record versions"
|
||||
- bash: pytest -nauto --junitxml=test.xml --cov=ocrmypdf --cov-report=xml
|
||||
displayName: "Test"
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFiles: "test.xml"
|
||||
testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
|
||||
condition: succeededOrFailed()
|
||||
- task: PublishCodeCoverageResults@1
|
||||
inputs:
|
||||
codeCoverageTool: Cobertura
|
||||
summaryFileLocation: "$(System.DefaultWorkingDirectory)/**/coverage.xml"
|
||||
|
||||
- stage: "Artifacts"
|
||||
jobs:
|
||||
- job: "sdist_wheel"
|
||||
pool:
|
||||
vmImage: "ubuntu-18.04"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "3.7"
|
||||
- bash: |
|
||||
python -m pip install --upgrade pip wheel
|
||||
python setup.py sdist bdist_wheel
|
||||
- publish: dist
|
||||
artifact: sdist_wheel
|
||||
|
||||
- stage: "Deploy"
|
||||
jobs:
|
||||
- deployment: "PyPI"
|
||||
pool:
|
||||
vmImage: "ubuntu-18.04"
|
||||
environment: "deploy"
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- download: current
|
||||
artifact: sdist_wheel
|
||||
- script: |
|
||||
mkdir -p dist
|
||||
mv $(Pipeline.Workspace)/sdist_wheel/* dist
|
||||
displayName: "Move dist files"
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "3.8"
|
||||
architecture: x64
|
||||
- script: |
|
||||
pip install --upgrade twine
|
||||
displayName: "Generate artifacts"
|
||||
- script: |
|
||||
cat <<FILE >.pypirc
|
||||
[distutils]
|
||||
index-servers =
|
||||
pypi
|
||||
|
||||
[pypi]
|
||||
username: __token__
|
||||
password: $(TOKEN_PYPI)
|
||||
|
||||
FILE
|
||||
displayName: "Generate PyPI auth file"
|
||||
- script: |
|
||||
python -m twine upload --config-file .pypirc dist/*
|
||||
displayName: "Upload to PyPI"
|
||||
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
|
||||
- script: |
|
||||
curl -X POST -d "token=$(TOKEN_RTD)" https://readthedocs.org/api/v2/webhook/pikepdf/39557/
|
||||
displayName: "Trigger ReadTheDocs"
|
||||
condition: and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')))
|
||||
@@ -202,13 +202,6 @@ Alternatives
|
||||
- `Watchman <https://facebook.github.io/watchman/>`__ is a more
|
||||
powerful alternative to ``watchmedo``.
|
||||
|
||||
AWS Lambda is not viable
|
||||
------------------------
|
||||
|
||||
AWS Lambda and its equivalents have low limits on execution time and payload
|
||||
size, relative to OCRmyPDF's needs. As of this writing, the request/response
|
||||
payload for AWS Lambda was 6 MB, which means many PDFs will not fit.
|
||||
|
||||
macOS Automator
|
||||
===============
|
||||
|
||||
|
||||
+5
-3
@@ -58,9 +58,11 @@ portrait pages.
|
||||
You can increase (decrease) the parameter ``--rotate-pages-threshold``
|
||||
to make page rotation more (less) aggressive. The threshold number is the ratio
|
||||
of how confidence the OCR engine is that the document image should be changed,
|
||||
compared to kept the same. A value of ``15.0`` is the default, and is fairly
|
||||
conservative. A value of ``2.0`` will produce more rotations, and more false
|
||||
positives.
|
||||
compared to kept the same. The default value is quite conservative; on some files
|
||||
it may not attempt rotations at all unless it is very confident that the current
|
||||
rotation is wrong. A lower value of ``2.0`` will produce more rotations, and
|
||||
more false positives. Run with ``-v1`` to see the confidence level for each
|
||||
page to see if there may be a better value for your files.
|
||||
|
||||
If the page is "just a little off horizontal", like a crooked picture,
|
||||
then you want ``--deskew``. ``--rotate-pages`` is for when the cardinal
|
||||
|
||||
+51
-25
@@ -12,19 +12,21 @@ system/platform. This version may be out of date, however.
|
||||
|
||||
These platforms have one-liner installs:
|
||||
|
||||
+-----------------------------+-------------------------------+
|
||||
| Debian, Ubuntu | ``apt install ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
| Windows Subsystem for Linux | ``apt install ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
| Fedora | ``dnf install ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
| macOS | ``brew install ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
| LinuxBrew | ``brew install ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
| FreeBSD | ``pkg install py37-ocrmypdf`` |
|
||||
+-----------------------------+-------------------------------+
|
||||
+-------------------------------+-------------------------------+
|
||||
| Debian, Ubuntu | ``apt install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| Windows Subsystem for Linux | ``apt install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| Fedora | ``dnf install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| macOS | ``brew install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| LinuxBrew | ``brew install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| FreeBSD | ``pkg install py37-ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
| Conda (WSL, macOS, Linux) | ``conda install ocrmypdf`` |
|
||||
+-------------------------------+-------------------------------+
|
||||
|
||||
More detailed procedures are outlined below. If you want to do a manual
|
||||
install, or install a more recent version than your platform provides, read on.
|
||||
@@ -54,6 +56,9 @@ Debian and Ubuntu 18.04 or newer
|
||||
.. |ubu-2004| image:: https://repology.org/badge/version-for-repo/ubuntu_20_04/ocrmypdf.svg
|
||||
:alt: Ubuntu 20.04 LTS
|
||||
|
||||
.. |ubu-2010| image:: https://repology.org/badge/version-for-repo/ubuntu_20_10/ocrmypdf.svg
|
||||
:alt: Ubuntu 20.10
|
||||
|
||||
+-----------------------------------------------+
|
||||
| **OCRmyPDF versions in Debian & Ubuntu** |
|
||||
+-----------------------------------------------+
|
||||
@@ -61,7 +66,7 @@ Debian and Ubuntu 18.04 or newer
|
||||
+-----------------------------------------------+
|
||||
| |deb-stable| |deb-testing| |deb-unstable| |
|
||||
+-----------------------------------------------+
|
||||
| |ubu-1804| |ubu-2004| |
|
||||
| |ubu-1804| |ubu-2004| |ubu-2010| |
|
||||
+-----------------------------------------------+
|
||||
|
||||
Users of Debian 9 ("stretch") or later, or Ubuntu 18.04 or later, including users
|
||||
@@ -90,15 +95,15 @@ For full details on version availability for your platform, check the
|
||||
automatically detect it (specifically the ``jbig2`` binary) on the
|
||||
``PATH``. To add JBIG2 encoding, see :ref:`jbig2`.
|
||||
|
||||
Fedora 29 or newer
|
||||
------------------
|
||||
|
||||
.. |fedora-31| image:: https://repology.org/badge/version-for-repo/fedora_31/ocrmypdf.svg
|
||||
:alt: Fedora 31
|
||||
Fedora
|
||||
------
|
||||
|
||||
.. |fedora-32| image:: https://repology.org/badge/version-for-repo/fedora_32/ocrmypdf.svg
|
||||
:alt: Fedora 32
|
||||
|
||||
.. |fedora-33| image:: https://repology.org/badge/version-for-repo/fedora_33/ocrmypdf.svg
|
||||
:alt: Fedora 33
|
||||
|
||||
.. |fedora-rawhide| image:: https://repology.org/badge/version-for-repo/fedora_rawhide/ocrmypdf.svg
|
||||
:alt: Fedore Rawhide
|
||||
|
||||
@@ -107,7 +112,7 @@ Fedora 29 or newer
|
||||
+-----------------------------------------------+
|
||||
| |latest| |
|
||||
+-----------------------------------------------+
|
||||
| |fedora-31| |fedora-32| |fedora-rawhide| |
|
||||
| |fedora-32| |fedora-33| |fedora-rawhide| |
|
||||
+-----------------------------------------------+
|
||||
|
||||
Users of Fedora 29 or later may simply
|
||||
@@ -158,7 +163,7 @@ To install ocrmypdf for the system:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo pip3 install ocrmypdf
|
||||
pip3 install ocrmypdf
|
||||
|
||||
To install for the current user only:
|
||||
|
||||
@@ -355,7 +360,8 @@ To install OCRmyPDF for Alpine Linux:
|
||||
Mageia 7
|
||||
--------
|
||||
|
||||
Install the following dependencies:
|
||||
There is no OS-level packaging available for Mageia, so you must install the
|
||||
dependencies:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -380,12 +386,16 @@ Install the following dependencies:
|
||||
|
||||
To install ocrmypdf for the system:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# As root user
|
||||
pip3 install ocrmypdf
|
||||
ldconfig
|
||||
|
||||
Or, to install for the current user only:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export PATH=$HOME/.local/bin:$PATH
|
||||
pip3 install --user ocrmypdf
|
||||
|
||||
@@ -454,7 +464,7 @@ Update Homebrew:
|
||||
|
||||
Install or upgrade the required Homebrew packages, if any are missing.
|
||||
To do this, use ``brew edit ocrmypdf`` to obtain a recent list of Homebrew
|
||||
dependencies. You could also check the ``azure-pipelines.yml``.
|
||||
dependencies. You could also check the ``.workflows/build.yml``.
|
||||
|
||||
This will include the English, French, German and Spanish language
|
||||
packs. If you need other languages you can optionally install them all:
|
||||
@@ -536,8 +546,9 @@ to change the PATH.
|
||||
.. warning::
|
||||
|
||||
As of early 2021, users have reported problems with the Microsoft Store version of
|
||||
Python affected most third party Python packages including OCRmyPDF. Please use
|
||||
Python downloaded from Python.org or Chocolatey as recommended here.
|
||||
Python and OCRmyPDF. These issues affect many other third party Python packages.
|
||||
Please download Python from Python.org or Chocolatey instead, and do not use the
|
||||
Microsoft Store version.
|
||||
|
||||
Windows Subsystem for Linux
|
||||
---------------------------
|
||||
@@ -645,6 +656,21 @@ the latest version. However, PyPI and ``pip`` cannot address the fact
|
||||
that ``ocrmypdf`` depends on certain non-Python system libraries and
|
||||
programs being installed.
|
||||
|
||||
.. warning::
|
||||
|
||||
Debian and Ubuntu users: unfortunately, Debian and Ubuntu customize
|
||||
Python in non-standard ways, and the nature of these customizations
|
||||
varies from release to release. This can make for a frustrating
|
||||
user experience. The instructions below work on almost all platforms that
|
||||
have Python installed, except for Debian and Ubuntu, where you may need
|
||||
to take additional steps. For best results on Debian and Ubuntu, use the
|
||||
``apt`` packages; or if these are too old, run
|
||||
``apt install python3-pip python3-venv``, create a virtual environment,
|
||||
and install OCRmyPDF in that environment.
|
||||
|
||||
`See here for more inforation on Debian-Python issues
|
||||
<https://gist.github.com/tiran/2dec9e03c6f901814f6d1e8dad09528e>`__.
|
||||
|
||||
For best results, first install `your platform's
|
||||
version <https://repology.org/metapackage/ocrmypdf/versions>`__ of
|
||||
``ocrmypdf``, using the instructions elsewhere in this document. Then
|
||||
|
||||
+4
-1
@@ -70,4 +70,7 @@ derived Docker image as
|
||||
Windows users
|
||||
=============
|
||||
|
||||
The Tesseract installer provided by Chocolatey already includes 100 languages.
|
||||
The Tesseract installer provided by Chocolatey currently includes only English language.
|
||||
To install other languages, download the respective language pack (``.traineddata`` file)
|
||||
from https://github.com/tesseract-ocr/tessdata/ and place it in
|
||||
``C:\\Program Files\\Tesseract-OCR\\tessdata`` (or wherever Tesseract OCR is installed).
|
||||
|
||||
@@ -151,6 +151,18 @@ Custom command line arguments
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.check_options
|
||||
|
||||
Execution and progress reporting
|
||||
--------------------------------
|
||||
|
||||
.. autoclass: ocrmypdf.pluginspec.Executor
|
||||
:members:
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.get_logging_console
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.get_executor
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.get_progressbar_class
|
||||
|
||||
Applying special behavior before processing
|
||||
-------------------------------------------
|
||||
|
||||
@@ -168,6 +180,8 @@ Modifying intermediate images
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.filter_page_image
|
||||
|
||||
.. autofunction:: ocrmypdf.pluginspec.filter_pdf_page
|
||||
|
||||
OCR engine
|
||||
----------
|
||||
|
||||
|
||||
@@ -12,6 +12,107 @@ may be unreliable. Use the API to depend on precise behavior.
|
||||
The public API may be useful in scripts that launch OCRmyPDF processes or that
|
||||
wish to use some of its features for working with PDFs.
|
||||
|
||||
v12.0.0
|
||||
=======
|
||||
|
||||
**Breaking changes**
|
||||
|
||||
- Due to recent security issues in pikepdf, Pillow and reportlab, we now require
|
||||
newer versions of these libraries and some of their dependencies. (If necessary,
|
||||
package maintainers may override these versions at their discretion; lower
|
||||
versions will often work.)
|
||||
- We now use the "LeaveColorUnchanged" color conversion strategy when directing
|
||||
Ghostscript to create a PDF/A. Generally this is faster than performing a
|
||||
color conversion, which is not always necessary.
|
||||
- OCR text is now packaged in a Form XObject. This makes it easier to isolate
|
||||
OCR from other document content. However, some poor implemented PDF text
|
||||
extraction algorithms may fail to find the text.
|
||||
- Many API functions have stricter parameter checking or expect keyword arguments
|
||||
were they previously did not.
|
||||
- Some deprecated functions in ``ocrmypdf.optimize`` were removed.
|
||||
- The ``ocrmypdf.leptonica`` module is now deprecated.
|
||||
- Continuous integration moved to GitHub Actions.
|
||||
- We no longer depend on ``pytest_helpers_namespace`` for testing.
|
||||
|
||||
**New features**
|
||||
|
||||
- New plugin hook: ``get_progressbar_class``, for progress reporting,
|
||||
allowing developers to replace the standard console progress bar with some
|
||||
other mechanism, such as updating a GUI progress bar.
|
||||
- New plugin hook: ``get_executor``, for replacing the concurrency model.
|
||||
This is primarily to support execution on AWS Lambda, which does not support
|
||||
standard Python ``multiprocessing`` due to its lack of shared memory.
|
||||
- New plugin hook: ``get_logging_console``, for replacing the standard
|
||||
way OCRmyPDF outputs its messages.
|
||||
- New plugin hook: ``filter_pdf_page``, for modifying individual PDF
|
||||
pages produced by OCRmyPDF.
|
||||
- Using the new plugin hooks, it is now possible to run OCRmyPDF on alternative
|
||||
execution environments that do not have interprocess semaphores, such as
|
||||
AWS Lambda and Android Termux.
|
||||
- Continuous integration moved to GitHub Actions.
|
||||
- We now generate an ARM64-compatible Docker image alongside the x64 image.
|
||||
Thanks to @andkrause for contributing the change and @0x326 for review comments.
|
||||
|
||||
**Fixes**
|
||||
|
||||
- Fixed a possible deadlock on attempting to flush ``sys.stderr`` when older
|
||||
versions of Leptonica are in use.
|
||||
- Some worker processes inherited resources from their parents such as log
|
||||
handlers that may have also lead to deadlocks. These resources are now released.
|
||||
- Improvements to test coverage.
|
||||
- Removed vestiges of support for Tesseract versions older than 4.0.0-beta1 (
|
||||
which ships with Ubuntu 18.04).
|
||||
- OCRmyPDF can now parse all of Tesseract version numbers, since several
|
||||
schemes have been in use.
|
||||
- Fixed an issue with parsing PDFs that contain images drawn at a scale of 0. (#761)
|
||||
|
||||
v11.7.3
|
||||
=======
|
||||
|
||||
- Exclude CCITT Group 3 images from being optimized. Some libraries
|
||||
OCRmyPDF uses do not seem to handle this obscure compression format properly.
|
||||
You may get errors or possible corrupted output images without this fix.
|
||||
|
||||
v11.7.2
|
||||
=======
|
||||
|
||||
- Updated pinned versions in main.txt, primarily to upgrade Pillow to 8.1.2, due
|
||||
to recently disclosed security vulnerabilities in that software.
|
||||
- The ``--sidecar`` parameter now causes an exception if set to the same file as
|
||||
the input or output PDF.
|
||||
|
||||
v11.7.1
|
||||
=======
|
||||
|
||||
- Some exceptions while attempting image optimization were only logged at the debug
|
||||
level, causing them to be suppressed. These errors are now logged appropriately.
|
||||
- Improved the error message related to ``--unpaper-args``.
|
||||
- Updated documentation to mention the new conda distribution.
|
||||
|
||||
v11.7.0
|
||||
=======
|
||||
|
||||
- We now support using ``--sidecar`` in conjunction with ``--pages``; these arguments
|
||||
used to be mutually exclusive. (#735)
|
||||
- Fixed a possible issue with PDF/A-1b generation. Acrobat complained that our PDFs use
|
||||
object streams. More robust PDF/A validators like veraPDF don't consider this a
|
||||
problem, but we'll honor Acrobat's objection from here on. This may increase file
|
||||
size of PDF/A-1b files. PDF/A-2b files will not be affected.
|
||||
|
||||
v11.6.2
|
||||
=======
|
||||
|
||||
- Fixed a regression where the wrong page orientation would be produced when using
|
||||
arguments such as ``--deskew --rotate-pages`` (#730).
|
||||
|
||||
v11.6.1
|
||||
=======
|
||||
|
||||
- Fixed an issue with attempting optimize unusually narrow-width images by excluding
|
||||
these images from optimization (#732).
|
||||
- Remove an obsolete compatibility shim for a version of pikepdf that is no longer
|
||||
supported.
|
||||
|
||||
v11.6.0
|
||||
=======
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
- "/media/scan:/input"
|
||||
- "/mnt/scan:/output"
|
||||
environment:
|
||||
- OCR_OUTPUT_DIRECTORY_YEAR_MONT=0
|
||||
- OCR_OUTPUT_DIRECTORY_YEAR_MONTH=0
|
||||
user: "<SET TO YOUR USER ID>:<SET TO YOUR GROUP ID>"
|
||||
entrypoint: python3
|
||||
command: watcher.py
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# requirements.txt can be used to replicate the developer's build environment
|
||||
# setup.py lists a separate set of requirements that are looser to simplify
|
||||
# installation
|
||||
cffi == 1.14.3
|
||||
coloredlogs == 14.0 # technically optional
|
||||
cffi == 1.14.5
|
||||
coloredlogs == 15.0 # technically optional
|
||||
img2pdf == 0.4.0
|
||||
pdfminer.six == 20201018
|
||||
pikepdf == 2.0.0
|
||||
pikepdf == 2.10.0
|
||||
pluggy == 0.13.1
|
||||
Pillow == 8.0.1
|
||||
reportlab == 3.5.55
|
||||
tqdm == 4.51.0
|
||||
Pillow == 8.1.2
|
||||
reportlab == 3.5.66
|
||||
tqdm == 4.59.0
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
pytest >= 5.0.0
|
||||
pytest-helpers-namespace >= 2019.1.8
|
||||
pytest-xdist >= 1.31.0
|
||||
pytest-cov >= 2.10.0
|
||||
pytest >= 6.0.0
|
||||
pytest-xdist >= 2.2.0
|
||||
pytest-cov >= 2.11.1
|
||||
python-xmp-toolkit == 2.0.1 # requires apt-get install libexempi3
|
||||
# or brew install exempi
|
||||
#PyMuPDF == 1.13.4 # optional
|
||||
|
||||
@@ -1 +1 @@
|
||||
watchdog == 0.10.2
|
||||
watchdog == 1.0.2
|
||||
|
||||
@@ -32,14 +32,12 @@ license_file = LICENSE
|
||||
|
||||
[coverage:paths]
|
||||
source =
|
||||
src/
|
||||
src/ocrmypdf
|
||||
|
||||
[coverage:run]
|
||||
branch = true
|
||||
parallel = true
|
||||
concurrency = multiprocessing
|
||||
source =
|
||||
src/ocrmypdf
|
||||
|
||||
[coverage:report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
|
||||
@@ -17,10 +17,6 @@ if sys.version_info < (3, 6):
|
||||
print("Python 3.6 or newer is required", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if 'upload' in sys.argv[1:]:
|
||||
print('Use twine to upload the package - setup.py upload is insecure')
|
||||
sys.exit(1)
|
||||
|
||||
tests_require = open('requirements/test.txt', encoding='utf-8').read().splitlines()
|
||||
|
||||
|
||||
@@ -73,11 +69,11 @@ setup(
|
||||
'coloredlogs >= 14.0', # strictly optional
|
||||
'img2pdf >= 0.3.0, < 0.5', # pure Python, so track HEAD closely
|
||||
'pdfminer.six >= 20191110, != 20200720, <= 20201018',
|
||||
"pikepdf >= 1.14.0, < 3 ; python_version < '3.9'",
|
||||
"pikepdf >= 2.0.0 ; python_version >= '3.9'",
|
||||
'Pillow >= 7.0.0',
|
||||
"pikepdf >= 2.10.0",
|
||||
'Pillow >= 8.1.2',
|
||||
'pluggy >= 0.13.0, < 1.0',
|
||||
'reportlab >= 3.3.0', # oldest released version with sane image handling
|
||||
'reportlab >= 3.5.66',
|
||||
'setuptools',
|
||||
'tqdm >= 4',
|
||||
],
|
||||
tests_require=tests_require,
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Release checklist
|
||||
|
||||
## Patch release
|
||||
|
||||
- Check `pytest`
|
||||
|
||||
- Update release notes
|
||||
|
||||
## Minor release
|
||||
|
||||
## Major release
|
||||
|
||||
- Run `pre-commit autoupdate`
|
||||
|
||||
- Check README.md
|
||||
|
||||
- Check setup.py
|
||||
|
||||
- Are classifiers up to date?
|
||||
- Is `python_requires` correct?
|
||||
- Python 3.6 is EOL on December 2021-12. Could drop support then.
|
||||
- Can we tighten any `install_requires` dependencies?
|
||||
|
||||
- Search for old version shims we can remove
|
||||
|
||||
- "shim"
|
||||
- ` pikepdf.__version__`
|
||||
|
||||
- Search for deprecation: search all files for deprec*, etc.
|
||||
|
||||
- Check requirements/*
|
||||
|
||||
- Delete `tests/cache`, do `pytest --runslow`, and update cache.
|
||||
|
||||
- Do `pytest --cov-report html`
|
||||
@@ -8,6 +8,7 @@
|
||||
from pluggy import HookimplMarker as _HookimplMarker
|
||||
|
||||
from ocrmypdf import helpers, hocrtransform, leptonica, pdfa, pdfinfo
|
||||
from ocrmypdf._concurrent import Executor
|
||||
from ocrmypdf._jobcontext import PageContext, PdfContext
|
||||
from ocrmypdf._version import PROGRAM_NAME, __version__
|
||||
from ocrmypdf.api import Verbosity, configure_logging, ocr
|
||||
|
||||
@@ -47,7 +47,10 @@ def run(args=None):
|
||||
verbosity = Verbosity.quiet
|
||||
options.progress_bar = False
|
||||
configure_logging(
|
||||
verbosity, progress_bar_friendly=options.progress_bar, manage_root_logger=True
|
||||
verbosity,
|
||||
progress_bar_friendly=options.progress_bar,
|
||||
manage_root_logger=True,
|
||||
plugin_manager=plugin_manager,
|
||||
)
|
||||
log.debug('ocrmypdf %s', __version__)
|
||||
try:
|
||||
|
||||
+117
-121
@@ -4,134 +4,130 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
import multiprocessing
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import threading
|
||||
from contextlib import suppress
|
||||
from multiprocessing import Pool as ProcessPool
|
||||
from multiprocessing.dummy import Pool as ThreadPool
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Callable, Iterable, Optional
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
from ocrmypdf.exceptions import InputFileError
|
||||
def _task_noop(*_args, **_kwargs):
|
||||
return
|
||||
|
||||
|
||||
def log_listener(queue):
|
||||
"""Listen to the worker processes and forward the messages to logging
|
||||
class NullProgressBar:
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
For simplicity this is a thread rather than a process. Only one process
|
||||
should actually write to sys.stderr or whatever we're using, so if this is
|
||||
made into a process the main application needs to be directed to it.
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
See https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
return False
|
||||
|
||||
def update(self, _arg=None):
|
||||
return
|
||||
|
||||
|
||||
class Executor(ABC):
|
||||
pool_lock = threading.Lock()
|
||||
pbar_class = NullProgressBar
|
||||
|
||||
def __init__(self, *, pbar_class=None):
|
||||
if pbar_class:
|
||||
self.pbar_class = pbar_class
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
worker_initializer: Optional[Callable] = None,
|
||||
task: Optional[Callable] = None,
|
||||
task_arguments: Optional[Iterable] = None,
|
||||
task_finished: Optional[Callable] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Set up parallel execution and progress reporting.
|
||||
|
||||
Args:
|
||||
use_threads: If ``False``, the workload is the sort that will benefit from
|
||||
running in a multiprocessing context (for example, it uses Python
|
||||
heavily, and parallelizing it with threads is not expected to be
|
||||
performant).
|
||||
max_workers: The maximum number of workers that should be run.
|
||||
tdqm_kwargs: Arguments to set up the progress bar.
|
||||
worker_initializer: Called when a worker is initialized, in the worker's
|
||||
execution context. If the child workers are processes, it must be
|
||||
possible to marshall/pickle the worker initializer.
|
||||
``functools.partial`` can be used to bind parameters.
|
||||
task: Called when the worker starts a new task, in the worker's execution
|
||||
context. Must be possible to marshall to the worker.
|
||||
task_finished: Called when a worker finishes a task, in the parent's
|
||||
context.
|
||||
task_arguments: An iterable that generates a group of parameters for each
|
||||
task. This runs in the parent's context, but the parameters must be
|
||||
marshallable to the worker.
|
||||
"""
|
||||
|
||||
if not task_arguments:
|
||||
return # Nothing to do!
|
||||
if not worker_initializer:
|
||||
worker_initializer = _task_noop
|
||||
if not task_finished:
|
||||
task_finished = _task_noop
|
||||
if not task:
|
||||
task = _task_noop
|
||||
|
||||
with self.pool_lock:
|
||||
self._execute(
|
||||
use_threads=use_threads,
|
||||
max_workers=max_workers,
|
||||
tqdm_kwargs=tqdm_kwargs,
|
||||
worker_initializer=worker_initializer,
|
||||
task=task,
|
||||
task_arguments=task_arguments,
|
||||
task_finished=task_finished,
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
def _execute(
|
||||
self,
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
worker_initializer: Callable,
|
||||
task: Callable,
|
||||
task_arguments: Iterable,
|
||||
task_finished: Callable,
|
||||
):
|
||||
"""Custom executors should override this method."""
|
||||
|
||||
|
||||
def setup_executor(plugin_manager) -> Executor:
|
||||
pbar_class = plugin_manager.hook.get_progressbar_class()
|
||||
return plugin_manager.hook.get_executor(progressbar_class=pbar_class)
|
||||
|
||||
|
||||
class SerialExecutor(Executor):
|
||||
"""Implements a purely sequential executor using the parallel protocol.
|
||||
|
||||
The current process/thread will be the worker that executes all tasks
|
||||
in order. As such, ``worker_initializer`` will never be called.
|
||||
"""
|
||||
|
||||
while True:
|
||||
try:
|
||||
record = queue.get()
|
||||
if record is None:
|
||||
break
|
||||
logger = logging.getLogger(record.name)
|
||||
logger.handle(record)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
import traceback # pylint: disable=import-outside-toplevel
|
||||
|
||||
print("Logging problem", file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
|
||||
def process_sigbus(*args):
|
||||
raise InputFileError("A worker process lost access to an input file")
|
||||
|
||||
|
||||
def process_init(queue, user_init, loglevel):
|
||||
"""Initialize a process pool worker"""
|
||||
|
||||
# Ignore SIGINT (our parent process will kill us gracefully)
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
|
||||
# Install SIGBUS handler (so our parent process can abort somewhat gracefully)
|
||||
with suppress(AttributeError): # Windows and Cygwin do not have SIGBUS
|
||||
signal.signal(signal.SIGBUS, process_sigbus)
|
||||
|
||||
# Reconfigure the root logger for this process to send all messages to a queue
|
||||
h = logging.handlers.QueueHandler(queue)
|
||||
root = logging.getLogger()
|
||||
root.setLevel(loglevel)
|
||||
root.handlers = []
|
||||
root.addHandler(h)
|
||||
|
||||
if user_init:
|
||||
user_init()
|
||||
|
||||
|
||||
def thread_init(_queue, user_init, _loglevel):
|
||||
# As a thread, block SIGBUS so the main thread deals with it...
|
||||
with suppress(AttributeError):
|
||||
# Windows and Cygwin do not have pthread_sigmask or SIGBUS
|
||||
signal.pthread_sigmask(signal.SIG_BLOCK, {signal.SIGBUS})
|
||||
if user_init:
|
||||
user_init()
|
||||
|
||||
|
||||
def exec_progress_pool(
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
task_initializer: Optional[Callable] = None,
|
||||
task: Optional[Callable] = None,
|
||||
task_arguments: Optional[Iterable] = None,
|
||||
task_finished: Optional[Callable] = None,
|
||||
):
|
||||
log_queue: multiprocessing.Queue = multiprocessing.Queue(-1)
|
||||
listener = threading.Thread(target=log_listener, args=(log_queue,))
|
||||
|
||||
if use_threads:
|
||||
pool_class = ThreadPool
|
||||
initializer = thread_init
|
||||
else:
|
||||
pool_class = ProcessPool
|
||||
initializer = process_init
|
||||
listener.start()
|
||||
|
||||
with tqdm(**tqdm_kwargs) as pbar:
|
||||
pool = pool_class(
|
||||
processes=max_workers,
|
||||
initializer=initializer,
|
||||
initargs=(log_queue, task_initializer, logging.getLogger("").level),
|
||||
)
|
||||
try:
|
||||
results = pool.imap_unordered(task, task_arguments)
|
||||
for result in results:
|
||||
if task_finished:
|
||||
task_finished(result, pbar)
|
||||
else:
|
||||
pbar.update()
|
||||
except KeyboardInterrupt:
|
||||
# Terminate pool so we exit instantly
|
||||
pool.terminate()
|
||||
# Don't try listener.join() here, will deadlock
|
||||
raise
|
||||
except Exception:
|
||||
if not os.environ.get("PYTEST_CURRENT_TEST", ""):
|
||||
# Unless inside pytest, exit immediately because no one wants
|
||||
# to wait for child processes to finalize results that will be
|
||||
# thrown away. Inside pytest, we want child processes to exit
|
||||
# cleanly so that they output an error messages or coverage data
|
||||
# we need from them.
|
||||
pool.terminate()
|
||||
raise
|
||||
finally:
|
||||
# Terminate log listener
|
||||
log_queue.put_nowait(None)
|
||||
pool.close()
|
||||
pool.join()
|
||||
|
||||
listener.join()
|
||||
def _execute(
|
||||
self,
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
worker_initializer: Callable,
|
||||
task: Callable,
|
||||
task_arguments: Iterable,
|
||||
task_finished: Callable,
|
||||
): # pylint: disable=unused-argument
|
||||
with self.pbar_class(**tqdm_kwargs) as pbar:
|
||||
for args in task_arguments:
|
||||
result = task(args)
|
||||
task_finished(result, pbar)
|
||||
|
||||
@@ -166,6 +166,7 @@ class GhostscriptFollower:
|
||||
def generate_pdfa(
|
||||
pdf_pages,
|
||||
output_file: os.PathLike,
|
||||
*,
|
||||
compression: str,
|
||||
pdf_version: str = '1.5',
|
||||
pdfa_part: str = '2',
|
||||
@@ -195,10 +196,11 @@ def generate_pdfa(
|
||||
"-dAutoFilterGrayImages=true",
|
||||
]
|
||||
|
||||
strategy = 'LeaveColorUnchanged'
|
||||
# Older versions of Ghostscript expect a leading slash in
|
||||
# sColorConversionStrategy, newer ones should not have it. See Ghostscript
|
||||
# git commit fe1c025d.
|
||||
strategy = 'RGB' if version() >= '9.19' else '/RGB'
|
||||
strategy = ('/' + strategy) if version() < '9.19' else strategy
|
||||
|
||||
if version() == '9.23':
|
||||
# 9.23: added JPEG passthrough as a new feature, but with a bug that
|
||||
|
||||
@@ -41,9 +41,17 @@ def convert_group(*, cwd, infiles, out_prefix):
|
||||
return proc
|
||||
|
||||
|
||||
def convert_group_mp(args):
|
||||
return convert_group(cwd=args[0], infiles=args[1], out_prefix=args[2])
|
||||
|
||||
|
||||
def convert_single(*, cwd, infile, outfile):
|
||||
args = ['jbig2', '-p', infile]
|
||||
with open(outfile, 'wb') as fstdout:
|
||||
proc = run(args, cwd=cwd, stdout=fstdout, stderr=PIPE)
|
||||
proc.check_returncode()
|
||||
return proc
|
||||
|
||||
|
||||
def convert_single_mp(args):
|
||||
return convert_single(cwd=args[0], infile=args[1], outfile=args[2])
|
||||
|
||||
@@ -59,3 +59,7 @@ def quantize(input_file: Path, output_file: Path, quality_min: int, quality_max:
|
||||
if result.returncode == 0:
|
||||
# input_file could be the same as output_file, so we defer the write
|
||||
output_file.write_bytes(result.stdout)
|
||||
|
||||
|
||||
def quantize_mp(args):
|
||||
return quantize(*args)
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from collections import namedtuple
|
||||
from distutils.version import StrictVersion
|
||||
from os import fspath
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, STDOUT, CalledProcessError, TimeoutExpired
|
||||
@@ -53,31 +55,29 @@ class TesseractLoggerAdapter(logging.LoggerAdapter):
|
||||
return '[tesseract] %s' % (msg), kwargs
|
||||
|
||||
|
||||
class TesseractVersion(StrictVersion):
|
||||
version_re = re.compile(
|
||||
r'''
|
||||
^(\d+) \. (\d+) (\. (\d+))? # groups: 1/major, 2/minor, 3/[skip], 4/patch
|
||||
[-]? # optional hyphen separator
|
||||
(?:(alpha|beta|rc|dev)[.\-\ ]?(\d+)?)? # 5/prerelease, 6/prerelease_num
|
||||
$
|
||||
''',
|
||||
re.VERBOSE | re.ASCII,
|
||||
)
|
||||
|
||||
def parse(self, vstring):
|
||||
try:
|
||||
super().parse(vstring)
|
||||
except TypeError as e:
|
||||
if 'int() argument must be a string' in str(e):
|
||||
super().parse(vstring + '0')
|
||||
|
||||
|
||||
def version():
|
||||
return get_version('tesseract', regex=r'tesseract\s(.+)')
|
||||
|
||||
|
||||
def has_textonly_pdf(langs=None):
|
||||
"""Does Tesseract have textonly_pdf capability?
|
||||
|
||||
Available in v4.00.00alpha since January 2017. Best to
|
||||
parse the parameter list.
|
||||
"""
|
||||
args_tess = tess_base_args(langs, engine_mode=None) + ['--print-parameters', 'pdf']
|
||||
params = ''
|
||||
try:
|
||||
proc = run(args_tess, check=True, stdout=PIPE, stderr=STDOUT)
|
||||
params = proc.stdout
|
||||
except CalledProcessError as e:
|
||||
raise MissingDependencyError(
|
||||
"Could not --print-parameters from tesseract. This can happen if the "
|
||||
"TESSDATA_PREFIX environment is not set to a valid tessdata folder. "
|
||||
) from e
|
||||
if b'textonly_pdf' in params:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def has_user_words():
|
||||
"""Does Tesseract have --user-words capability?
|
||||
|
||||
@@ -221,6 +221,7 @@ def _generate_null_hocr(output_hocr, output_text, image):
|
||||
|
||||
|
||||
def generate_hocr(
|
||||
*,
|
||||
input_file: Path,
|
||||
output_hocr: Path,
|
||||
output_text: Path,
|
||||
|
||||
@@ -69,7 +69,7 @@ def _setup_unpaper_io(tmpdir: Path, input_file: Path) -> Tuple[Path, Path]:
|
||||
|
||||
|
||||
def run(
|
||||
input_file: Path, output_file: Path, dpi: DecFloat, mode_args: List[str]
|
||||
input_file: Path, output_file: Path, *, dpi: DecFloat, mode_args: List[str]
|
||||
) -> None:
|
||||
args_unpaper = ['unpaper', '-v', '--dpi', str(round(dpi, 6))] + mode_args
|
||||
|
||||
@@ -114,6 +114,7 @@ def validate_custom_args(args: str) -> List[str]:
|
||||
def clean(
|
||||
input_file: Path,
|
||||
output_file: Path,
|
||||
*,
|
||||
dpi: DecFloat,
|
||||
unpaper_args: Optional[List[str]] = None,
|
||||
):
|
||||
@@ -130,4 +131,4 @@ def clean(
|
||||
]
|
||||
if not unpaper_args:
|
||||
unpaper_args = default_args
|
||||
run(input_file, output_file, dpi, unpaper_args)
|
||||
run(input_file, output_file, dpi=dpi, mode_args=unpaper_args)
|
||||
|
||||
+38
-19
@@ -6,33 +6,39 @@
|
||||
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
from contextlib import suppress
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import pikepdf
|
||||
from pikepdf.objects import Dictionary, Name
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
MAX_REPLACE_PAGES = 100
|
||||
|
||||
|
||||
def _update_page_resources(*, page, font, font_key, procset):
|
||||
"""Update this page's fonts with a reference to the Glyphless font"""
|
||||
def _ensure_dictionary(obj, name):
|
||||
if name not in obj:
|
||||
obj[name] = Dictionary({})
|
||||
return obj[name]
|
||||
|
||||
if '/Resources' not in page:
|
||||
page['/Resources'] = pikepdf.Dictionary({})
|
||||
resources = page['/Resources']
|
||||
try:
|
||||
fonts = resources['/Font']
|
||||
except KeyError:
|
||||
fonts = pikepdf.Dictionary({})
|
||||
|
||||
def _update_resources(*, obj, font, font_key, procset):
|
||||
"""Update this obj's fonts with a reference to the Glyphless font.
|
||||
|
||||
obj can be a page or Form XObject.
|
||||
"""
|
||||
|
||||
resources = _ensure_dictionary(obj, Name.Resources)
|
||||
fonts = _ensure_dictionary(resources, Name.Font)
|
||||
if font_key is not None and font_key not in fonts:
|
||||
fonts[font_key] = font
|
||||
resources['/Font'] = fonts
|
||||
|
||||
# Reassign /ProcSet to one that just lists everything - ProcSet is
|
||||
# obsolete and doesn't matter but recommended for old viewer support
|
||||
resources['/ProcSet'] = procset
|
||||
if procset:
|
||||
resources['/ProcSet'] = procset
|
||||
|
||||
|
||||
def strip_invisible_text(pdf, page):
|
||||
@@ -169,13 +175,13 @@ class OcrGrafter:
|
||||
"""
|
||||
|
||||
page0 = self.pdf_base.pages[0]
|
||||
_update_page_resources(
|
||||
page=page0, font=self.font, font_key=self.font_key, procset=self.procset
|
||||
_update_resources(
|
||||
obj=page0, font=self.font, font_key=self.font_key, procset=self.procset
|
||||
)
|
||||
|
||||
# We cannot read and write the same file, that will corrupt it
|
||||
# but we don't to keep more copies than we need to. Delete intermediates.
|
||||
# {interim_count} is the opened file we were updateing
|
||||
# {interim_count} is the opened file we were updating
|
||||
# {interim_count - 1} can be deleted
|
||||
# {interim_count + 1} is the new file will produce and open
|
||||
old_file = self.output_file.with_suffix(f'.working{self.interim_count - 1}.pdf')
|
||||
@@ -210,6 +216,7 @@ class OcrGrafter:
|
||||
pdf_text_fonts = pdf_text.pages[0].Resources.get('/Font', {})
|
||||
except (AttributeError, IndexError, KeyError):
|
||||
return None, None
|
||||
pdf_text_font = None
|
||||
for f in possible_font_names:
|
||||
pdf_text_font = pdf_text_fonts.get(f, None)
|
||||
if pdf_text_font is not None:
|
||||
@@ -279,17 +286,29 @@ class OcrGrafter:
|
||||
# finally move the lower left corner to match the mediabox
|
||||
ctm = translate @ rotate @ scale @ untranslate @ corner
|
||||
|
||||
pdf_text_contents = (
|
||||
b'q %s cm\n' % ctm.encode() + pdf_text_contents + b'\nQ\n'
|
||||
base_resources = _ensure_dictionary(base_page, Name.Resources)
|
||||
base_xobjs = _ensure_dictionary(base_resources, Name.XObject)
|
||||
text_xobj_name = Name('/' + str(uuid.uuid4()))
|
||||
xobj = self.pdf_base.make_stream(pdf_text_contents)
|
||||
base_xobjs[text_xobj_name] = xobj
|
||||
xobj.Type = Name.XObject
|
||||
xobj.Subtype = Name.Form
|
||||
xobj.FormType = 1
|
||||
xobj.BBox = mediabox
|
||||
_update_resources(
|
||||
obj=xobj, font=font, font_key=font_key, procset=[Name.PDF]
|
||||
)
|
||||
|
||||
new_text_layer = pikepdf.Stream(self.pdf_base, pdf_text_contents)
|
||||
pdf_draw_xobj = (
|
||||
(b'q %s cm\n' % ctm.encode()) + (b'%s Do\n' % text_xobj_name) + b'\nQ\n'
|
||||
)
|
||||
new_text_layer = pikepdf.Stream(self.pdf_base, pdf_draw_xobj)
|
||||
|
||||
if strip_old_text:
|
||||
strip_invisible_text(self.pdf_base, base_page)
|
||||
|
||||
base_page.page_contents_add(new_text_layer, prepend=True)
|
||||
|
||||
_update_page_resources(
|
||||
page=base_page, font=font, font_key=font_key, procset=procset
|
||||
_update_resources(
|
||||
obj=base_page, font=font, font_key=font_key, procset=procset
|
||||
)
|
||||
|
||||
+77
-28
@@ -13,15 +13,15 @@ from contextlib import suppress
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from shutil import copyfileobj
|
||||
from typing import BinaryIO, Dict, Iterable, Optional, Union, cast
|
||||
from typing import Dict, Iterable, Optional
|
||||
|
||||
import img2pdf
|
||||
import pikepdf
|
||||
from pikepdf.models.metadata import encode_pdf_date
|
||||
from PIL import Image, ImageColor, ImageDraw
|
||||
from tqdm import tqdm
|
||||
|
||||
from ocrmypdf import leptonica
|
||||
from ocrmypdf._concurrent import Executor
|
||||
from ocrmypdf._exec import unpaper
|
||||
from ocrmypdf._jobcontext import PageContext, PdfContext
|
||||
from ocrmypdf._version import PROGRAM_NAME
|
||||
@@ -146,6 +146,8 @@ def triage(original_filename, input_file, output_file, options):
|
||||
|
||||
def get_pdfinfo(
|
||||
input_file,
|
||||
*,
|
||||
executor: Executor,
|
||||
detailed_analysis=False,
|
||||
progbar=False,
|
||||
max_workers=None,
|
||||
@@ -158,11 +160,12 @@ def get_pdfinfo(
|
||||
progbar=progbar,
|
||||
max_workers=max_workers,
|
||||
check_pages=check_pages,
|
||||
executor=executor,
|
||||
)
|
||||
except pikepdf.PasswordError:
|
||||
raise EncryptedPdfError()
|
||||
except pikepdf.PdfError:
|
||||
raise InputFileError()
|
||||
except pikepdf.PasswordError as e:
|
||||
raise EncryptedPdfError() from e
|
||||
except pikepdf.PdfError as e:
|
||||
raise InputFileError() from e
|
||||
|
||||
|
||||
def validate_pdfinfo_options(context: PdfContext):
|
||||
@@ -480,7 +483,12 @@ def preprocess_deskew(input_file: Path, page_context: PageContext):
|
||||
def preprocess_clean(input_file: Path, page_context: PageContext):
|
||||
output_file = page_context.get_path('pp_clean.png')
|
||||
dpi = get_page_square_dpi(page_context.pageinfo, page_context.options)
|
||||
unpaper.clean(input_file, output_file, dpi.x, page_context.options.unpaper_args)
|
||||
unpaper.clean(
|
||||
input_file,
|
||||
output_file,
|
||||
dpi=dpi.x,
|
||||
unpaper_args=page_context.options.unpaper_args,
|
||||
)
|
||||
return output_file
|
||||
|
||||
|
||||
@@ -584,7 +592,9 @@ def create_visible_page_jpg(image: Path, page_context: PageContext) -> Path:
|
||||
return output_file
|
||||
|
||||
|
||||
def create_pdf_page_from_image(image: Path, page_context: PageContext):
|
||||
def create_pdf_page_from_image(
|
||||
image: Path, page_context: PageContext, orientation_correction
|
||||
):
|
||||
# We rasterize a square DPI version of each page because most image
|
||||
# processing tools don't support rectangular DPI. Use the square DPI as it
|
||||
# accurately describes the image. It would be possible to resample the image
|
||||
@@ -595,7 +605,8 @@ def create_pdf_page_from_image(image: Path, page_context: PageContext):
|
||||
|
||||
pageinfo = page_context.pageinfo
|
||||
pagesize = 72.0 * float(pageinfo.width_inches), 72.0 * float(pageinfo.height_inches)
|
||||
if pageinfo.rotation % 180 == 90:
|
||||
effective_rotation = (pageinfo.rotation - orientation_correction) % 360
|
||||
if effective_rotation % 180 == 90:
|
||||
pagesize = pagesize[1], pagesize[0]
|
||||
|
||||
# This create a single page PDF
|
||||
@@ -607,6 +618,11 @@ def create_pdf_page_from_image(image: Path, page_context: PageContext):
|
||||
imfile, with_pdfrw=False, layout_fun=layout_fun, outputstream=pdf
|
||||
)
|
||||
log.debug('convert done')
|
||||
|
||||
output_file = page_context.plugin_manager.hook.filter_pdf_page(
|
||||
page=page_context, image_filename=image, output_pdf=output_file
|
||||
)
|
||||
|
||||
return output_file
|
||||
|
||||
|
||||
@@ -616,9 +632,9 @@ def render_hocr_page(hocr: Path, page_context: PageContext):
|
||||
dpi = get_page_square_dpi(page_context.pageinfo, options)
|
||||
debug_mode = options.pdf_renderer == 'hocrdebug'
|
||||
|
||||
hocrtransform = HocrTransform(hocr, dpi.x) # square
|
||||
hocrtransform = HocrTransform(hocr_filename=hocr, dpi=dpi.x) # square
|
||||
hocrtransform.to_pdf(
|
||||
output_file,
|
||||
out_filename=output_file,
|
||||
image_filename=None,
|
||||
show_bounding_boxes=False if not debug_mode else True,
|
||||
invisible_text=True if not debug_mode else False,
|
||||
@@ -670,11 +686,6 @@ def get_docinfo(base_pdf: pikepdf.Pdf, context: PdfContext) -> Dict[str, str]:
|
||||
|
||||
pdfmark['/Creator'] = f'{PROGRAM_NAME} {VERSION} / {creator_tag}'
|
||||
pdfmark['/Producer'] = f'pikepdf {pikepdf.__version__}'
|
||||
if 'OCRMYPDF_CREATOR' in os.environ:
|
||||
pdfmark['/Creator'] = os.environ['OCRMYPDF_CREATOR']
|
||||
if 'OCRMYPDF_PRODUCER' in os.environ:
|
||||
pdfmark['/Producer'] = os.environ['OCRMYPDF_PRODUCER']
|
||||
|
||||
pdfmark['/ModDate'] = encode_pdf_date(datetime.now(timezone.utc))
|
||||
return pdfmark
|
||||
|
||||
@@ -722,7 +733,11 @@ def convert_to_pdfa(input_pdf: Path, input_ps_stub: Path, context: PdfContext):
|
||||
output_file=output_file,
|
||||
compression=options.pdfa_image_compression,
|
||||
pdfa_part=options.output_type[-1], # is pdfa-1, pdfa-2, or pdfa-3
|
||||
progressbar_class=tqdm if options.progress_bar else None,
|
||||
progressbar_class=(
|
||||
context.plugin_manager.hook.get_progressbar_class()
|
||||
if options.progress_bar
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
return output_file
|
||||
@@ -735,6 +750,24 @@ def should_linearize(working_file: Path, context: PdfContext):
|
||||
return False
|
||||
|
||||
|
||||
def get_pdf_save_settings(output_type: str):
|
||||
if output_type == 'pdfa-1':
|
||||
# Trigger recompression to ensure object streams are removed, because
|
||||
# Acrobat complains about them in PDF/A-1b validation.
|
||||
return dict(
|
||||
preserve_pdfa=True,
|
||||
compress_streams=True,
|
||||
stream_decode_level=pikepdf.StreamDecodeLevel.generalized,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.disable,
|
||||
)
|
||||
else:
|
||||
return dict(
|
||||
preserve_pdfa=True,
|
||||
compress_streams=True,
|
||||
object_stream_mode=(pikepdf.ObjectStreamMode.generate),
|
||||
)
|
||||
|
||||
|
||||
def metadata_fixup(working_file: Path, context: PdfContext):
|
||||
output_file = context.get_path('metafix.pdf')
|
||||
options = context.options
|
||||
@@ -779,9 +812,7 @@ def metadata_fixup(working_file: Path, context: PdfContext):
|
||||
|
||||
pdf.save(
|
||||
output_file,
|
||||
compress_streams=True,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
**get_pdf_save_settings(options.output_type),
|
||||
linearize=( # Don't linearize if optimize() will be linearizing too
|
||||
should_linearize(working_file, context)
|
||||
if options.optimize == 0
|
||||
@@ -792,23 +823,37 @@ def metadata_fixup(working_file: Path, context: PdfContext):
|
||||
return output_file
|
||||
|
||||
|
||||
def optimize_pdf(input_file: Path, context: PdfContext):
|
||||
def optimize_pdf(input_file: Path, context: PdfContext, executor: Executor):
|
||||
output_file = context.get_path('optimize.pdf')
|
||||
save_settings = dict(
|
||||
compress_streams=True,
|
||||
preserve_pdfa=True,
|
||||
object_stream_mode=pikepdf.ObjectStreamMode.generate,
|
||||
linearize=should_linearize(input_file, context),
|
||||
**get_pdf_save_settings(context.options.output_type),
|
||||
)
|
||||
optimize(input_file, output_file, context, save_settings)
|
||||
optimize(input_file, output_file, context, save_settings, executor)
|
||||
return output_file
|
||||
|
||||
|
||||
def enumerate_compress_ranges(iterable):
|
||||
skipped_from, index = None, 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_:
|
||||
@@ -821,7 +866,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
|
||||
|
||||
|
||||
|
||||
@@ -66,15 +66,26 @@ class OcrmypdfPluginManager(pluggy.PluginManager):
|
||||
|
||||
# 1. Register builtins
|
||||
if self.__builtins:
|
||||
for module in pkgutil.iter_modules(ocrmypdf.builtin_plugins.__path__):
|
||||
for module in sorted(
|
||||
pkgutil.iter_modules(ocrmypdf.builtin_plugins.__path__)
|
||||
):
|
||||
name = f'ocrmypdf.builtin_plugins.{module.name}'
|
||||
module = importlib.import_module(name)
|
||||
self.register(module)
|
||||
|
||||
# 2. Register setuptools plugins
|
||||
# 2. Install semfree if needed
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from multiprocessing.synchronize import SemLock
|
||||
|
||||
del SemLock
|
||||
except ImportError:
|
||||
self.register(importlib.import_module('ocrmypdf.extra_plugins.semfree'))
|
||||
|
||||
# 3. Register setuptools plugins
|
||||
self.load_setuptools_entrypoints('ocrmypdf')
|
||||
|
||||
# 3. Register plugins specified on command line
|
||||
# 4. Register plugins specified on command line
|
||||
for name in self.__plugins:
|
||||
if isinstance(name, Path) or name.endswith('.py'):
|
||||
# Import by filename
|
||||
|
||||
+12
-11
@@ -15,10 +15,9 @@ from pathlib import Path
|
||||
from tempfile import mkdtemp
|
||||
from typing import List, NamedTuple, Optional, Tuple
|
||||
|
||||
import pikepdf
|
||||
import PIL
|
||||
|
||||
from ocrmypdf._concurrent import exec_progress_pool
|
||||
from ocrmypdf._concurrent import Executor, setup_executor
|
||||
from ocrmypdf._graft import OcrGrafter
|
||||
from ocrmypdf._jobcontext import PageContext, PdfContext, cleanup_working_files
|
||||
from ocrmypdf._logging import PageNumberFilter
|
||||
@@ -66,7 +65,7 @@ from ocrmypdf.pdfa import file_claims_pdfa
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PageResult(NamedTuple):
|
||||
class PageResult(NamedTuple): # pylint: disable=inherit-non-class
|
||||
pageno: int
|
||||
pdf_page_from_image: Optional[Path]
|
||||
ocr: Optional[Path]
|
||||
@@ -204,7 +203,7 @@ def exec_page_sync(page_context: PageContext):
|
||||
if filtered_image:
|
||||
visible_image_out = filtered_image
|
||||
pdf_page_from_image_out = create_pdf_page_from_image(
|
||||
visible_image_out, page_context
|
||||
visible_image_out, page_context, orientation_correction
|
||||
)
|
||||
|
||||
if options.pdf_renderer.startswith('hocr'):
|
||||
@@ -224,14 +223,14 @@ def exec_page_sync(page_context: PageContext):
|
||||
)
|
||||
|
||||
|
||||
def post_process(pdf_file, context: PdfContext):
|
||||
def post_process(pdf_file, context: PdfContext, executor: Executor):
|
||||
pdf_out = pdf_file
|
||||
if context.options.output_type.startswith('pdfa'):
|
||||
ps_stub_out = generate_postscript_stub(context)
|
||||
pdf_out = convert_to_pdfa(pdf_out, ps_stub_out, context)
|
||||
|
||||
pdf_out = metadata_fixup(pdf_out, context)
|
||||
return optimize_pdf(pdf_out, context)
|
||||
return optimize_pdf(pdf_out, context, executor)
|
||||
|
||||
|
||||
def worker_init(max_pixels: int):
|
||||
@@ -242,7 +241,7 @@ def worker_init(max_pixels: int):
|
||||
pikepdf_enable_mmap()
|
||||
|
||||
|
||||
def exec_concurrent(context: PdfContext):
|
||||
def exec_concurrent(context: PdfContext, executor: Executor):
|
||||
"""Execute the pipeline concurrently"""
|
||||
|
||||
# Run exec_page_sync on every page context
|
||||
@@ -269,7 +268,7 @@ def exec_concurrent(context: PdfContext):
|
||||
finally:
|
||||
tls.pageno = None
|
||||
|
||||
exec_progress_pool(
|
||||
executor(
|
||||
use_threads=options.use_threads,
|
||||
max_workers=max_workers,
|
||||
tqdm_kwargs=dict(
|
||||
@@ -279,7 +278,7 @@ def exec_concurrent(context: PdfContext):
|
||||
unit_scale=0.5,
|
||||
disable=not options.progress_bar,
|
||||
),
|
||||
task_initializer=partial(worker_init, PIL.Image.MAX_IMAGE_PIXELS),
|
||||
worker_initializer=partial(worker_init, PIL.Image.MAX_IMAGE_PIXELS),
|
||||
task=exec_page_sync,
|
||||
task_arguments=context.get_page_contexts(),
|
||||
task_finished=update_page,
|
||||
@@ -296,7 +295,7 @@ def exec_concurrent(context: PdfContext):
|
||||
|
||||
# PDF/A and metadata
|
||||
log.info("Postprocessing...")
|
||||
pdf = post_process(pdf, context)
|
||||
pdf = post_process(pdf, context, executor)
|
||||
|
||||
# Copy PDF file to destination
|
||||
copy_final(pdf, options.output_file, context)
|
||||
@@ -346,6 +345,7 @@ def run_pipeline(options, *, plugin_manager, api=False):
|
||||
|
||||
pikepdf_enable_mmap()
|
||||
|
||||
executor = setup_executor(plugin_manager)
|
||||
try:
|
||||
check_requested_output_file(options)
|
||||
start_input_file, original_filename = create_input_file(options, work_folder)
|
||||
@@ -358,6 +358,7 @@ def run_pipeline(options, *, plugin_manager, api=False):
|
||||
# Gather pdfinfo and create context
|
||||
pdfinfo = get_pdfinfo(
|
||||
origin_pdf,
|
||||
executor=executor,
|
||||
detailed_analysis=options.redo_ocr,
|
||||
progbar=options.progress_bar,
|
||||
max_workers=options.jobs if not options.use_threads else 1, # To help debug
|
||||
@@ -370,7 +371,7 @@ def run_pipeline(options, *, plugin_manager, api=False):
|
||||
validate_pdfinfo_options(context)
|
||||
|
||||
# Execute the pipeline
|
||||
exec_concurrent(context)
|
||||
exec_concurrent(context, executor)
|
||||
|
||||
if options.output_file == '-':
|
||||
log.info("Output sent to stdout")
|
||||
|
||||
@@ -112,6 +112,10 @@ def check_options_sidecar(options):
|
||||
"--sidecar filename must be specified when output file is stdout."
|
||||
)
|
||||
options.sidecar = options.output_file + '.txt'
|
||||
if options.sidecar == options.input_file or options.sidecar == options.output_file:
|
||||
raise BadArgsError(
|
||||
"--sidecar file must be different from the input and output files"
|
||||
)
|
||||
|
||||
|
||||
def check_options_preprocessing(options):
|
||||
@@ -133,7 +137,7 @@ def check_options_preprocessing(options):
|
||||
options.unpaper_args
|
||||
)
|
||||
except Exception as e:
|
||||
raise BadArgsError(str(e))
|
||||
raise BadArgsError("--unpaper-args: " + str(e)) from e
|
||||
|
||||
|
||||
def _pages_from_ranges(ranges: str) -> Set[int]:
|
||||
@@ -184,8 +188,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)
|
||||
|
||||
@@ -339,7 +341,17 @@ def create_input_file(options, work_folder: Path) -> Tuple[Path, str]:
|
||||
safe_symlink(options.input_file, target)
|
||||
return target, os.fspath(options.input_file)
|
||||
except FileNotFoundError:
|
||||
raise InputFileError(f"File not found - {options.input_file}")
|
||||
msg = f"File not found - {options.input_file}"
|
||||
if Path('/.dockerenv').exists(): # pragma: no cover
|
||||
msg += (
|
||||
"\nDocker cannot your working directory unless you "
|
||||
"explicitly share it with the Docker container and set up"
|
||||
"permissions correctly.\n"
|
||||
"You may find it easier to use stdin/stdout:"
|
||||
"\n"
|
||||
"\tdocker run -i --rm jbarlow83/ocrmypdf - - <input.pdf >output.pdf\n"
|
||||
)
|
||||
raise InputFileError(msg)
|
||||
|
||||
|
||||
def check_requested_output_file(options):
|
||||
|
||||
+27
-13
@@ -15,7 +15,10 @@ from pathlib import Path
|
||||
from typing import AnyStr, BinaryIO, Iterable, Optional, Union
|
||||
from warnings import warn
|
||||
|
||||
from ocrmypdf._logging import PageNumberFilter, TqdmConsole
|
||||
from ocrmypdf._logging import ( # pylint: disable=unused-import
|
||||
PageNumberFilter,
|
||||
TqdmConsole,
|
||||
)
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf._sync import run_pipeline
|
||||
from ocrmypdf._validation import check_options
|
||||
@@ -45,18 +48,23 @@ class Verbosity(IntEnum):
|
||||
|
||||
def configure_logging(
|
||||
verbosity: Verbosity,
|
||||
*,
|
||||
progress_bar_friendly: bool = True,
|
||||
manage_root_logger: bool = False,
|
||||
plugin_manager=None,
|
||||
):
|
||||
"""Set up logging.
|
||||
|
||||
Before calling :func:`ocrmypdf.ocr()`, you can use this function to
|
||||
configure logging, if you want ocrmypdf's output to look like the ocrmypdf
|
||||
configure logging if you want ocrmypdf's output to look like the ocrmypdf
|
||||
command line interface. It will register log handlers, log filters, and
|
||||
formatters, configure color logging to standard error, and adjust the log
|
||||
levels of third party libraries. Details of this are fine-tuned and subject
|
||||
to change. The ``verbosity`` argument is equivalent to the argument
|
||||
``--verbose`` and applies those settings.
|
||||
``--verbose`` and applies those settings. If you have a wrapper
|
||||
script for ocrmypdf and you want it to be very similar to ocrmypdf, use this
|
||||
function; if you are using ocrmypdf as part of an application that manages
|
||||
its own logging, you probably do not want this function.
|
||||
|
||||
If this function is not called, ocrmypdf will not configure logging, and it
|
||||
is up to the caller of ``ocrmypdf.ocr()`` to set up logging as it wishes using
|
||||
@@ -74,12 +82,11 @@ def configure_logging(
|
||||
their own debug logging.
|
||||
|
||||
Args:
|
||||
verbosity (Verbosity): Verbosity level.
|
||||
progress_bar_friendly (bool): Install the TqdmConsole log handler, which is
|
||||
compatible with the tqdm progress bar; without this log messages will
|
||||
overwrite the progress bar
|
||||
manage_root_logger (bool): Configure the process's root logger, to ensure
|
||||
all log output is sent through
|
||||
verbosity: Verbosity level.
|
||||
progress_bar_friendly: If True (the default), install a custom log handler
|
||||
that is compatible with progress bars and colored output.
|
||||
manage_root_logger: Configure the process's root logger.
|
||||
plugin_manager: The plugin manager, used for obtaining the custom log handler.
|
||||
|
||||
Returns:
|
||||
The toplevel logger for ocrmypdf (or the root logger, if we are managing it).
|
||||
@@ -90,9 +97,11 @@ def configure_logging(
|
||||
log = logging.getLogger(prefix)
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
if progress_bar_friendly:
|
||||
console = logging.StreamHandler(stream=TqdmConsole(sys.stderr))
|
||||
else:
|
||||
console = None
|
||||
if plugin_manager and progress_bar_friendly:
|
||||
console = plugin_manager.hook.get_logging_console()
|
||||
|
||||
if not console:
|
||||
console = logging.StreamHandler(stream=sys.stderr)
|
||||
|
||||
if verbosity < 0:
|
||||
@@ -245,6 +254,7 @@ def ocr( # pylint: disable=unused-argument
|
||||
user_patterns: os.PathLike = None,
|
||||
fast_web_view: float = None,
|
||||
plugins: Iterable[StrPath] = None,
|
||||
plugin_manager=None,
|
||||
keep_temporary_files: bool = None,
|
||||
progress_bar: bool = None,
|
||||
**kwargs,
|
||||
@@ -296,6 +306,9 @@ def ocr( # pylint: disable=unused-argument
|
||||
Returns:
|
||||
:class:`ocrmypdf.ExitCode`
|
||||
"""
|
||||
if plugins and plugin_manager:
|
||||
raise ValueError("plugins= and plugin_manager are mutually exclusive")
|
||||
|
||||
if not plugins:
|
||||
plugins = []
|
||||
elif isinstance(plugins, (str, Path)):
|
||||
@@ -315,7 +328,8 @@ def ocr( # pylint: disable=unused-argument
|
||||
# they might install different plugins, and generally speaking we have areas
|
||||
# of code that use global state.
|
||||
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
if not plugin_manager:
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member
|
||||
|
||||
if 'verbose' in kwargs:
|
||||
|
||||
@@ -3,3 +3,7 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file exists only mark builtin_plugins as a package.
|
||||
# The plugin manager will not load it, so anything defined here may not be
|
||||
# processed as a module.
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
# © 2020 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# © 2020 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
import multiprocessing
|
||||
import os
|
||||
import queue
|
||||
import signal
|
||||
import sys
|
||||
import threading
|
||||
from contextlib import suppress
|
||||
from multiprocessing import Pool as ProcessPool
|
||||
from multiprocessing.pool import ThreadPool
|
||||
from typing import Callable, Iterable, Union
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
from ocrmypdf import Executor, hookimpl
|
||||
from ocrmypdf._logging import TqdmConsole
|
||||
from ocrmypdf.exceptions import InputFileError
|
||||
from ocrmypdf.helpers import remove_all_log_handlers
|
||||
|
||||
Queue = Union[multiprocessing.Queue, queue.Queue]
|
||||
|
||||
|
||||
def log_listener(q: Queue):
|
||||
"""Listen to the worker processes and forward the messages to logging
|
||||
|
||||
For simplicity this is a thread rather than a process. Only one process
|
||||
should actually write to sys.stderr or whatever we're using, so if this is
|
||||
made into a process the main application needs to be directed to it.
|
||||
|
||||
See https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes
|
||||
"""
|
||||
|
||||
while True:
|
||||
try:
|
||||
record = q.get()
|
||||
if record is None:
|
||||
break
|
||||
logger = logging.getLogger(record.name)
|
||||
logger.handle(record)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
import traceback # pylint: disable=import-outside-toplevel
|
||||
|
||||
print("Logging problem", file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
|
||||
def process_sigbus(*args):
|
||||
raise InputFileError("A worker process lost access to an input file")
|
||||
|
||||
|
||||
def process_init(q: Queue, user_init: Callable[[], None], loglevel):
|
||||
"""Initialize a process pool worker"""
|
||||
|
||||
# Ignore SIGINT (our parent process will kill us gracefully)
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
|
||||
# Install SIGBUS handler (so our parent process can abort somewhat gracefully)
|
||||
with suppress(AttributeError): # Windows and Cygwin do not have SIGBUS
|
||||
# Windows and Cygwin do not have pthread_sigmask or SIGBUS
|
||||
signal.signal(signal.SIGBUS, process_sigbus)
|
||||
|
||||
# Remove any log handlers that belong to the parent process
|
||||
root = logging.getLogger()
|
||||
remove_all_log_handlers(root)
|
||||
|
||||
# Set up our single log handler to forward messages to the parent
|
||||
root.setLevel(loglevel)
|
||||
root.addHandler(logging.handlers.QueueHandler(q))
|
||||
|
||||
user_init()
|
||||
return
|
||||
|
||||
|
||||
def thread_init(_queue: Queue, user_init: Callable[[], None], _loglevel):
|
||||
# As a thread, block SIGBUS so the main thread deals with it...
|
||||
with suppress(AttributeError):
|
||||
signal.pthread_sigmask(signal.SIG_BLOCK, {signal.SIGBUS})
|
||||
|
||||
user_init()
|
||||
return
|
||||
|
||||
|
||||
class StandardExecutor(Executor):
|
||||
def _execute(
|
||||
self,
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
worker_initializer: Callable,
|
||||
task: Callable,
|
||||
task_arguments: Iterable,
|
||||
task_finished: Callable,
|
||||
):
|
||||
if use_threads:
|
||||
log_queue = queue.Queue(-1)
|
||||
pool_class = ThreadPool
|
||||
initializer = thread_init
|
||||
else:
|
||||
log_queue = multiprocessing.Queue(-1)
|
||||
pool_class = ProcessPool
|
||||
initializer = process_init
|
||||
|
||||
# Regardless of whether we use_threads for worker processes, the log_listener
|
||||
# must be a thread. Make sure we create the listener after the worker pool,
|
||||
# so that it does not get forked into the workers.
|
||||
listener = threading.Thread(target=log_listener, args=(log_queue,))
|
||||
listener.start()
|
||||
|
||||
with self.pbar_class(**tqdm_kwargs) as pbar:
|
||||
pool = pool_class(
|
||||
processes=max_workers,
|
||||
initializer=initializer,
|
||||
initargs=(log_queue, worker_initializer, logging.getLogger("").level),
|
||||
)
|
||||
try:
|
||||
results = pool.imap_unordered(task, task_arguments)
|
||||
for result in results:
|
||||
if task_finished:
|
||||
task_finished(result, pbar)
|
||||
else:
|
||||
pbar.update()
|
||||
except KeyboardInterrupt:
|
||||
# Terminate pool so we exit instantly
|
||||
pool.terminate()
|
||||
# Don't try listener.join() here, will deadlock
|
||||
raise
|
||||
except Exception:
|
||||
if not os.environ.get("PYTEST_CURRENT_TEST", ""):
|
||||
# Unless inside pytest, exit immediately because no one wants
|
||||
# to wait for child processes to finalize results that will be
|
||||
# thrown away. Inside pytest, we want child processes to exit
|
||||
# cleanly so that they output an error messages or coverage data
|
||||
# we need from them.
|
||||
pool.terminate()
|
||||
raise
|
||||
finally:
|
||||
# Terminate log listener
|
||||
log_queue.put_nowait(None)
|
||||
pool.close()
|
||||
pool.join()
|
||||
|
||||
listener.join()
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_executor(progressbar_class):
|
||||
return StandardExecutor(pbar_class=progressbar_class)
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_progressbar_class():
|
||||
return tqdm
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_logging_console():
|
||||
return logging.StreamHandler(stream=TqdmConsole(sys.stderr))
|
||||
@@ -0,0 +1,14 @@
|
||||
# © 2021 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from ocrmypdf import hookimpl
|
||||
|
||||
|
||||
@hookimpl
|
||||
def filter_pdf_page(
|
||||
page, image_filename, output_pdf
|
||||
): # pylint: disable=unused-argument
|
||||
return output_pdf
|
||||
@@ -80,20 +80,14 @@ def check_options(options):
|
||||
program='tesseract',
|
||||
package={'linux': 'tesseract-ocr'},
|
||||
version_checker=tesseract.version,
|
||||
need_version='4.0.0', # using backport for Travis CI
|
||||
need_version='4.0.0-beta.1', # using backport for Travis CI
|
||||
version_parser=tesseract.TesseractVersion,
|
||||
)
|
||||
|
||||
# Decide on what renderer to use
|
||||
if options.pdf_renderer == 'auto':
|
||||
options.pdf_renderer = 'sandwich'
|
||||
|
||||
if options.pdf_renderer == 'sandwich' and not tesseract.has_textonly_pdf(
|
||||
set(options.languages)
|
||||
):
|
||||
raise MissingDependencyError(
|
||||
"You are using an alpha version of Tesseract 4.0 that does not support "
|
||||
"the textonly_pdf parameter. We don't support versions this old."
|
||||
)
|
||||
if not tesseract.has_user_words() and (options.user_words or options.user_patterns):
|
||||
log.warning(
|
||||
"Tesseract 4.0 ignores --user-words and --user-patterns, so these "
|
||||
|
||||
+2
-1
@@ -167,7 +167,8 @@ Online documentation is located at:
|
||||
metavar='FILE',
|
||||
help="Generate sidecar text files that contain the same text recognized "
|
||||
"by Tesseract. This may be useful for building a OCR text database. "
|
||||
"If FILE is omitted, the sidecar file be named {output_file}.txt "
|
||||
"If FILE is omitted, the sidecar file be named {output_file}.txt; the next "
|
||||
"argument must NOT be the name of the input PDF. "
|
||||
"If FILE is set to '-', the sidecar is written to stdout (a "
|
||||
"convenient way to preview OCR quality). The output file and sidecar "
|
||||
"may not both use stdout at the same time.",
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
# © 2021 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
"""Semaphore-free alternate executor.
|
||||
|
||||
There are two popular environments that do not fully support the standard Python
|
||||
multiprocessing module: AWS Lambda, and Termux (a terminal emulator for Android).
|
||||
|
||||
This alternate executor divvies up work among worker processes before processing,
|
||||
rather than having each worker consume work from a shared queue when they finish
|
||||
their task. This means workers have no need to coordinate with each other. Each
|
||||
worker communicates only with the main process.
|
||||
|
||||
This is not without drawbacks. If the tasks are not "even" in size, which cannot
|
||||
be guaranteed, some workers may end up with too much work while others are idle.
|
||||
It is less efficient than the standard implementation, so not th edefault.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
import signal
|
||||
from contextlib import suppress
|
||||
from enum import Enum, auto
|
||||
from itertools import islice, repeat, takewhile, zip_longest
|
||||
from multiprocessing import Pipe, Process
|
||||
from multiprocessing.connection import Connection, wait
|
||||
from typing import Callable, Iterable, Iterator
|
||||
|
||||
from ocrmypdf import Executor, hookimpl
|
||||
from ocrmypdf._concurrent import NullProgressBar
|
||||
from ocrmypdf.exceptions import InputFileError
|
||||
from ocrmypdf.helpers import remove_all_log_handlers
|
||||
|
||||
|
||||
class MessageType(Enum):
|
||||
exception = auto()
|
||||
result = auto()
|
||||
complete = auto()
|
||||
|
||||
|
||||
def split_every(n: int, iterable: Iterable) -> Iterator:
|
||||
"""Split iterable into groups of n.
|
||||
|
||||
>>> list(split_every(4, range(10)))
|
||||
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
|
||||
|
||||
https://stackoverflow.com/a/22919323
|
||||
"""
|
||||
iterator = iter(iterable)
|
||||
return takewhile(bool, (list(islice(iterator, n)) for _ in repeat(None)))
|
||||
|
||||
|
||||
def process_sigbus(*args):
|
||||
raise InputFileError("A worker process lost access to an input file")
|
||||
|
||||
|
||||
class ConnectionLogHandler(logging.handlers.QueueHandler):
|
||||
def __init__(self, conn: Connection) -> None:
|
||||
super().__init__(None)
|
||||
self.conn = conn
|
||||
|
||||
def enqueue(self, record):
|
||||
self.conn.send(('log', record))
|
||||
|
||||
|
||||
def process_loop(
|
||||
conn: Connection, user_init: Callable[[], None], loglevel, task, task_args
|
||||
):
|
||||
"""Initialize a process pool worker"""
|
||||
|
||||
# Install SIGBUS handler (so our parent process can abort somewhat gracefully)
|
||||
with suppress(AttributeError): # Windows and Cygwin do not have SIGBUS
|
||||
# Windows and Cygwin do not have pthread_sigmask or SIGBUS
|
||||
signal.signal(signal.SIGBUS, process_sigbus)
|
||||
|
||||
# Reconfigure the root logger for this process to send all messages to a queue
|
||||
h = ConnectionLogHandler(conn)
|
||||
root = logging.getLogger()
|
||||
remove_all_log_handlers(root)
|
||||
root.setLevel(loglevel)
|
||||
root.addHandler(h)
|
||||
|
||||
user_init()
|
||||
|
||||
for args in task_args:
|
||||
try:
|
||||
result = task(args)
|
||||
except Exception as e:
|
||||
conn.send((MessageType.exception, e))
|
||||
break
|
||||
else:
|
||||
conn.send((MessageType.result, result))
|
||||
|
||||
conn.send((MessageType.complete, None))
|
||||
conn.close()
|
||||
return
|
||||
|
||||
|
||||
class LambdaExecutor(Executor):
|
||||
def _execute(
|
||||
self,
|
||||
*,
|
||||
use_threads: bool,
|
||||
max_workers: int,
|
||||
tqdm_kwargs: dict,
|
||||
worker_initializer: Callable,
|
||||
task: Callable,
|
||||
task_arguments: Iterable,
|
||||
task_finished: Callable,
|
||||
):
|
||||
if use_threads and max_workers == 1:
|
||||
with self.pbar_class(**tqdm_kwargs) as pbar:
|
||||
for args in task_arguments:
|
||||
result = task(args)
|
||||
task_finished(result, pbar)
|
||||
return
|
||||
|
||||
task_arguments = list(task_arguments)
|
||||
grouped_args = list(
|
||||
zip_longest(*list(split_every(max_workers, task_arguments)))
|
||||
)
|
||||
if not grouped_args:
|
||||
return
|
||||
|
||||
processes = []
|
||||
connections = []
|
||||
for chunk in grouped_args:
|
||||
parent_conn, child_conn = Pipe()
|
||||
|
||||
worker_args = [args for args in chunk if args is not None]
|
||||
process = Process(
|
||||
target=process_loop,
|
||||
args=(
|
||||
child_conn,
|
||||
worker_initializer,
|
||||
logging.getLogger("").level,
|
||||
task,
|
||||
worker_args,
|
||||
),
|
||||
)
|
||||
process.daemon = True
|
||||
processes.append(process)
|
||||
connections.append(parent_conn)
|
||||
|
||||
for process in processes:
|
||||
process.start()
|
||||
|
||||
with self.pbar_class(**tqdm_kwargs) as pbar:
|
||||
while connections:
|
||||
for r in wait(connections):
|
||||
try:
|
||||
msg_type, msg = r.recv()
|
||||
except EOFError:
|
||||
connections.remove(r)
|
||||
continue
|
||||
|
||||
if msg_type == MessageType.result:
|
||||
if task_finished:
|
||||
task_finished(msg, pbar)
|
||||
elif msg_type == 'log':
|
||||
record = msg
|
||||
logger = logging.getLogger(record.name)
|
||||
logger.handle(record)
|
||||
elif msg_type == MessageType.complete:
|
||||
connections.remove(r)
|
||||
elif msg_type == MessageType.exception:
|
||||
for process in processes:
|
||||
process.terminate()
|
||||
raise msg
|
||||
|
||||
for process in processes:
|
||||
process.join()
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_executor(progressbar_class):
|
||||
return LambdaExecutor(pbar_class=progressbar_class)
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_logging_console():
|
||||
return logging.StreamHandler()
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_progressbar_class():
|
||||
return NullProgressBar
|
||||
+45
-38
@@ -15,7 +15,7 @@ from collections.abc import Iterable
|
||||
from contextlib import suppress
|
||||
from functools import wraps
|
||||
from io import StringIO
|
||||
from math import isclose
|
||||
from math import isclose, isfinite
|
||||
from pathlib import Path
|
||||
from typing import Any, Sequence
|
||||
|
||||
@@ -39,6 +39,10 @@ class Resolution(namedtuple('Resolution', ('x', 'y'))):
|
||||
def is_square(self) -> bool:
|
||||
return isclose(self.x, self.y, rel_tol=1e-3)
|
||||
|
||||
@property
|
||||
def is_finite(self) -> bool:
|
||||
return isfinite(self.x) and isfinite(self.y)
|
||||
|
||||
def take_max(self, vals, yvals=None):
|
||||
if yvals is not None:
|
||||
return Resolution(max(self.x, *vals), max(self.y, *yvals))
|
||||
@@ -54,7 +58,7 @@ class Resolution(namedtuple('Resolution', ('x', 'y'))):
|
||||
def __str__(self):
|
||||
return f"{self.x:f}x{self.y:f}"
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self): # pragma: no cover
|
||||
return f"Resolution({self.x}x{self.y} dpi)"
|
||||
|
||||
|
||||
@@ -87,10 +91,7 @@ def safe_symlink(input_file: os.PathLike, soft_link_name: os.PathLike):
|
||||
# do not delete or overwrite real (non-soft link) file
|
||||
if not os.path.islink(soft_link_name):
|
||||
raise FileExistsError(f"{soft_link_name} exists and is not a link")
|
||||
try:
|
||||
os.unlink(soft_link_name)
|
||||
except OSError:
|
||||
log.debug("Can't unlink %s", soft_link_name)
|
||||
os.unlink(soft_link_name)
|
||||
|
||||
if not os.path.exists(input_file):
|
||||
raise FileNotFoundError(f"trying to create a broken symlink to {input_file}")
|
||||
@@ -181,45 +182,44 @@ def check_pdf(input_file: Path) -> bool:
|
||||
Checks for proper formatting and proper linearization. Uses pikepdf (which in
|
||||
turn, uses QPDF) to perform the checks.
|
||||
"""
|
||||
pdf = None
|
||||
try:
|
||||
pdf = pikepdf.open(input_file)
|
||||
except pikepdf.PdfError as e:
|
||||
log.error(e)
|
||||
return False
|
||||
else:
|
||||
messages = pdf.check()
|
||||
for msg in messages:
|
||||
if 'error' in msg.lower():
|
||||
log.error(msg)
|
||||
with pdf:
|
||||
messages = pdf.check()
|
||||
for msg in messages:
|
||||
if 'error' in msg.lower():
|
||||
log.error(msg)
|
||||
else:
|
||||
log.warning(msg)
|
||||
|
||||
sio = StringIO()
|
||||
linearize_msgs = ''
|
||||
try:
|
||||
# If linearization is missing entirely, we do not complain. We do
|
||||
# complain if linearization is present but incorrect.
|
||||
pdf.check_linearization(sio)
|
||||
except RuntimeError:
|
||||
pass
|
||||
except (
|
||||
# Workaround for a problematic pikepdf version
|
||||
# pragma: no cover
|
||||
getattr(pikepdf, 'ForeignObjectError')
|
||||
if pikepdf.__version__ == '2.1.0'
|
||||
else NeverRaise
|
||||
):
|
||||
pass
|
||||
else:
|
||||
log.warning(msg)
|
||||
linearize_msgs = sio.getvalue()
|
||||
if linearize_msgs:
|
||||
log.warning(linearize_msgs)
|
||||
|
||||
sio = StringIO()
|
||||
linearize_msgs = ''
|
||||
try:
|
||||
# If linearization is missing entirely, we do not complain. We do
|
||||
# complain if linearization is present but incorrect.
|
||||
pdf.check_linearization(sio)
|
||||
except RuntimeError:
|
||||
pass
|
||||
except (
|
||||
getattr(pikepdf, 'ForeignObjectError')
|
||||
if pikepdf.__version__ == '2.1.0' # This version may throw wrong exception
|
||||
else NeverRaise
|
||||
):
|
||||
pass
|
||||
else:
|
||||
linearize_msgs = sio.getvalue()
|
||||
if linearize_msgs:
|
||||
log.warning(linearize_msgs)
|
||||
|
||||
if not messages and not linearize_msgs:
|
||||
return True
|
||||
return False
|
||||
finally:
|
||||
if pdf:
|
||||
pdf.close()
|
||||
if not messages and not linearize_msgs:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def clamp(n, smallest, largest): # mypy doesn't understand types for this
|
||||
@@ -227,6 +227,13 @@ def clamp(n, smallest, largest): # mypy doesn't understand types for this
|
||||
return max(smallest, min(n, largest))
|
||||
|
||||
|
||||
def remove_all_log_handlers(logger):
|
||||
"Remove all log handlers, usually used in a child process."
|
||||
for handler in logger.handlers[:]:
|
||||
logger.removeHandler(handler)
|
||||
handler.close() # To ensure handlers with opened resources are released
|
||||
|
||||
|
||||
def pikepdf_enable_mmap():
|
||||
# try:
|
||||
# if pikepdf._qpdf.set_access_default_mmap(True):
|
||||
@@ -236,7 +243,7 @@ def pikepdf_enable_mmap():
|
||||
# We found a race condition probably related to pybind issue #2252 that can
|
||||
# cause a crash. For now, disable pikepdf mmap to be on the safe side.
|
||||
# Fix is not in pybind11 2.6.0
|
||||
log.debug("pikepdf mmap disabled")
|
||||
# log.debug("pikepdf mmap disabled")
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ class HocrTransform:
|
||||
{'ff': 'ff', 'ffi': 'ffi', 'ffl': 'ffl', 'fi': 'fi', 'fl': 'fl'}
|
||||
)
|
||||
|
||||
def __init__(self, hocr_filename: Union[str, Path], dpi: float):
|
||||
def __init__(self, *, hocr_filename: Union[str, Path], dpi: float):
|
||||
self.dpi = dpi
|
||||
self.hocr = ElementTree.parse(os.fspath(hocr_filename))
|
||||
|
||||
@@ -182,6 +182,7 @@ class HocrTransform:
|
||||
|
||||
def to_pdf(
|
||||
self,
|
||||
*,
|
||||
out_filename: Path,
|
||||
image_filename: Optional[Path] = None,
|
||||
show_bounding_boxes: bool = False,
|
||||
@@ -433,10 +434,10 @@ if __name__ == "__main__":
|
||||
parser.add_argument('outputfile', help='Path to the PDF file to be generated')
|
||||
args = parser.parse_args()
|
||||
|
||||
hocr = HocrTransform(args.hocrfile, args.resolution)
|
||||
hocr = HocrTransform(hocr_filename=args.hocrfile, dpi=args.resolution)
|
||||
hocr.to_pdf(
|
||||
args.outputfile,
|
||||
args.image,
|
||||
args.boundingboxes,
|
||||
out_filename=args.outputfile,
|
||||
image_filename=args.image,
|
||||
show_bounding_boxes=args.boundingboxes,
|
||||
interword_spaces=args.interword_spaces,
|
||||
)
|
||||
|
||||
@@ -15,7 +15,6 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import warnings
|
||||
from collections import deque
|
||||
from collections.abc import Sequence
|
||||
from contextlib import suppress
|
||||
@@ -24,6 +23,7 @@ from functools import lru_cache
|
||||
from io import BytesIO, UnsupportedOperation
|
||||
from os import fspath
|
||||
from tempfile import TemporaryFile
|
||||
from warnings import warn
|
||||
|
||||
from ocrmypdf.exceptions import MissingDependencyError
|
||||
from ocrmypdf.lib._leptonica import ffi
|
||||
@@ -88,9 +88,9 @@ except ffi.error as e:
|
||||
|
||||
class _LeptonicaErrorTrap_Redirect:
|
||||
"""
|
||||
Context manager to trap errors reported by Leptonica.
|
||||
Context manager to trap errors reported by Leptonica < 1.79 or on Apple Silicon.
|
||||
|
||||
Leptonica's error return codes don't provide much informatino about what
|
||||
Leptonica's error return codes don't provide much information about what
|
||||
went wrong. Leptonica does, however, write more detailed errors to stderr
|
||||
(provided this is not disabled at compile time). The Leptonica source
|
||||
code is very consistent in its use of macros to generate errors.
|
||||
@@ -114,8 +114,10 @@ class _LeptonicaErrorTrap_Redirect:
|
||||
# Save the old stderr, and redirect stderr to temporary file
|
||||
self.leptonica_lock.acquire()
|
||||
try:
|
||||
with suppress(AttributeError):
|
||||
sys.stderr.flush()
|
||||
# It would make sense to do sys.stderr.flush() here, but that can deadlock
|
||||
# due to https://bugs.python.org/issue6721. So don't flush. Pretend
|
||||
# there's nothing important in sys.stderr. If the user cared they would
|
||||
# be using Leptonica 1.79 or later anyway to avoid this mess.
|
||||
self.copy_of_stderr = os.dup(sys.stderr.fileno())
|
||||
os.dup2(self.tmpfile.fileno(), sys.stderr.fileno(), inheritable=False)
|
||||
except AttributeError:
|
||||
@@ -389,7 +391,7 @@ class Pix(LeptonicaObject):
|
||||
|
||||
@classmethod
|
||||
def read(cls, path):
|
||||
warnings.warn('Use Pix.open() instead', DeprecationWarning)
|
||||
warn('Use Pix.open() instead', DeprecationWarning)
|
||||
return cls.open(path)
|
||||
|
||||
@classmethod
|
||||
|
||||
+91
-134
@@ -9,7 +9,6 @@ import logging
|
||||
import sys
|
||||
import tempfile
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
from os import fspath
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
@@ -29,14 +28,13 @@ import img2pdf
|
||||
import pikepdf
|
||||
from pikepdf import Dictionary, Name, Object, Pdf, PdfImage
|
||||
from PIL import Image
|
||||
from tqdm import tqdm
|
||||
|
||||
from ocrmypdf import leptonica
|
||||
from ocrmypdf._concurrent import exec_progress_pool
|
||||
from ocrmypdf._concurrent import Executor, SerialExecutor
|
||||
from ocrmypdf._exec import jbig2enc, pngquant
|
||||
from ocrmypdf._jobcontext import PdfContext
|
||||
from ocrmypdf.exceptions import OutputFileAccessError
|
||||
from ocrmypdf.helpers import deprecated, safe_symlink
|
||||
from ocrmypdf.helpers import safe_symlink
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -64,18 +62,20 @@ def jpg_name(root: Path, xref: Xref) -> Path:
|
||||
return img_name(root, xref, '.jpg')
|
||||
|
||||
|
||||
def tif_name(root: Path, xref: Xref) -> Path:
|
||||
return img_name(root, xref, '.tif')
|
||||
|
||||
|
||||
def extract_image_filter(
|
||||
pike: Pdf, root: Path, image: Object, xref: Xref
|
||||
) -> Optional[Tuple[PdfImage, Tuple[Name, Object]]]:
|
||||
del pike # unused args
|
||||
del root
|
||||
|
||||
if image.Subtype != Name.Image:
|
||||
return None
|
||||
if image.Length < 100:
|
||||
log.debug(f"Skipping small image, xref {xref}")
|
||||
return None
|
||||
if image.Width < 8 or image.Height < 8: # Issue 732
|
||||
log.debug(f"Skipping oddly sized image, xref {xref}")
|
||||
return None
|
||||
|
||||
pim = PdfImage(image)
|
||||
|
||||
@@ -92,6 +92,10 @@ def extract_image_filter(
|
||||
log.debug(f"Skipping JPEG2000 iamge, xref {xref}")
|
||||
return None # Don't do JPEG2000
|
||||
|
||||
if filtdp[0] == Name.CCITTFaxDecode and filtdp[1].get('/K', 0) >= 0:
|
||||
log.debug(f"Skipping CCITT Group 3 image, xref {xref}")
|
||||
return None # pikepdf doesn't support Group 3 yet
|
||||
|
||||
if Name.Decode in image:
|
||||
log.debug(f"Skipping image with Decode table, xref {xref}")
|
||||
return None # Don't mess with custom Decode tables
|
||||
@@ -102,6 +106,8 @@ def extract_image_filter(
|
||||
def extract_image_jbig2(
|
||||
*, pike: pikepdf.Pdf, root: Path, image: Object, xref: Xref, options
|
||||
) -> Optional[XrefExt]:
|
||||
del options # unused arg
|
||||
|
||||
result = extract_image_filter(pike, root, image, xref)
|
||||
if result is None:
|
||||
return None
|
||||
@@ -150,11 +156,6 @@ def extract_image_generic(
|
||||
if pim.bits_per_component == 1:
|
||||
return None
|
||||
|
||||
try:
|
||||
pim.indexed # pikepdf 1.6.3 can't handle [/Indexed [/Array...]]
|
||||
except NotImplementedError:
|
||||
return None
|
||||
|
||||
if filtdp[0] == Name.DCTDecode and options.optimize >= 2:
|
||||
# This is a simple heuristic derived from some training data, that has
|
||||
# about a 70% chance of guessing whether the JPEG is high quality,
|
||||
@@ -260,8 +261,8 @@ def extract_images(
|
||||
result = extract_fn(
|
||||
pike=pike, root=root, image=image, xref=xref, options=options
|
||||
)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
log.debug("Image xref %s, error %s", xref, repr(e))
|
||||
except Exception: # pylint: disable=broad-except
|
||||
log.exception(f"While extracting image xref {xref}, an error occurred")
|
||||
errors += 1
|
||||
else:
|
||||
if result:
|
||||
@@ -299,17 +300,17 @@ def extract_images_jbig2(pike: Pdf, root: Path, options) -> Dict[int, List[XrefE
|
||||
|
||||
|
||||
def _produce_jbig2_images(
|
||||
jbig2_groups: Dict[int, List[XrefExt]], root: Path, options
|
||||
jbig2_groups: Dict[int, List[XrefExt]], root: Path, options, executor: Executor
|
||||
) -> None:
|
||||
"""Produce JBIG2 images from their groups"""
|
||||
|
||||
def jbig2_group_args(root: Path, groups: Dict[int, List[XrefExt]]):
|
||||
for group, xref_exts in groups.items():
|
||||
prefix = f'group{group:08d}'
|
||||
yield dict(
|
||||
cwd=fspath(root),
|
||||
infiles=(img_name(root, xref, ext) for xref, ext in xref_exts),
|
||||
out_prefix=prefix,
|
||||
yield (
|
||||
fspath(root), # =cwd
|
||||
(img_name(root, xref, ext) for xref, ext in xref_exts), # =infiles
|
||||
prefix, # =out_prefix
|
||||
)
|
||||
|
||||
def jbig2_single_args(root, groups: Dict[int, List[XrefExt]]):
|
||||
@@ -318,23 +319,20 @@ def _produce_jbig2_images(
|
||||
# Second loop is to ensure multiple images per page are unpacked
|
||||
for n, xref_ext in enumerate(xref_exts):
|
||||
xref, ext = xref_ext
|
||||
yield dict(
|
||||
cwd=fspath(root),
|
||||
infile=img_name(root, xref, ext),
|
||||
outfile=root / f'{prefix}.{n:04d}',
|
||||
yield (
|
||||
fspath(root),
|
||||
img_name(root, xref, ext),
|
||||
root / f'{prefix}.{n:04d}',
|
||||
)
|
||||
|
||||
def convert_generic(fn, kwargs_dict):
|
||||
return fn(**kwargs_dict)
|
||||
|
||||
if options.jbig2_page_group_size > 1:
|
||||
jbig2_args = jbig2_group_args
|
||||
jbig2_convert = partial(convert_generic, jbig2enc.convert_group)
|
||||
jbig2_convert = jbig2enc.convert_group_mp
|
||||
else:
|
||||
jbig2_args = jbig2_single_args
|
||||
jbig2_convert = partial(convert_generic, jbig2enc.convert_single)
|
||||
jbig2_convert = jbig2enc.convert_single_mp
|
||||
|
||||
exec_progress_pool(
|
||||
executor(
|
||||
use_threads=True,
|
||||
max_workers=options.jobs,
|
||||
tqdm_kwargs=dict(
|
||||
@@ -349,7 +347,11 @@ def _produce_jbig2_images(
|
||||
|
||||
|
||||
def convert_to_jbig2(
|
||||
pike: Pdf, jbig2_groups: Dict[int, List[XrefExt]], root: Path, options
|
||||
pike: Pdf,
|
||||
jbig2_groups: Dict[int, List[XrefExt]],
|
||||
root: Path,
|
||||
options,
|
||||
executor: Executor,
|
||||
) -> None:
|
||||
"""Convert images to JBIG2 and insert into PDF.
|
||||
|
||||
@@ -364,7 +366,7 @@ def convert_to_jbig2(
|
||||
and needs no dictionary. Currently this must be lossless JBIG2.
|
||||
"""
|
||||
|
||||
_produce_jbig2_images(jbig2_groups, root, options)
|
||||
_produce_jbig2_images(jbig2_groups, root, options, executor)
|
||||
|
||||
for group, xref_exts in jbig2_groups.items():
|
||||
prefix = f'group{group:08d}'
|
||||
@@ -388,27 +390,53 @@ def convert_to_jbig2(
|
||||
)
|
||||
|
||||
|
||||
def transcode_jpegs(pike: Pdf, jpegs: Sequence[Xref], root: Path, options) -> None:
|
||||
for xref in tqdm(
|
||||
jpegs, desc="JPEGs", unit='image', disable=not options.progress_bar
|
||||
):
|
||||
in_jpg = jpg_name(root, xref)
|
||||
opt_jpg = in_jpg.with_suffix('.opt.jpg')
|
||||
def _optimize_jpeg(args):
|
||||
xref, in_jpg, opt_jpg, jpeg_quality = args
|
||||
|
||||
# This produces a debug warning from PIL
|
||||
# DEBUG:PIL.Image:Error closing: 'NoneType' object has no attribute
|
||||
# 'close'. Seems to be mostly harmless
|
||||
# https://github.com/python-pillow/Pillow/issues/1144
|
||||
with Image.open(in_jpg) as im:
|
||||
im.save(opt_jpg, optimize=True, quality=options.jpeg_quality)
|
||||
# This may produce a debug warning from PIL
|
||||
# DEBUG:PIL.Image:Error closing: 'NoneType' object has no attribute
|
||||
# 'close'. Seems to be mostly harmless
|
||||
# https://github.com/python-pillow/Pillow/issues/1144
|
||||
with Image.open(in_jpg) as im:
|
||||
im.save(opt_jpg, optimize=True, quality=jpeg_quality)
|
||||
|
||||
if opt_jpg.stat().st_size > in_jpg.stat().st_size:
|
||||
log.debug("xref %s, jpeg, made larger - skip", xref)
|
||||
continue
|
||||
if opt_jpg.stat().st_size > in_jpg.stat().st_size:
|
||||
log.debug("xref %s, jpeg, made larger - skip", xref)
|
||||
opt_jpg.unlink()
|
||||
opt_jpg = None
|
||||
return xref, opt_jpg
|
||||
|
||||
compdata = leptonica.CompressedData.open(opt_jpg)
|
||||
im_obj = pike.get_object(xref, 0)
|
||||
im_obj.write(compdata.read(), filter=Name.DCTDecode)
|
||||
|
||||
def transcode_jpegs(
|
||||
pike: Pdf, jpegs: Sequence[Xref], root: Path, options, executor
|
||||
) -> None:
|
||||
def jpeg_args():
|
||||
for xref in jpegs:
|
||||
in_jpg = jpg_name(root, xref)
|
||||
opt_jpg = in_jpg.with_suffix('.opt.jpg')
|
||||
yield xref, in_jpg, opt_jpg, options.jpeg_quality
|
||||
|
||||
def finish_jpeg(result, pbar):
|
||||
xref, opt_jpg = result
|
||||
if opt_jpg:
|
||||
compdata = leptonica.CompressedData.open(opt_jpg)
|
||||
im_obj = pike.get_object(xref, 0)
|
||||
im_obj.write(compdata.read(), filter=Name.DCTDecode)
|
||||
pbar.update()
|
||||
|
||||
executor(
|
||||
use_threads=True, # Processes are significantly slower at this task
|
||||
max_workers=options.jobs,
|
||||
tqdm_kwargs=dict(
|
||||
desc="JPEGs",
|
||||
total=len(jpegs),
|
||||
unit='image',
|
||||
disable=not options.progress_bar,
|
||||
),
|
||||
task=_optimize_jpeg,
|
||||
task_arguments=jpeg_args(),
|
||||
task_finished=finish_jpeg,
|
||||
)
|
||||
|
||||
|
||||
def _transcode_png(pike: Pdf, filename: Path, xref: Xref) -> bool:
|
||||
@@ -458,6 +486,7 @@ def transcode_pngs(
|
||||
image_name_fn: Callable[[Path, Xref], Path],
|
||||
root: Path,
|
||||
options,
|
||||
executor,
|
||||
) -> None:
|
||||
modified: MutableSet[Xref] = set()
|
||||
if options.optimize >= 2:
|
||||
@@ -477,10 +506,7 @@ def transcode_pngs(
|
||||
)
|
||||
modified.add(xref)
|
||||
|
||||
def pngquant_fn(args):
|
||||
pngquant.quantize(*args)
|
||||
|
||||
exec_progress_pool(
|
||||
executor(
|
||||
use_threads=True,
|
||||
max_workers=options.jobs,
|
||||
tqdm_kwargs=dict(
|
||||
@@ -489,7 +515,7 @@ def transcode_pngs(
|
||||
unit='image',
|
||||
disable=not options.progress_bar,
|
||||
),
|
||||
task=pngquant_fn,
|
||||
task=pngquant.quantize_mp,
|
||||
task_arguments=pngquant_args(),
|
||||
)
|
||||
|
||||
@@ -498,82 +524,13 @@ def transcode_pngs(
|
||||
_transcode_png(pike, filename, xref)
|
||||
|
||||
|
||||
@deprecated
|
||||
def rewrite_png_as_g4(pike: Pdf, im_obj: Object, compdata) -> None: # pragma: no cover
|
||||
im_obj.BitsPerComponent = 1
|
||||
im_obj.Width = compdata.w
|
||||
im_obj.Height = compdata.h
|
||||
|
||||
im_obj.write(compdata.read())
|
||||
|
||||
log.debug(f"PNG to G4 {im_obj.objgen}")
|
||||
if Name.Predictor in im_obj:
|
||||
del im_obj.Predictor
|
||||
if Name.DecodeParms in im_obj:
|
||||
del im_obj.DecodeParms
|
||||
im_obj.DecodeParms = Dictionary(
|
||||
K=-1, BlackIs1=bool(compdata.minisblack), Columns=compdata.w
|
||||
)
|
||||
|
||||
im_obj.Filter = Name.CCITTFaxDecode
|
||||
return
|
||||
|
||||
|
||||
@deprecated
|
||||
def rewrite_png(pike: Pdf, im_obj: Object, compdata) -> None: # pragma: no cover
|
||||
# When a PNG is inserted into a PDF, we more or less copy the IDAT section from
|
||||
# the PDF and transfer the rest of the PNG headers to PDF image metadata.
|
||||
# One thing we have to do is tell the PDF reader whether a predictor was used
|
||||
# on the image before Flate encoding. (Typically one is.)
|
||||
# According to Leptonica source, PDF readers don't actually need us
|
||||
# to specify the correct predictor, they just need a value of either:
|
||||
# 1 - no predictor
|
||||
# 10-14 - there is a predictor
|
||||
# Leptonica's compdata->predictor only tells TRUE or FALSE
|
||||
# 10-14 means the actual predictor is specified in the data, so for any
|
||||
# number >= 10 the PDF reader will use whatever the PNG data specifies.
|
||||
# In practice Leptonica should use Paeth, 14, but 15 seems to be the
|
||||
# designated value for "optimal". So we will use 15.
|
||||
# See:
|
||||
# - PDF RM 7.4.4.4 Table 10
|
||||
# - https://github.com/DanBloomberg/leptonica/blob/master/src/pdfio2.c#L757
|
||||
predictor = 15 if compdata.predictor > 0 else 1
|
||||
dparms = Dictionary(Predictor=predictor)
|
||||
if predictor > 1:
|
||||
dparms.BitsPerComponent = compdata.bps # Yes, this is redundant
|
||||
dparms.Colors = compdata.spp
|
||||
dparms.Columns = compdata.w
|
||||
|
||||
im_obj.BitsPerComponent = compdata.bps
|
||||
im_obj.Width = compdata.w
|
||||
im_obj.Height = compdata.h
|
||||
|
||||
log.debug(
|
||||
f"PNG {im_obj.objgen}: palette={compdata.ncolors} spp={compdata.spp} bps={compdata.bps}"
|
||||
)
|
||||
if compdata.ncolors > 0:
|
||||
# .ncolors is the number of colors in the palette, not the number of
|
||||
# colors used in a true color image. The palette string is always
|
||||
# given as RGB tuples even when the image is grayscale; see
|
||||
# https://github.com/DanBloomberg/leptonica/blob/master/src/colormap.c#L2067
|
||||
palette_pdf_string = compdata.get_palette_pdf_string()
|
||||
palette_data = pikepdf.Object.parse(palette_pdf_string)
|
||||
palette_stream = pikepdf.Stream(pike, bytes(palette_data))
|
||||
palette = [Name.Indexed, Name.DeviceRGB, compdata.ncolors - 1, palette_stream]
|
||||
cs = palette
|
||||
else:
|
||||
# ncolors == 0 means we are using a colorspace without a palette
|
||||
if compdata.spp == 1:
|
||||
cs = Name.DeviceGray
|
||||
elif compdata.spp == 4:
|
||||
cs = Name.DeviceCMYK
|
||||
else: # spp == 3
|
||||
cs = Name.DeviceRGB
|
||||
im_obj.ColorSpace = cs
|
||||
im_obj.write(compdata.read(), filter=Name.FlateDecode, decode_parms=dparms)
|
||||
|
||||
|
||||
def optimize(input_file: Path, output_file: Path, context, save_settings) -> None:
|
||||
def optimize(
|
||||
input_file: Path,
|
||||
output_file: Path,
|
||||
context,
|
||||
save_settings,
|
||||
executor: Executor = SerialExecutor(),
|
||||
) -> None:
|
||||
options = context.options
|
||||
if options.optimize == 0:
|
||||
safe_symlink(input_file, output_file)
|
||||
@@ -591,14 +548,14 @@ def optimize(input_file: Path, output_file: Path, context, save_settings) -> Non
|
||||
root.mkdir(exist_ok=True)
|
||||
|
||||
jpegs, pngs = extract_images_generic(pike, root, options)
|
||||
transcode_jpegs(pike, jpegs, root, options)
|
||||
transcode_jpegs(pike, jpegs, root, options, executor)
|
||||
# if options.optimize >= 2:
|
||||
# Try pngifying the jpegs
|
||||
# transcode_pngs(pike, jpegs, jpg_name, root, options)
|
||||
transcode_pngs(pike, pngs, png_name, root, options)
|
||||
transcode_pngs(pike, pngs, png_name, root, options, executor)
|
||||
|
||||
jbig2_groups = extract_images_jbig2(pike, root, options)
|
||||
convert_to_jbig2(pike, jbig2_groups, root, options)
|
||||
convert_to_jbig2(pike, jbig2_groups, root, options, executor)
|
||||
|
||||
target_file = output_file.with_suffix('.opt.pdf')
|
||||
pike.remove_unreferenced_resources()
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import atexit
|
||||
import logging
|
||||
import re
|
||||
from collections import defaultdict, namedtuple
|
||||
from contextlib import ExitStack
|
||||
from decimal import Decimal
|
||||
from enum import Enum
|
||||
from functools import partial
|
||||
from math import hypot, isclose
|
||||
from math import hypot, inf, isclose
|
||||
from os import PathLike
|
||||
from pathlib import Path
|
||||
from typing import Container, Iterator, Optional, Tuple, Union
|
||||
@@ -21,7 +23,7 @@ from warnings import warn
|
||||
import pikepdf
|
||||
from pikepdf import Object, Pdf, PdfMatrix
|
||||
|
||||
from ocrmypdf._concurrent import exec_progress_pool
|
||||
from ocrmypdf._concurrent import Executor, SerialExecutor
|
||||
from ocrmypdf.exceptions import EncryptedPdfError, InputFileError
|
||||
from ocrmypdf.helpers import Resolution, available_cpu_count, pikepdf_enable_mmap
|
||||
from ocrmypdf.pdfinfo.layout import get_page_analysis, get_text_boxes
|
||||
@@ -254,17 +256,15 @@ def _get_dpi(ctm_shorthand, image_size) -> Resolution:
|
||||
a, b, c, d, _, _ = ctm_shorthand
|
||||
|
||||
# Calculate the width and height of the image in PDF units
|
||||
image_drawn_width = hypot(a, b)
|
||||
image_drawn_height = hypot(c, d)
|
||||
image_drawn = hypot(a, b), hypot(c, d)
|
||||
|
||||
# The scale of the image is pixels per unit of default user space (1/72")
|
||||
scale_w = image_size[0] / image_drawn_width
|
||||
scale_h = image_size[1] / image_drawn_height
|
||||
|
||||
# DPI = scale * 72
|
||||
dpi_w = scale_w * 72.0
|
||||
dpi_h = scale_h * 72.0
|
||||
def calc(drawn, pixels, inches_per_pt=72.0):
|
||||
# The scale of the image is pixels per unit of default user space (1/72")
|
||||
scale = pixels / drawn if drawn != 0 else inf
|
||||
dpi = scale * inches_per_pt
|
||||
return dpi
|
||||
|
||||
dpi_w, dpi_h = (calc(image_drawn[n], image_size[n]) for n in range(2))
|
||||
return Resolution(dpi_w, dpi_h)
|
||||
|
||||
|
||||
@@ -363,6 +363,10 @@ class ImageInfo:
|
||||
def enc(self):
|
||||
return self._enc
|
||||
|
||||
@property
|
||||
def renderable(self):
|
||||
return self.dpi.is_finite and self.width >= 0 and self.height >= 0
|
||||
|
||||
@property
|
||||
def dpi(self):
|
||||
return _get_dpi(self._shorthand, (self._width, self._height))
|
||||
@@ -571,29 +575,42 @@ def simplify_textboxes(miner, textbox_getter) -> Iterator[TextboxInfo]:
|
||||
worker_pdf = None
|
||||
|
||||
|
||||
def _pdf_pageinfo_sync_init(infile: Path, pdfminer_loglevel):
|
||||
def _pdf_pageinfo_sync_init(pdf: Pdf, infile: Path, pdfminer_loglevel):
|
||||
global worker_pdf # pylint: disable=global-statement
|
||||
pikepdf_enable_mmap()
|
||||
|
||||
logging.getLogger('pdfminer').setLevel(pdfminer_loglevel)
|
||||
|
||||
# If this function is called as a thread initializer, we need a messy hack
|
||||
# to close worker_pdf. If called as a process, it will be released when the
|
||||
# process is terminated.
|
||||
worker_pdf = pikepdf.open(infile)
|
||||
# If the pdf is not opened, open a copy for our worker process to use
|
||||
if pdf is None:
|
||||
worker_pdf = pikepdf.open(infile)
|
||||
|
||||
def on_process_close():
|
||||
worker_pdf.close()
|
||||
|
||||
# Close when this process exits
|
||||
atexit.register(on_process_close)
|
||||
|
||||
|
||||
def _pdf_pageinfo_sync(args):
|
||||
global worker_pdf # pylint: disable=global-statement
|
||||
pageno, infile, check_pages, detailed_analysis = args
|
||||
page = PageInfo(worker_pdf, pageno, infile, check_pages, detailed_analysis)
|
||||
return page
|
||||
pageno, thread_pdf, infile, check_pages, detailed_analysis = args
|
||||
pdf = thread_pdf if thread_pdf is not None else worker_pdf
|
||||
with ExitStack() as stack:
|
||||
if not pdf: # When called with SerialExecutor
|
||||
pdf = stack.enter_context(pikepdf.open(infile))
|
||||
page = PageInfo(pdf, pageno, infile, check_pages, detailed_analysis)
|
||||
return page
|
||||
|
||||
|
||||
def _pdf_pageinfo_concurrent(
|
||||
pdf, infile, progbar, max_workers, check_pages, detailed_analysis=False
|
||||
pdf,
|
||||
executor: Executor,
|
||||
infile,
|
||||
progbar,
|
||||
max_workers,
|
||||
check_pages,
|
||||
detailed_analysis=False,
|
||||
):
|
||||
global worker_pdf # pylint: disable=global-statement
|
||||
pages = [None] * len(pdf.pages)
|
||||
|
||||
def update_pageinfo(result, pbar):
|
||||
@@ -607,7 +624,6 @@ def _pdf_pageinfo_concurrent(
|
||||
max_workers = available_cpu_count()
|
||||
|
||||
total = len(pdf.pages)
|
||||
contexts = ((n, infile, check_pages, detailed_analysis) for n in range(total))
|
||||
|
||||
use_threads = False # No performance gain if threaded due to GIL
|
||||
n_workers = min(1 + len(pages) // 4, max_workers)
|
||||
@@ -616,25 +632,31 @@ def _pdf_pageinfo_concurrent(
|
||||
# a separate process.
|
||||
use_threads = True
|
||||
|
||||
try:
|
||||
exec_progress_pool(
|
||||
use_threads=use_threads,
|
||||
max_workers=n_workers,
|
||||
tqdm_kwargs=dict(
|
||||
total=total, desc="Scanning contents", unit='page', disable=not progbar
|
||||
),
|
||||
task_initializer=partial(
|
||||
_pdf_pageinfo_sync_init, infile, logging.getLogger('pdfminer').level
|
||||
),
|
||||
task=_pdf_pageinfo_sync,
|
||||
task_arguments=contexts,
|
||||
task_finished=update_pageinfo,
|
||||
)
|
||||
finally:
|
||||
if worker_pdf and use_threads:
|
||||
assert n_workers == 1, "Should have only one worker when threaded"
|
||||
# This is messy, but if we ran in thread, close worker_pdf
|
||||
worker_pdf.close()
|
||||
# If we use a thread, we can pass the already-open Pdf for them to use
|
||||
# If we use processes, we pass a None which tells the init function to open its
|
||||
# own
|
||||
initial_pdf = pdf if use_threads else None
|
||||
|
||||
contexts = (
|
||||
(n, initial_pdf, infile, check_pages, detailed_analysis) for n in range(total)
|
||||
)
|
||||
assert n_workers == 1 if use_threads else n_workers >= 1, "Not multithreadable"
|
||||
executor(
|
||||
use_threads=use_threads,
|
||||
max_workers=n_workers,
|
||||
tqdm_kwargs=dict(
|
||||
total=total, desc="Scanning contents", unit='page', disable=not progbar
|
||||
),
|
||||
worker_initializer=partial(
|
||||
_pdf_pageinfo_sync_init,
|
||||
initial_pdf,
|
||||
infile,
|
||||
logging.getLogger('pdfminer').level,
|
||||
),
|
||||
task=_pdf_pageinfo_sync,
|
||||
task_arguments=contexts,
|
||||
task_finished=update_pageinfo,
|
||||
)
|
||||
return pages
|
||||
|
||||
|
||||
@@ -714,7 +736,9 @@ class PageInfo:
|
||||
|
||||
self._dpi = None
|
||||
if self._images:
|
||||
dpi = Resolution(0.0, 0.0).take_max(image.dpi for image in self._images)
|
||||
dpi = Resolution(0.0, 0.0).take_max(
|
||||
image.dpi for image in self._images if image.renderable
|
||||
)
|
||||
self._dpi = dpi
|
||||
self._width_pixels = int(round(dpi.x * float(self._width_inches)))
|
||||
self._height_pixels = int(round(dpi.y * float(self._height_inches)))
|
||||
@@ -819,10 +843,12 @@ class PdfInfo:
|
||||
def __init__(
|
||||
self,
|
||||
infile,
|
||||
*,
|
||||
detailed_analysis: bool = False,
|
||||
progbar: bool = False,
|
||||
max_workers: int = None,
|
||||
check_pages=None,
|
||||
executor: Executor = SerialExecutor(),
|
||||
):
|
||||
self._infile = infile
|
||||
if check_pages is None:
|
||||
@@ -833,6 +859,7 @@ class PdfInfo:
|
||||
raise EncryptedPdfError() # Triggered by encryption with empty passwd
|
||||
self._pages = _pdf_pageinfo_concurrent(
|
||||
pdf,
|
||||
executor,
|
||||
infile,
|
||||
progbar,
|
||||
max_workers,
|
||||
|
||||
+127
-5
@@ -8,24 +8,41 @@
|
||||
from abc import ABC, abstractmethod, abstractstaticmethod
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from collections import namedtuple
|
||||
from logging import Handler
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, AbstractSet, List, Optional
|
||||
|
||||
import pluggy
|
||||
|
||||
from ocrmypdf._concurrent import Executor
|
||||
from ocrmypdf.helpers import Resolution
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from PIL import Image
|
||||
|
||||
# pylint: disable=ungrouped-imports
|
||||
from ocrmypdf._jobcontext import PageContext
|
||||
from ocrmypdf.pdfinfo import PdfInfo
|
||||
|
||||
# pylint: enable=ungrouped-imports
|
||||
|
||||
hookspec = pluggy.HookspecMarker('ocrmypdf')
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def get_logging_console() -> Handler:
|
||||
"""Returns a custom logging handler.
|
||||
|
||||
Generally this is necessary when both logging output and a progress bar are both
|
||||
outputting to ``sys.stderr``.
|
||||
|
||||
Note:
|
||||
This is a :ref:`firstresult hook<firstresult>`.
|
||||
"""
|
||||
|
||||
|
||||
@hookspec
|
||||
def add_options(parser: ArgumentParser) -> None:
|
||||
"""Allows the plugin to add its own command line and API arguments.
|
||||
@@ -62,6 +79,67 @@ def check_options(options: Namespace) -> None:
|
||||
"""
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def get_executor(progressbar_class) -> Executor:
|
||||
"""Called to obtain an object that manages parallel execution.
|
||||
|
||||
This may be used to replace OCRmyPDF's default parallel execution system
|
||||
with a third party alternative. For example, you could make OCRmyPDF run in a
|
||||
distributed environment.
|
||||
|
||||
OCRmyPDF's executors are analogous to the standard Python executors in
|
||||
``conconcurrent.futures``, but they do not work the same way. Executors may
|
||||
be reused for different, unrelated batch operations, since all of the context
|
||||
for a given job are passed to :meth:`Executor.__call__`.
|
||||
|
||||
Should be of type :class:`Executor` or otherwise conforming to the protocol
|
||||
of that call.
|
||||
|
||||
Arguments:
|
||||
progressbar_class: A progress bar class, which will be created when
|
||||
|
||||
Note:
|
||||
This hook will be called from the main process, and may modify global state
|
||||
before child worker processes are forked.
|
||||
Note:
|
||||
This is a :ref:`firstresult hook<firstresult>`.
|
||||
"""
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def get_progressbar_class():
|
||||
"""Called to obtain a class that can be used to monitor progress.
|
||||
|
||||
A progress bar is assumed, but this could be used for any type of monitoring.
|
||||
|
||||
The class should follow a tqdm-like protocol. Calling the class should return
|
||||
a new progress bar object, which is activated with ``__enter__`` and terminated
|
||||
``__exit__``. An update method is called whenever the progress bar is updated.
|
||||
Progress bar objects will not be reused; a new one will be created for each
|
||||
group of tasks.
|
||||
|
||||
The progress bar is held in the main process/thread and not updated by child
|
||||
process/threads. When a child notifies the parent of completed work, the
|
||||
parent updates the progress bar.
|
||||
|
||||
The arguments are the same as `tqdm <https://github.com/tqdm/tqdm>`_ accepts.
|
||||
|
||||
Progress bars should never write to ``sys.stdout``, or they will corrupt the
|
||||
output if OCRmyPDF writes a PDF to standard output.
|
||||
|
||||
The type of events that OCRmyPDF reports to a progress bar may change in
|
||||
minor releases.
|
||||
|
||||
Here is how OCRmyPDF will use the progress bar:
|
||||
|
||||
Example:
|
||||
pbar_class = pm.hook.get_progressbar_class()
|
||||
with pbar_class(**tqdm_kwargs) as pbar:
|
||||
...
|
||||
pbar.update(1)
|
||||
"""
|
||||
|
||||
|
||||
@hookspec
|
||||
def validate(pdfinfo: 'PdfInfo', options: Namespace) -> None:
|
||||
"""Called to give a plugin an opportunity to review *options* and *pdfinfo*.
|
||||
@@ -163,11 +241,11 @@ def filter_page_image(page: 'PageContext', image_filename: Path) -> Path:
|
||||
will be resized and the OCR layer misaligned. OCRmyPDF does not nothing
|
||||
to enforce these constraints; it is up to the plugin to do sensible things.
|
||||
|
||||
OCRmyPDF will create the PDF page based on the image format used. If you
|
||||
convert the image to a JPEG, the output page will be created as a JPEG, etc.
|
||||
If you change the colorspace, that change will be kept. Note that the
|
||||
OCRmyPDF image optimization stage, if enabled, may ultimately chose a
|
||||
different format.
|
||||
OCRmyPDF will create the PDF page based on the image format used (unless the
|
||||
hook is overriden). If you convert the image to a JPEG, the output page will
|
||||
be created as a JPEG, etc. If you change the colorspace, that change will be
|
||||
kept. Note that the OCRmyPDF image optimization stage, if enabled, may
|
||||
ultimately chose a different format.
|
||||
|
||||
If the return value is a file that does not exist, ``FileNotFoundError``
|
||||
will occur. The return value should be a path to a file in the same folder
|
||||
@@ -185,6 +263,50 @@ def filter_page_image(page: 'PageContext', image_filename: Path) -> Path:
|
||||
"""
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def filter_pdf_page(
|
||||
page: 'PageContext', image_filename: Path, output_pdf: Path
|
||||
) -> Path:
|
||||
"""Called to convert a filtered whole page image into a PDF.
|
||||
|
||||
A whole page image is only produced when preprocessing command line arguments
|
||||
are issued or when ``--force-ocr`` is issued. If no whole page is image is
|
||||
produced for a given page, this function will not be called. This is not
|
||||
the image that will be shown to OCR. The whole page image is filtered in
|
||||
the hook above, ``filter_page_image``, then this function is called for
|
||||
PDF conversion.
|
||||
|
||||
This function will only be called when OCRmyPDF runs in a mode such as
|
||||
"force OCR" mode where rasterizing of all content is performed.
|
||||
|
||||
Clever things could be done at this stage such as segmenting the page image into
|
||||
color regions or vector equivalents.
|
||||
|
||||
The provider of the hook implementation is responsible for ensuring that the
|
||||
OCR text layer is aligned with the PDF produced here, or text misalignment
|
||||
will result.
|
||||
|
||||
Currently this function must produce a single page PDF or the pipeline will
|
||||
fail. If the intent is to remove the PDF, then create a single page empty
|
||||
PDF.
|
||||
|
||||
Args:
|
||||
page: Context for this page.
|
||||
image_filename: Filename of the input image used to create output_pdf,
|
||||
for "reference" if recreating the output_pdf entirely.
|
||||
output_pdf: The previous created output_pdf.
|
||||
|
||||
Returns:
|
||||
output_pdf
|
||||
|
||||
Note:
|
||||
This hook will be called from child processes. Modifying global state
|
||||
will not affect the main process or other child processes.
|
||||
Note:
|
||||
This is a :ref:`firstresult hook<firstresult>`.
|
||||
"""
|
||||
|
||||
|
||||
OrientationConfidence = namedtuple('OrientationConfidence', ('angle', 'confidence'))
|
||||
"""Expresses an OCR engine's confidence in page rotation.
|
||||
|
||||
|
||||
@@ -13,14 +13,17 @@ import re
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
from contextlib import suppress
|
||||
from distutils.version import LooseVersion
|
||||
from distutils.version import LooseVersion, Version
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, STDOUT, CalledProcessError, CompletedProcess, Popen
|
||||
from subprocess import run as subprocess_run
|
||||
from typing import Callable, Optional, Type, Union
|
||||
|
||||
from ocrmypdf.exceptions import MissingDependencyError
|
||||
|
||||
# pylint: disable=logging-format-interpolation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -264,13 +267,30 @@ def _error_old_version(program, package, need_version, found_version, required_f
|
||||
|
||||
def check_external_program(
|
||||
*,
|
||||
program,
|
||||
package,
|
||||
version_checker,
|
||||
need_version,
|
||||
required_for=None,
|
||||
program: str,
|
||||
package: str,
|
||||
version_checker: Union[str, Callable],
|
||||
need_version: str,
|
||||
required_for: Optional[str] = None,
|
||||
recommended=False,
|
||||
version_parser: Type[Version] = LooseVersion,
|
||||
):
|
||||
"""Check for required version of external program and raise exception if not.
|
||||
|
||||
Args:
|
||||
program: The name of the program to test.
|
||||
package: The name of a software package that typically supplies this program.
|
||||
Usually the same as program.
|
||||
version_check: A callable without arguments that retrieves the installed
|
||||
version of program.
|
||||
need_version: The minimum required version.
|
||||
required_for: The name of an argument of feature that requires this program.
|
||||
recommended: If this external program is recommended, instead of raising
|
||||
an exception, log a warning and allow execution to continue.
|
||||
version_parser: A class that should be used to parse and compare version
|
||||
numbers. Used when version numbers do not follow standard conventions.
|
||||
"""
|
||||
|
||||
try:
|
||||
if callable(version_checker):
|
||||
found_version = version_checker()
|
||||
@@ -279,7 +299,7 @@ def check_external_program(
|
||||
except (CalledProcessError, FileNotFoundError, MissingDependencyError):
|
||||
_error_missing_program(program, package, required_for, recommended)
|
||||
if not recommended:
|
||||
raise MissingDependencyError()
|
||||
raise MissingDependencyError(program)
|
||||
return
|
||||
|
||||
def remove_leading_v(s):
|
||||
@@ -290,9 +310,9 @@ def check_external_program(
|
||||
found_version = remove_leading_v(found_version)
|
||||
need_version = remove_leading_v(need_version)
|
||||
|
||||
if found_version and LooseVersion(found_version) < LooseVersion(need_version):
|
||||
if found_version and version_parser(found_version) < version_parser(need_version):
|
||||
_error_old_version(program, package, need_version, found_version, required_for)
|
||||
if not recommended:
|
||||
raise MissingDependencyError()
|
||||
raise MissingDependencyError(program)
|
||||
|
||||
log.debug('Found %s %s', program, found_version)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# © 2021 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Empty __init__.py file
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.mrqsewbu/000001_ocr.png"; bbox 0 0 1000 800; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.h7hsz1g7/000001_ocr.png"; bbox 0 0 1000 800; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 296 96 704 504">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 296 96 704 504">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 296 96 704 504; baseline 0 296; x_size 169.33333; x_descenders 42.333332; x_ascenders 42.333336">
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.ces85e5u/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.tgp04npj/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 582 131 1968 303">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 582 131 1968 303">
|
||||
<span class='ocr_header' id='line_1_1' title="bbox 882 131 1657 217; baseline 0.001 -17; x_size 85; x_descenders 16; x_ascenders 19">
|
||||
|
||||
BIN
Binary file not shown.
+888
-888
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -103,7 +103,7 @@ ERASE, REPEAT, PLAY/STOP, or LOCATE.
|
||||
|
||||
© Will sync to standard LinnDrum or Linn 9000 sync tone.
|
||||
|
||||
® Utilizes ultra high-speed, 8 MHz 80186 16 bit computer internally for FAST operation.
|
||||
© Utilizes ultra high-speed, 8 MHz 80186 16 bit computer internally for FAST operation.
|
||||
* TEMPO may be specified in BEATS-PER-MINUTE or FRAMES-PER-BEAT at 24, 25, or 30 frames per second,
|
||||
|
||||
(even drop frame!)
|
||||
@@ -115,9 +115,9 @@ on the TAP TEMPO button.
|
||||
¢ TEMPO CHANGES may be programmed into a sequence, with smooth transitions if desired.
|
||||
¢ Any TIME SIGNATURE may be used, and may be changed within a song.
|
||||
|
||||
nn
|
||||
|
||||
linn
|
||||
Linn Electronics, Inc.
|
||||
|
||||
18720 Oxnard Street, Tarzana, CA 91356
|
||||
(818) 708-8131 TELEX #298949 LINN UR
|
||||
|
||||
BIN
Binary file not shown.
+977
-1007
File diff suppressed because it is too large
Load Diff
+82
-87
@@ -1,128 +1,123 @@
|
||||
2A NNI‘I 6F6867# XATALL IE18-80L (818)
|
||||
The LinnSequencer
|
||||
32 Track MIDI Sequence Recorder
|
||||
|
||||
9SEI6 VO “BUBZIRY, “J0aNS PIPUXO OZLEI
|
||||
“Uy ‘soTUOMOI,q UUrT
|
||||
The LinnSequencer is a state-of-the-art composition and performance tool for the professional musician. It is
|
||||
|
||||
uut]
|
||||
extremely powerful, yet amazingly simple to learn and use. It’s many remarkable features include:
|
||||
|
||||
“‘SUOS B UIJIM pasueyo oq ABU pue ‘posn oq AWW AYN IVNOIS AWLL AUV
|
||||
“parlsop Jr SUOTIISUBI} YIOOUIS YIM “BoueNbas eB OJUI pourtueIZOId 9q ABU SFONWHO OdINAL e
|
||||
¢ Operation is similar to multi-track tape recorder with PLAY, STOP, RECORD, FAST
|
||||
FORWARD, REWIND, and LOCATE controls.
|
||||
|
||||
‘uonng OdNAL dV L 9) uO
|
||||
e Each of the 100 sequences contains 32 simultaneous, polyphonic tracks. Each track may
|
||||
be assigned to one of 16 MIDI channels. Simultaneously plays up to 16 polyphonic
|
||||
|
||||
sojou Jayienb Suiddy} Aq 10 ‘syUSTIOIOUI oINUTIAI-J8g-Jesg & JO sys} UL ofquisn(pe ‘ATTeouIAUINU paiajus oq ABU OdINALL e
|
||||
synthesizers!
|
||||
|
||||
(jouer doup u3a9)
|
||||
¢ Ultra-fast 3%” disk drive stores complex songs in seconds and holds over 110,000 notes
|
||||
|
||||
“puooes Jed souely O€ 10 “SZ “pz 18 [LVAG-MAd-SHN VU 10 ALOANIWAAd-SLVAd U! patyoeds aq kewl OAL «
|
||||
‘uoTe1odo [SVx JO} Aj[eusoyUT JoyndUIOd 11g 9] 98108 ZHI 8g ‘poeds-ysry Bann soz] e
|
||||
per disk!
|
||||
|
||||
"9U0} DUAS 0006 UUL] Jo wNIqUUr] prepue}s 0} OUAS [ITAA ©
|
||||
¢ One or all tracks may be TRANSPOSED at the touch of a key.
|
||||
e Exclusive real-time ERASE function makes editing FAST.
|
||||
* Exclusive REPEAT function automatically repeats any held notes at a pre-selected
|
||||
|
||||
“ONYBA 9}OU poloapes Aue Je sas—nd jndyno 07 pewureigold 3q ACW SL Ad LNO YADONAL OML
|
||||
rhythmic value.
|
||||
|
||||
"ALVOOT 10 GOLS/AV 1d ‘LWddad “ASV
|
||||
¢ TIMING CORRECTION works during playback and operates without ‘chopping’ notes.
|
||||
|
||||
SUIpNpoUr ‘suOTIOUN] posn A[UOUILUOS 94] JO AUBUT [O1]UOD AJ9]OWIAI 0} PousIsse oq ACUI ST AdNI HOLIMSLOO OME «
|
||||
“SUIPIONAI I[IYM P2sesd JOU Iv $3}OU BUTISIXO—ZUIPIOIA SATON.ASOP-UON
|
||||
¢ Optional SMPTE time code synchronization.
|
||||
|
||||
‘suoneurldxa peuoyippe sdeydsip uowng g1TqH
|
||||
© Optional remote control.
|
||||
|
||||
oy] ‘pepsau JI ‘suoneiodo [ye yYsnosy] NOA sapins ApIespo Avfdsip QO] Joey Z7¢ 9y3—uoeIodo Urea] 0} Ased ‘aus «
|
||||
Recording a Sequence
|
||||
|
||||
jUorel]suowtap & IO} Aepol Jayeap uur’] INOA dag ‘dISHUL
|
||||
INOA 0} UONUS}]¥ PaplAIPUN INOA SUTJOASp ITY ps pue
|
||||
p1osai ‘asoduod no Jay 0} pausisap st 1s0uenbesuur’] oy)
|
||||
Aum Aposiooid $,Jeu], ‘SS9d0Id SATTBS1D OY} YIM SOIOJIOIUT
|
||||
yey) xo]dwWI0d Os dq JOA9U P[NoUsS osn NOA AZopOuYdE} oy
|
||||
To record a sequence, simply press RECORD and PLAY,
|
||||
then play your MIDI keyboard in time to the Sequencer’s
|
||||
click track. When the sequence loops back around to bar 1,
|
||||
you’ ll hear what you played—only all timing errors will be
|
||||
|
||||
ISTUMOIAUIO?) NOAA UOHISOdWIO)
|
||||
corrected! (Timing correction may be adjusted or defeated).
|
||||
|
||||
"NOSpr] B Oy ‘AONUTJUT yada 0} seq Maz Se] BY] Jas UdAd
|
||||
uvd NOA ‘palisap JJ ‘souanbes Mou ¥B OVUT sjied ou] [Te Adoo
|
||||
ATesrewO Ne WI) [IM ONOS ALVAAO JeyIe80} wey}
|
||||
,deyd,, 0} UOTOUNJ ONOS ALVA ou] asn usy] ‘saouanbes
|
||||
JENPIAIpUt UI (“949 ‘snJOYD ‘aS1OA) UOTIDIS JIseq Yes
|
||||
Pl0da1 OF ST ABM JOuIOUY “(812g 666 01 dn) ysnory) ABM
|
||||
Any additional notes played will be added into the track
|
||||
— existing notes are not erased while recording!
|
||||
|
||||
dU} [fe YORI] YORs p10991 0} ST SUOS B 9789I9 0} ABM SUG,
|
||||
FAST FORWARD, REWIND, and LOCATE controls
|
||||
may be used at any time to quickly access any location in
|
||||
your sequence for spot-recording. To overdub a new part,
|
||||
select a different track and start recording—while you
|
||||
record, the first track will play in perfect sync (unless you
|
||||
MUTE it, or SOLO another track). In this way, up to 32
|
||||
tracks may be overdubbed! All MIDI effects are recorded
|
||||
including pitch bend, modulation, velocity, aftertouch,
|
||||
sustain pedal, and program changes!
|
||||
|
||||
SUOS & SUTVAID
|
||||
Editing
|
||||
|
||||
*suoT}oes poJUBMUN
|
||||
To erase a wrong note, simply hold ERASE and press
|
||||
the note to be erased just before it plays in the sequence—
|
||||
when played back, it will be gone. Notes may also be
|
||||
|
||||
SAOUIOI 0} ABM SWS dU} SoyeIodo SUV ALATAaG
|
||||
added, erased, or changed using the SINGLE STEP func-
|
||||
tion. To overdub notes at specific points within a sequence,
|
||||
|
||||
“OBPLIq dy} PUB SNIOY PUOdAS dT]] Ud9MIAQ SIDA ISI
|
||||
Additional Features
|
||||
|
||||
ay) Jo Adoo B JJasuT WYSE NOAA ‘afdwexs 10.f ‘UO JUSIN]JIP
|
||||
simply use LOCATE, FAST FORWARD, or REWIND to
|
||||
find the desired bar number, then start recording.
|
||||
|
||||
B IO aouaNbas sues OY} UI—JOY OUP 0} UOTIEIO] 9UO WOT]
|
||||
$1Bq JAOUI OF NOA sMOTIe WOTIOUNS AdOO/IMASNI OULL
|
||||
The INSERT/COPY function allows you to move bars
|
||||
from one location to another—in the same sequence or a
|
||||
different one. For example, you might insert a copy of the
|
||||
first verse between the second chorus and the bridge.
|
||||
DELETE BARS operates the same way to remove
|
||||
unwanted sections,
|
||||
|
||||
‘SUIPIONAI JIVIS Udy) “OQuINU eq porisop ay} puy
|
||||
Creating a Song
|
||||
|
||||
0} CNIMAY 10 ‘CYVM Od LSWA “AEVOOT esn Apduns
|
||||
One way to create a song is to record each track all the
|
||||
way through (up to 999 bars). Another way is to record
|
||||
each basic section (verse, chorus, etc.) in individual
|
||||
sequences, then use the CREATE SONG function to “chain”
|
||||
them together. CREATE SONG will then automatically
|
||||
copy all the parts into a new sequence. If desired, you can
|
||||
even set the last few bars to repeat infinitely, for a fadeout.
|
||||
|
||||
sainjeay [PUOHIPPY
|
||||
Composition Without Compromise
|
||||
|
||||
‘gouanbas & UTYIIM s]UTOd a1y1dads 3¥ $9100 QnPIOAO OL "UOT}
|
||||
-ouns dALLS ATONIS 24) Suisn pasueyo Jo ‘pasesa ‘pappe
|
||||
aq osye ABUT S9]ON ‘U0 9q ]IIM 1 “yoeq podeyd uayM
|
||||
—aouanbas oy] ul skeyd 71 a10J9q Isnf posers oq 0} d]0U ayy
|
||||
ssaid pue ASvwug ploy Aydunis ‘jou Suomm & aseso OL
|
||||
The technology you use should never be so complex that
|
||||
it interferes with the creative process. That’s precisely why
|
||||
the LinnSequencer is designed to let you compose, record
|
||||
and edit while devoting your undivided attention to your
|
||||
music. See your Linn dealer today for a demonstration!
|
||||
|
||||
sunipa
|
||||
* Simple, easy to learn operation—the 32 character LCD display clearly guides you through all operations. If needed, the
|
||||
|
||||
jsesdueyo ureisoid pue ‘fepod ureysns
|
||||
‘yonoplalje ‘AWOOTOA ‘UOTyeTNpow ‘pusg youd Surpnyour
|
||||
pep10del are $199JJ2 TCTIN [WV iPeqqnpseao aq Aeur syoen
|
||||
Ze 07 dn ‘Kem sie Uy *(foeI} JOyOUR OJOS 10 ALLAN
|
||||
NOA ssofum) duAS yOaysod ul Avy [[IM Yow] ISI 93 “prooar
|
||||
NOA 3[IYM—SUIPIOIA LIBIS PU YORI) TUdIOTJIP B JOaTas
|
||||
*y1ed MOU B QNPIsA0 OL, “SuIps0daJ-jods 10} aouanbes mno0k
|
||||
UI UOHBIO] Aue ssad0e ATYOIND 0} owt} Aue ye pasn aq AvUE
|
||||
SJONUOD FLIVOOT pur ‘ANIMA ‘CYVMaYOd LSVd
|
||||
{SUIPIOSAI {IY posesa JOU se So]OU SuTsTXO—
|
||||
yous} 3U} OUT poppe aq JIM poteyd sajou yeuonippe Auy
|
||||
HELP button displays additional explanations.
|
||||
|
||||
*(povesjap 10 poysn{pe oq ABW UOTIIII0D BUTUTT]) j{paqoeLI09
|
||||
* Non-destructive recording—existing notes are not erased while recording.
|
||||
¢ Two FOOTSWITCH INPUTS may be assigned to remotely control many of the commonly used functions, including
|
||||
|
||||
2q ][IM S1OLIe Sur [fe ATUO—patey]d nod Jey Jedy ]],NOA
|
||||
ERASE, REPEAT, PLAY/STOP, or LOCATE.
|
||||
|
||||
‘] req 0] punose yoeq sdoo] sduanbas ay] Udy AA “YOu Yor
|
||||
¢ Iwo TRIGGER OUTPUTS may be programmed to output pulses at any selected note value.
|
||||
|
||||
§,sa0uaNbas at} O] SUIT) UI preogday [IW] INO Avy usy3
|
||||
AV'1d pue (YOON ssoid Ayduus ‘aousnbes & p1o09es OF,
|
||||
© Will sync to standard LinnDrum or Linn 9000 sync tone.
|
||||
|
||||
g0uaNbas & SUIP10I0y]
|
||||
© Utilizes ultra high-speed, 8 MHz 80186 16 bit computer internally for FAST operation.
|
||||
* TEMPO may be specified in BEATS-PER-MINUTE or FRAMES-PER-BEAT at 24, 25, or 30 frames per second,
|
||||
|
||||
‘JONWOD s}JouNaI TeuONdGO e
|
||||
(even drop frame!)
|
||||
|
||||
"UOTJEZIUOIYUAS OPOS UIT} FLAWS [euondo e
|
||||
¢ TEMPO may be entered numerically, adjustable in tenths of a Beat-Per-Minute increments, or by tapping quarter notes
|
||||
|
||||
‘sou .sulddoys, noyyM sayelodo pue yoegdvyd ZuLINp S¥IOM NOLLOANNYOO ONIWILL e
|
||||
on the TAP TEMPO button.
|
||||
|
||||
‘onqea ory AY
|
||||
¢ TEMPO CHANGES may be programmed into a sequence, with smooth transitions if desired.
|
||||
¢ Any TIME SIGNATURE may be used, and may be changed within a song.
|
||||
|
||||
pojoojes-oid & ye sajou pyoy Aue syeadas ATTeONewWO Ne UOTOUNS [WAdAY OAISNOX e
|
||||
‘LSVJ SUnIpS soyeu UOTOUN ASV UA OUlN-[eal SAISNIOXY e
|
||||
‘Koy B JO YONO} 941 12 CASOdSNVALL 0g ABU Syde] [Te 10 9UC e
|
||||
linn
|
||||
Linn Electronics, Inc.
|
||||
|
||||
i ASIP Jed
|
||||
|
||||
S9}0U OOO‘OTT JOA SpfOy puv SpUOdeS UT SBUOS Xa[AUIOD So10}S DALIP YSIP , 74 € ISCJ-CNIN
|
||||
|
||||
jSIOZISOUJUAS
|
||||
|
||||
stuoydAjod of 0} dn skeyd A[snoourynuls ‘spouueYd [IW 9T JO duo 0} pousisse oq
|
||||
ABUL YORI] YOR ‘syous) oruoydAjod ‘snoouelnurs 7¢ SuTeJUOS ssouUaNbas QO] OY} JO YORA e
|
||||
|
||||
‘SJONUOS ATWOOT pur ‘GNIMAY ‘GaVM OA
|
||||
LSVd ‘GYOOde AOLS ‘AV Td YIM Jopsocas ade} Yowsj-N[NU O} eps st UOTLISdO @
|
||||
LOPNOUT SaINjeoy s[quyIeUlss AUB S.JJ ‘OSN pue UIes] 0} o[duns A[suIzeUe JOA ‘PnJsomod APOUIOITXO
|
||||
St 1] “UeIOIsNUL feUOIssajoid oY} 10 JOO} soUBULIOJIJAd pue UOTIsOduIOS 11e-dY1-JO-9}e)s B SI IONUANbDaguUT] ay
|
||||
|
||||
JOps1odady soUINbIS [GTI YVAL ZE
|
||||
Jgouanbaguury oy
|
||||
18720 Oxnard Street, Tarzana, CA 91356
|
||||
(818) 708-8131 TELEX #298949 LINN UR
|
||||
|
||||
BIN
Binary file not shown.
+979
-995
File diff suppressed because it is too large
Load Diff
+82
-83
@@ -1,124 +1,123 @@
|
||||
2A NNI‘I 6F6867# XATALL IE18-80L (818)
|
||||
The LinnSequencer
|
||||
32 Track MIDI Sequence Recorder
|
||||
|
||||
9SEI6 VO “BUBZIRY, “J0aNS PIPUXO OZLEI
|
||||
“Uy ‘soTUOMOI,q UUrT
|
||||
The LinnSequencer is a state-of-the-art composition and performance tool for the professional musician. It is
|
||||
|
||||
uu
|
||||
extremely powerful, yet amazingly simple to learn and use. It’s many remarkable features include:
|
||||
|
||||
“‘SUOS B UIJIM pasueyo oq ABU pue ‘posn oq AWW AYN IVNOIS AWLL AUV
|
||||
“parlsop Jr SUOTIISUBI} YIOOUIS YIM “BoueNbas eB OJUI pourtueIZOId 9q ABU SFONWHO OdINAL e
|
||||
¢ Operation is similar to multi-track tape recorder with PLAY, STOP, RECORD, FAST
|
||||
FORWARD, REWIND, and LOCATE controls.
|
||||
|
||||
‘uonng OdNAL dV L 9) uO
|
||||
e Each of the 100 sequences contains 32 simultaneous, polyphonic tracks. Each track may
|
||||
be assigned to one of 16 MIDI channels. Simultaneously plays up to 16 polyphonic
|
||||
|
||||
sojou Jayienb Suiddy} Aq 10 ‘syUSTIOIOUI oINUTIAI-J8g-Jesg & JO sys} UL ofquisn(pe ‘ATTeouIAUINU paiajus oq ABU OdINALL e
|
||||
synthesizers!
|
||||
|
||||
(jouer doup u3a9)
|
||||
¢ Ultra-fast 3%” disk drive stores complex songs in seconds and holds over 110,000 notes
|
||||
|
||||
“puooes Jed souely O€ 10 “SZ “pz 18 [LVAG-MAd-SHN VU 10 ALOANIWAAd-SLVAd U! patyoeds aq kewl OAL «
|
||||
‘uoTe1odo [SVx JO} Aj[eusoyUT JoyndUIOd 11g 9] 98108 ZHI 8g ‘poeds-ysry Bann soz] e
|
||||
per disk!
|
||||
|
||||
"9U0} DUAS 0006 UUL] Jo wNIqUUr] prepue}s 0} OUAS [ITAA ©
|
||||
¢ One or all tracks may be TRANSPOSED at the touch of a key.
|
||||
e Exclusive real-time ERASE function makes editing FAST.
|
||||
* Exclusive REPEAT function automatically repeats any held notes at a pre-selected
|
||||
|
||||
“ONYBA 9}OU poloapes Aue Je sas—nd jndyno 07 pewureigold 3q ACW SL Ad LNO YADONAL OML
|
||||
rhythmic value.
|
||||
|
||||
"ALVOOT 10 GOLS/AV 1d ‘LWddad “ASV
|
||||
¢ TIMING CORRECTION works during playback and operates without ‘chopping’ notes.
|
||||
|
||||
SUIpNpoUr ‘suOTIOUN] posn A[UOUILUOS 94] JO AUBUT [O1]UOD AJ9]OWIAI 0} PousIsse oq ACUI ST AdNI HOLIMSLOO OME «
|
||||
“SUIPIONAI I[IYM P2sesd JOU Iv $3}OU BUTISIXO—ZUIPIOIA SATON.ASOP-UON
|
||||
¢ Optional SMPTE time code synchronization.
|
||||
|
||||
‘suoneurldxa peuoyippe sdeydsip uowng g1TqH
|
||||
© Optional remote control.
|
||||
|
||||
oy] ‘pepsau JI ‘suoneiodo [ye yYsnosy] NOA sapins ApIespo Avfdsip QO] Joey Z7¢ 9y3—uoeIodo Urea] 0} Ased ‘aus «
|
||||
Recording a Sequence
|
||||
|
||||
jUorel]suowtap & IO} Aepol Jayeap uur’] INOA dag ‘dISHUL
|
||||
INOA 0} UONUS}]¥ PaplAIPUN INOA SUTJOASp ITY ps pue
|
||||
p1osai ‘asoduod no Jay 0} pausisap st 1s0uenbesuur’] oy)
|
||||
Aum Aposiooid $,Jeu], ‘SS9d0Id SATTBS1D OY} YIM SOIOJIOIUT
|
||||
yey) xo]dwWI0d Os dq JOA9U P[NoUsS osn NOA AZopOuYdE} oy
|
||||
To record a sequence, simply press RECORD and PLAY,
|
||||
then play your MIDI keyboard in time to the Sequencer’s
|
||||
click track. When the sequence loops back around to bar 1,
|
||||
you’ ll hear what you played—only all timing errors will be
|
||||
|
||||
ISTUMOIAUIO?) NOAA UOHISOdWIO)
|
||||
corrected! (Timing correction may be adjusted or defeated).
|
||||
|
||||
"NOSpr] B Oy ‘AONUTJUT yada 0} seq Maz Se] BY] Jas UdAd
|
||||
uvd NOA ‘palisap JJ ‘souanbes Mou ¥B OVUT sjied ou] [Te Adoo
|
||||
ATesrewO Ne WI) [IM ONOS ALVAAO JeyIe80} wey}
|
||||
,deyd,, 0} UOTOUNJ ONOS ALVA ou] asn usy] ‘saouanbes
|
||||
JENPIAIpUt UI (“949 ‘snJOYD ‘aS1OA) UOTIDIS JIseq Yes
|
||||
Pl0da1 OF ST ABM JOuIOUY “(812g 666 01 dn) ysnory) ABM
|
||||
Any additional notes played will be added into the track
|
||||
— existing notes are not erased while recording!
|
||||
|
||||
dU} [fe YORI] YORs p10991 0} ST SUOS B 9789I9 0} ABM SUG,
|
||||
FAST FORWARD, REWIND, and LOCATE controls
|
||||
may be used at any time to quickly access any location in
|
||||
your sequence for spot-recording. To overdub a new part,
|
||||
select a different track and start recording—while you
|
||||
record, the first track will play in perfect sync (unless you
|
||||
MUTE it, or SOLO another track). In this way, up to 32
|
||||
tracks may be overdubbed! All MIDI effects are recorded
|
||||
including pitch bend, modulation, velocity, aftertouch,
|
||||
sustain pedal, and program changes!
|
||||
|
||||
SUOS & SUTVAID
|
||||
Editing
|
||||
|
||||
*suoT}oes poJUBMUN
|
||||
To erase a wrong note, simply hold ERASE and press
|
||||
the note to be erased just before it plays in the sequence—
|
||||
when played back, it will be gone. Notes may also be
|
||||
|
||||
SAOUIOI 0} ABM SWS dU} SoyeIodo SUV ALATAaG
|
||||
added, erased, or changed using the SINGLE STEP func-
|
||||
tion. To overdub notes at specific points within a sequence,
|
||||
|
||||
“OBPLIq dy} PUB SNIOY PUOdAS dT]] Ud9MIAQ SIDA ISI
|
||||
Additional Features
|
||||
|
||||
ay) Jo Adoo B JJasuT WYSE NOAA ‘afdwexs 10.f ‘UO JUSIN]JIP
|
||||
simply use LOCATE, FAST FORWARD, or REWIND to
|
||||
find the desired bar number, then start recording.
|
||||
|
||||
B IO aouaNbas sues OY} UI—JOY OUP 0} UOTIEIO] 9UO WOT]
|
||||
$1Bq JAOUI OF NOA sMOTIe WOTIOUNS AdOO/IMASNI OULL
|
||||
The INSERT/COPY function allows you to move bars
|
||||
from one location to another—in the same sequence or a
|
||||
different one. For example, you might insert a copy of the
|
||||
first verse between the second chorus and the bridge.
|
||||
DELETE BARS operates the same way to remove
|
||||
unwanted sections,
|
||||
|
||||
‘SUIPIONAI JIVIS Udy) “OQuINU eq porisop ay} puy
|
||||
Creating a Song
|
||||
|
||||
0} CNIMAY 10 ‘CYVM Od LSWA “AEVOOT esn Apduns
|
||||
One way to create a song is to record each track all the
|
||||
way through (up to 999 bars). Another way is to record
|
||||
each basic section (verse, chorus, etc.) in individual
|
||||
sequences, then use the CREATE SONG function to “chain”
|
||||
them together. CREATE SONG will then automatically
|
||||
copy all the parts into a new sequence. If desired, you can
|
||||
even set the last few bars to repeat infinitely, for a fadeout.
|
||||
|
||||
sainjeay [PUOHIPPY
|
||||
Composition Without Compromise
|
||||
|
||||
‘gouanbas & UTYIIM s]UTOd a1y1dads 3¥ $9100 QnPIOAO OL "UOT}
|
||||
-ouns dALLS ATONIS 24) Suisn pasueyo Jo ‘pasesa ‘pappe
|
||||
aq osye ABUT S9]ON ‘U0 9q ]IIM 1 “yoeq podeyd uayM
|
||||
—aouanbas oy] ul skeyd 71 a10J9q Isnf posers oq 0} d]0U ayy
|
||||
ssaid pue ASvwug ploy Aydunis ‘jou Suomm & aseso OL
|
||||
The technology you use should never be so complex that
|
||||
it interferes with the creative process. That’s precisely why
|
||||
the LinnSequencer is designed to let you compose, record
|
||||
and edit while devoting your undivided attention to your
|
||||
music. See your Linn dealer today for a demonstration!
|
||||
|
||||
sunipa
|
||||
* Simple, easy to learn operation—the 32 character LCD display clearly guides you through all operations. If needed, the
|
||||
|
||||
jsesdueyo ureisoid pue ‘fepod ureysns
|
||||
‘yonoplalje ‘AWOOTOA ‘UOTyeTNpow ‘pusg youd Surpnyour
|
||||
pep10del are $199JJ2 TCTIN [WV iPeqqnpseao aq Aeur syoen
|
||||
Ze 07 dn ‘Kem sie Uy *(foeI} JOyOUR OJOS 10 ALLAN
|
||||
NOA ssofum) duAS yOaysod ul Avy [[IM Yow] ISI 93 “prooar
|
||||
NOA 3[IYM—SUIPIOIA LIBIS PU YORI) TUdIOTJIP B JOaTas
|
||||
*y1ed MOU B QNPIsA0 OL, “SuIps0daJ-jods 10} aouanbes mno0k
|
||||
UI UOHBIO] Aue ssad0e ATYOIND 0} owt} Aue ye pasn aq AvUE
|
||||
SJONUOD FLIVOOT pur ‘ANIMA ‘CYVMaYOd LSVd
|
||||
{SUIPIOSAI {IY posesa JOU se So]OU SuTsTXO—
|
||||
yous} 3U} OUT poppe aq JIM poteyd sajou yeuonippe Auy
|
||||
*(povesjap 10 poysn{pe oq ABW UOTIIII0D BUTUTT]) j{paqoeLI09
|
||||
2q ][IM S1OLIe Sur [fe ATUO—patey]d nod Jey Jedy ]],NOA
|
||||
‘] req 0] punose yoeq sdoo] sduanbas ay] Udy AA “YOu Yor
|
||||
§,sa0uaNbas at} O] SUIT) UI preogday [IW] INO Avy usy3
|
||||
AV'1d pue (YOON ssoid Ayduus ‘aousnbes & p1o09es OF,
|
||||
HELP button displays additional explanations.
|
||||
|
||||
g0uaNbas & SUIP10I0y]
|
||||
* Non-destructive recording—existing notes are not erased while recording.
|
||||
¢ Two FOOTSWITCH INPUTS may be assigned to remotely control many of the commonly used functions, including
|
||||
|
||||
‘JONWOD s}JouNaI TeuONdGO e
|
||||
ERASE, REPEAT, PLAY/STOP, or LOCATE.
|
||||
|
||||
"UOTJEZIUOIYUAS OPOS UIT} FLAWS [euondo e
|
||||
¢ Iwo TRIGGER OUTPUTS may be programmed to output pulses at any selected note value.
|
||||
|
||||
‘sou .sulddoys, noyyM sayelodo pue yoegdvyd ZuLINp S¥IOM NOLLOANNYOO ONIWILL e
|
||||
© Will sync to standard LinnDrum or Linn 9000 sync tone.
|
||||
|
||||
‘onqea ory AY
|
||||
© Utilizes ultra high-speed, 8 MHz 80186 16 bit computer internally for FAST operation.
|
||||
* TEMPO may be specified in BEATS-PER-MINUTE or FRAMES-PER-BEAT at 24, 25, or 30 frames per second,
|
||||
|
||||
pojoojes-oid & ye sajou pyoy Aue syeadas ATTeONewWO Ne UOTOUNS [WAdAY OAISNOX e
|
||||
‘LSVJ SUnIpS soyeu UOTOUN ASV UA OUlN-[eal SAISNIOXY e
|
||||
‘Koy B JO YONO} 941 12 CASOdSNVALL 0g ABU Syde] [Te 10 9UC e
|
||||
(even drop frame!)
|
||||
|
||||
i ASIP Jed
|
||||
¢ TEMPO may be entered numerically, adjustable in tenths of a Beat-Per-Minute increments, or by tapping quarter notes
|
||||
|
||||
S9}0U OOO‘OTT JOA SpfOy puv SpUOdeS UT SBUOS Xa[AUIOD So10}S DALIP YSIP , 74 € ISCJ-CNIN
|
||||
on the TAP TEMPO button.
|
||||
|
||||
jSIOZISOUJUAS
|
||||
¢ TEMPO CHANGES may be programmed into a sequence, with smooth transitions if desired.
|
||||
¢ Any TIME SIGNATURE may be used, and may be changed within a song.
|
||||
|
||||
stuoydAjod of 0} dn skeyd A[snoourynuls ‘spouueYd [IW 9T JO duo 0} pousisse oq
|
||||
ABUL YORI] YOR ‘syous) oruoydAjod ‘snoouelnurs 7¢ SuTeJUOS ssouUaNbas QO] OY} JO YORA e
|
||||
linn
|
||||
Linn Electronics, Inc.
|
||||
|
||||
‘SJONUOS ATWOOT pur ‘GNIMAY ‘GaVM OA
|
||||
LSVd ‘GYOOde AOLS ‘AV Td YIM Jopsocas ade} Yowsj-N[NU O} eps st UOTLISdO @
|
||||
LOPNOUT SaINjeoy s[quyIeUlss AUB S.JJ ‘OSN pue UIes] 0} o[duns A[suIzeUe JOA ‘PnJsomod APOUIOITXO
|
||||
St 1] “UeIOIsNUL feUOIssajoid oY} 10 JOO} soUBULIOJIJAd pue UOTIsOduIOS 11e-dY1-JO-9}e)s B SI IONUANbDaguUT] ay
|
||||
|
||||
JOps1odady soUINbIS [GTI YVAL ZE
|
||||
Jgouanbaguury oy
|
||||
18720 Oxnard Street, Tarzana, CA 91356
|
||||
(818) 708-8131 TELEX #298949 LINN UR
|
||||
|
||||
BIN
Binary file not shown.
+34
-34
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.ucmqv4tt/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sly7uqzv/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 582 131 1968 303">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 582 131 1968 303">
|
||||
<span class='ocr_header' id='line_1_1' title="bbox 882 131 1657 217; baseline 0.001 -17; x_size 85; x_descenders 16; x_ascenders 19">
|
||||
@@ -29,7 +29,7 @@
|
||||
<p class='ocr_par' id='par_1_2' lang='eng' title="bbox 347 380 2188 423">
|
||||
<span class='ocr_header' id='line_1_3' title="bbox 347 380 2188 423; baseline -0.001 -12; x_size 38; x_descenders 8; x_ascenders 10">
|
||||
<span class='ocrx_word' id='word_1_8' title='bbox 347 380 412 410; x_wconf 93'>The</span>
|
||||
<span class='ocrx_word' id='word_1_9' title='bbox 424 380 676 417; x_wconf 92'>LinnSequencer</span>
|
||||
<span class='ocrx_word' id='word_1_9' title='bbox 424 380 676 417; x_wconf 91'>LinnSequencer</span>
|
||||
<span class='ocrx_word' id='word_1_10' title='bbox 688 380 712 411; x_wconf 96'>is</span>
|
||||
<span class='ocrx_word' id='word_1_11' title='bbox 724 390 743 411; x_wconf 96'>a</span>
|
||||
<span class='ocrx_word' id='word_1_12' title='bbox 754 381 1005 423; x_wconf 96'>state-of-the-art</span>
|
||||
@@ -39,7 +39,7 @@
|
||||
<span class='ocrx_word' id='word_1_16' title='bbox 1536 380 1602 411; x_wconf 96'>tool</span>
|
||||
<span class='ocrx_word' id='word_1_17' title='bbox 1615 380 1663 411; x_wconf 97'>for</span>
|
||||
<span class='ocrx_word' id='word_1_18' title='bbox 1674 381 1725 410; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_19' title='bbox 1737 380 1940 417; x_wconf 95'>professional</span>
|
||||
<span class='ocrx_word' id='word_1_19' title='bbox 1737 380 1940 417; x_wconf 96'>professional</span>
|
||||
<span class='ocrx_word' id='word_1_20' title='bbox 1952 380 2112 411; x_wconf 96'>musician.</span>
|
||||
<span class='ocrx_word' id='word_1_21' title='bbox 2127 381 2152 410; x_wconf 96'>It</span>
|
||||
<span class='ocrx_word' id='word_1_22' title='bbox 2164 380 2188 410; x_wconf 96'>is</span>
|
||||
@@ -209,7 +209,7 @@
|
||||
<div class='ocr_carea' id='block_1_8' title="bbox 382 1021 689 1065">
|
||||
<p class='ocr_par' id='par_1_10' lang='eng' title="bbox 382 1021 689 1065">
|
||||
<span class='ocr_line' id='line_1_15' title="bbox 382 1021 689 1065; baseline 0.003 -8; x_size 45; x_descenders 8; x_ascenders 12">
|
||||
<span class='ocrx_word' id='word_1_135' title='bbox 382 1021 564 1065; x_wconf 96'>rhythmic</span>
|
||||
<span class='ocrx_word' id='word_1_135' title='bbox 382 1021 564 1065; x_wconf 95'>rhythmic</span>
|
||||
<span class='ocrx_word' id='word_1_136' title='bbox 577 1021 689 1058; x_wconf 96'>value.</span>
|
||||
</span>
|
||||
</p>
|
||||
@@ -246,7 +246,7 @@
|
||||
<div class='ocr_carea' id='block_1_11' title="bbox 349 1195 874 1240">
|
||||
<p class='ocr_par' id='par_1_13' lang='eng' title="bbox 349 1195 874 1240">
|
||||
<span class='ocr_line' id='line_1_18' title="bbox 349 1195 874 1240; baseline 0 -8; x_size 45; x_descenders 8; x_ascenders 12">
|
||||
<span class='ocrx_word' id='word_1_154' title='bbox 349 1203 367 1222; x_wconf 74'>©</span>
|
||||
<span class='ocrx_word' id='word_1_154' title='bbox 349 1203 367 1222; x_wconf 70'>©</span>
|
||||
<span class='ocrx_word' id='word_1_155' title='bbox 382 1195 560 1240; x_wconf 96'>Optional</span>
|
||||
<span class='ocrx_word' id='word_1_156' title='bbox 573 1201 709 1233; x_wconf 96'>remote</span>
|
||||
<span class='ocrx_word' id='word_1_157' title='bbox 723 1196 874 1233; x_wconf 95'>control.</span>
|
||||
@@ -300,8 +300,8 @@
|
||||
<span class='ocrx_word' id='word_1_190' title='bbox 1213 1419 1232 1450; x_wconf 74'>1,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_23' title="bbox 346 1457 1223 1491; baseline 0.001 -7; x_size 34; x_descenders 7; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_191' title='bbox 346 1457 430 1490; x_wconf 14'>you’</span>
|
||||
<span class='ocrx_word' id='word_1_192' title='bbox 406 1453 436 1496; x_wconf 14'>ll</span>
|
||||
<span class='ocrx_word' id='word_1_191' title='bbox 346 1457 430 1490; x_wconf 15'>you’</span>
|
||||
<span class='ocrx_word' id='word_1_192' title='bbox 406 1453 439 1496; x_wconf 15'>ll</span>
|
||||
<span class='ocrx_word' id='word_1_193' title='bbox 441 1457 506 1485; x_wconf 96'>hear</span>
|
||||
<span class='ocrx_word' id='word_1_194' title='bbox 517 1458 590 1485; x_wconf 96'>what</span>
|
||||
<span class='ocrx_word' id='word_1_195' title='bbox 600 1466 654 1491; x_wconf 93'>you</span>
|
||||
@@ -361,7 +361,7 @@
|
||||
<span class='ocrx_word' id='word_1_230' title='bbox 684 1617 844 1648; x_wconf 95'>REWIND,</span>
|
||||
<span class='ocrx_word' id='word_1_231' title='bbox 857 1616 912 1643; x_wconf 95'>and</span>
|
||||
<span class='ocrx_word' id='word_1_232' title='bbox 924 1616 1068 1643; x_wconf 96'>LOCATE</span>
|
||||
<span class='ocrx_word' id='word_1_233' title='bbox 1079 1616 1199 1643; x_wconf 95'>controls</span>
|
||||
<span class='ocrx_word' id='word_1_233' title='bbox 1079 1616 1199 1643; x_wconf 96'>controls</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_28' title="bbox 346 1655 1202 1689; baseline 0 -7; x_size 34; x_descenders 6; x_ascenders 9">
|
||||
<span class='ocrx_word' id='word_1_234' title='bbox 346 1663 409 1688; x_wconf 92'>may</span>
|
||||
@@ -400,9 +400,9 @@
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_31' title="bbox 346 1773 1203 1808; baseline 0.001 -8; x_size 33; x_descenders 6; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_263' title='bbox 346 1774 448 1806; x_wconf 96'>record,</span>
|
||||
<span class='ocrx_word' id='word_1_264' title='bbox 460 1774 506 1801; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_265' title='bbox 503 1769 577 1812; x_wconf 96'>first</span>
|
||||
<span class='ocrx_word' id='word_1_266' title='bbox 581 1774 658 1801; x_wconf 96'>track</span>
|
||||
<span class='ocrx_word' id='word_1_264' title='bbox 460 1774 506 1801; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_265' title='bbox 517 1773 577 1801; x_wconf 96'>first</span>
|
||||
<span class='ocrx_word' id='word_1_266' title='bbox 587 1774 662 1801; x_wconf 96'>track</span>
|
||||
<span class='ocrx_word' id='word_1_267' title='bbox 673 1774 726 1801; x_wconf 96'>will</span>
|
||||
<span class='ocrx_word' id='word_1_268' title='bbox 736 1774 799 1807; x_wconf 96'>play</span>
|
||||
<span class='ocrx_word' id='word_1_269' title='bbox 809 1774 836 1801; x_wconf 96'>in</span>
|
||||
@@ -412,11 +412,11 @@
|
||||
<span class='ocrx_word' id='word_1_273' title='bbox 1148 1782 1203 1807; x_wconf 96'>you</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_32' title="bbox 346 1813 1191 1847; baseline 0.002 -8; x_size 33; x_descenders 5; x_ascenders 9">
|
||||
<span class='ocrx_word' id='word_1_274' title='bbox 346 1813 454 1840; x_wconf 95'>MUTE</span>
|
||||
<span class='ocrx_word' id='word_1_275' title='bbox 464 1813 492 1845; x_wconf 95'>it,</span>
|
||||
<span class='ocrx_word' id='word_1_274' title='bbox 346 1813 454 1840; x_wconf 94'>MUTE</span>
|
||||
<span class='ocrx_word' id='word_1_275' title='bbox 464 1813 492 1845; x_wconf 94'>it,</span>
|
||||
<span class='ocrx_word' id='word_1_276' title='bbox 505 1821 537 1840; x_wconf 95'>or</span>
|
||||
<span class='ocrx_word' id='word_1_277' title='bbox 547 1813 642 1840; x_wconf 95'>SOLO</span>
|
||||
<span class='ocrx_word' id='word_1_278' title='bbox 653 1814 769 1841; x_wconf 95'>another</span>
|
||||
<span class='ocrx_word' id='word_1_278' title='bbox 653 1814 769 1841; x_wconf 96'>another</span>
|
||||
<span class='ocrx_word' id='word_1_279' title='bbox 779 1814 875 1847; x_wconf 94'>track).</span>
|
||||
<span class='ocrx_word' id='word_1_280' title='bbox 889 1814 920 1840; x_wconf 96'>In</span>
|
||||
<span class='ocrx_word' id='word_1_281' title='bbox 930 1813 984 1841; x_wconf 96'>this</span>
|
||||
@@ -518,13 +518,13 @@
|
||||
<span class='ocr_line' id='line_1_41' title="bbox 345 2207 1228 2242; baseline 0.002 -8; x_size 35; x_descenders 7; x_ascenders 9">
|
||||
<span class='ocrx_word' id='word_1_349' title='bbox 345 2207 412 2234; x_wconf 96'>tion.</span>
|
||||
<span class='ocrx_word' id='word_1_350' title='bbox 424 2208 461 2235; x_wconf 93'>To</span>
|
||||
<span class='ocrx_word' id='word_1_351' title='bbox 472 2208 592 2235; x_wconf 91'>overdub</span>
|
||||
<span class='ocrx_word' id='word_1_351' title='bbox 472 2208 592 2235; x_wconf 92'>overdub</span>
|
||||
<span class='ocrx_word' id='word_1_352' title='bbox 603 2212 680 2235; x_wconf 96'>notes</span>
|
||||
<span class='ocrx_word' id='word_1_353' title='bbox 691 2212 718 2235; x_wconf 96'>at</span>
|
||||
<span class='ocrx_word' id='word_1_354' title='bbox 729 2208 841 2242; x_wconf 96'>specific</span>
|
||||
<span class='ocrx_word' id='word_1_355' title='bbox 851 2209 943 2242; x_wconf 97'>points</span>
|
||||
<span class='ocrx_word' id='word_1_356' title='bbox 955 2208 1049 2236; x_wconf 96'>within</span>
|
||||
<span class='ocrx_word' id='word_1_357' title='bbox 1060 2217 1076 2236; x_wconf 96'>a</span>
|
||||
<span class='ocrx_word' id='word_1_356' title='bbox 955 2208 1049 2236; x_wconf 97'>within</span>
|
||||
<span class='ocrx_word' id='word_1_357' title='bbox 1060 2217 1076 2236; x_wconf 97'>a</span>
|
||||
<span class='ocrx_word' id='word_1_358' title='bbox 1086 2216 1228 2242; x_wconf 96'>sequence,</span>
|
||||
</span>
|
||||
</p>
|
||||
@@ -681,7 +681,7 @@
|
||||
<span class='ocrx_word' id='word_1_465' title='bbox 1810 1808 1911 1835; x_wconf 96'>SONG</span>
|
||||
<span class='ocrx_word' id='word_1_466' title='bbox 1923 1808 2050 1836; x_wconf 96'>function</span>
|
||||
<span class='ocrx_word' id='word_1_467' title='bbox 2060 1812 2089 1835; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_468' title='bbox 2103 1808 2215 1836; x_wconf 93'>“chain”</span>
|
||||
<span class='ocrx_word' id='word_1_468' title='bbox 2103 1808 2215 1836; x_wconf 91'>“chain”</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_56' title="bbox 1295 1847 2135 1881; baseline 0.001 -7; x_size 34; x_descenders 7; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_469' title='bbox 1295 1848 1370 1874; x_wconf 96'>them</span>
|
||||
@@ -874,10 +874,10 @@
|
||||
<div class='ocr_carea' id='block_1_25' title="bbox 347 2556 1768 2590">
|
||||
<p class='ocr_par' id='par_1_33' lang='eng' title="bbox 347 2556 1768 2590">
|
||||
<span class='ocr_header' id='line_1_70' title="bbox 347 2556 1768 2590; baseline 0.001 -8; x_size 34; x_descenders 7; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_604' title='bbox 347 2561 361 2575; x_wconf 86'>¢</span>
|
||||
<span class='ocrx_word' id='word_1_605' title='bbox 372 2556 433 2583; x_wconf 85'>Iwo</span>
|
||||
<span class='ocrx_word' id='word_1_604' title='bbox 347 2561 361 2575; x_wconf 85'>¢</span>
|
||||
<span class='ocrx_word' id='word_1_605' title='bbox 372 2556 433 2583; x_wconf 84'>Iwo</span>
|
||||
<span class='ocrx_word' id='word_1_606' title='bbox 443 2556 612 2583; x_wconf 96'>TRIGGER</span>
|
||||
<span class='ocrx_word' id='word_1_607' title='bbox 623 2556 797 2584; x_wconf 96'>OUTPUTS</span>
|
||||
<span class='ocrx_word' id='word_1_607' title='bbox 623 2556 797 2584; x_wconf 95'>OUTPUTS</span>
|
||||
<span class='ocrx_word' id='word_1_608' title='bbox 808 2565 871 2590; x_wconf 96'>may</span>
|
||||
<span class='ocrx_word' id='word_1_609' title='bbox 881 2557 915 2584; x_wconf 96'>be</span>
|
||||
<span class='ocrx_word' id='word_1_610' title='bbox 925 2557 1119 2590; x_wconf 96'>programmed</span>
|
||||
@@ -887,7 +887,7 @@
|
||||
<span class='ocrx_word' id='word_1_614' title='bbox 1381 2561 1409 2584; x_wconf 96'>at</span>
|
||||
<span class='ocrx_word' id='word_1_615' title='bbox 1419 2565 1472 2590; x_wconf 96'>any</span>
|
||||
<span class='ocrx_word' id='word_1_616' title='bbox 1483 2557 1598 2584; x_wconf 96'>selected</span>
|
||||
<span class='ocrx_word' id='word_1_617' title='bbox 1608 2561 1673 2584; x_wconf 97'>note</span>
|
||||
<span class='ocrx_word' id='word_1_617' title='bbox 1608 2561 1673 2584; x_wconf 96'>note</span>
|
||||
<span class='ocrx_word' id='word_1_618' title='bbox 1683 2556 1768 2583; x_wconf 96'>value.</span>
|
||||
</span>
|
||||
</p>
|
||||
@@ -911,15 +911,15 @@
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_27' title="bbox 347 2648 2100 2727">
|
||||
<p class='ocr_par' id='par_1_35' lang='eng' title="bbox 347 2648 2100 2727">
|
||||
<span class='ocr_header' id='line_1_72' title="bbox 347 2648 1664 2682; baseline 0.001 -7; x_size 33; x_descenders 6; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_630' title='bbox 347 2654 360 2667; x_wconf 45'>©</span>
|
||||
<span class='ocrx_word' id='word_1_631' title='bbox 372 2648 483 2675; x_wconf 95'>Utilizes</span>
|
||||
<span class='ocrx_word' id='word_1_632' title='bbox 493 2648 564 2680; x_wconf 96'>ultra</span>
|
||||
<span class='ocr_header' id='line_1_72' title="bbox 347 2648 1664 2682; baseline 0 -7; x_size 33; x_descenders 6; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_630' title='bbox 347 2654 360 2667; x_wconf 51'>©</span>
|
||||
<span class='ocrx_word' id='word_1_631' title='bbox 372 2648 483 2675; x_wconf 96'>Utilizes</span>
|
||||
<span class='ocrx_word' id='word_1_632' title='bbox 493 2648 564 2677; x_wconf 96'>ultra</span>
|
||||
<span class='ocrx_word' id='word_1_633' title='bbox 573 2648 744 2682; x_wconf 96'>high-speed,</span>
|
||||
<span class='ocrx_word' id='word_1_634' title='bbox 757 2649 772 2676; x_wconf 95'>8</span>
|
||||
<span class='ocrx_word' id='word_1_635' title='bbox 783 2649 862 2675; x_wconf 94'>MHz</span>
|
||||
<span class='ocrx_word' id='word_1_636' title='bbox 873 2649 954 2676; x_wconf 96'>80186</span>
|
||||
<span class='ocrx_word' id='word_1_637' title='bbox 965 2649 994 2676; x_wconf 96'>16</span>
|
||||
<span class='ocrx_word' id='word_1_636' title='bbox 873 2649 954 2676; x_wconf 95'>80186</span>
|
||||
<span class='ocrx_word' id='word_1_637' title='bbox 965 2649 994 2676; x_wconf 95'>16</span>
|
||||
<span class='ocrx_word' id='word_1_638' title='bbox 1004 2648 1043 2676; x_wconf 96'>bit</span>
|
||||
<span class='ocrx_word' id='word_1_639' title='bbox 1054 2653 1197 2682; x_wconf 96'>computer</span>
|
||||
<span class='ocrx_word' id='word_1_640' title='bbox 1208 2649 1350 2682; x_wconf 96'>internally</span>
|
||||
@@ -960,18 +960,18 @@
|
||||
<div class='ocr_carea' id='block_1_29' title="bbox 347 2777 2174 2811">
|
||||
<p class='ocr_par' id='par_1_37' lang='eng' title="bbox 347 2777 2174 2811">
|
||||
<span class='ocr_header' id='line_1_75' title="bbox 347 2777 2174 2811; baseline 0.001 -8; x_size 33; x_descenders 5; x_ascenders 9">
|
||||
<span class='ocrx_word' id='word_1_664' title='bbox 347 2782 360 2796; x_wconf 81'>¢</span>
|
||||
<span class='ocrx_word' id='word_1_664' title='bbox 347 2782 360 2796; x_wconf 79'>¢</span>
|
||||
<span class='ocrx_word' id='word_1_665' title='bbox 372 2777 504 2804; x_wconf 94'>TEMPO</span>
|
||||
<span class='ocrx_word' id='word_1_666' title='bbox 515 2785 578 2810; x_wconf 96'>may</span>
|
||||
<span class='ocrx_word' id='word_1_667' title='bbox 588 2777 622 2804; x_wconf 96'>be</span>
|
||||
<span class='ocrx_word' id='word_1_667' title='bbox 588 2777 622 2804; x_wconf 95'>be</span>
|
||||
<span class='ocrx_word' id='word_1_668' title='bbox 633 2778 741 2804; x_wconf 95'>entered</span>
|
||||
<span class='ocrx_word' id='word_1_669' title='bbox 751 2777 934 2811; x_wconf 96'>numerically,</span>
|
||||
<span class='ocrx_word' id='word_1_670' title='bbox 946 2777 1101 2811; x_wconf 95'>adjustable</span>
|
||||
<span class='ocrx_word' id='word_1_671' title='bbox 1111 2777 1139 2804; x_wconf 95'>in</span>
|
||||
<span class='ocrx_word' id='word_1_670' title='bbox 946 2777 1101 2811; x_wconf 96'>adjustable</span>
|
||||
<span class='ocrx_word' id='word_1_671' title='bbox 1111 2777 1139 2804; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_672' title='bbox 1149 2778 1239 2805; x_wconf 96'>tenths</span>
|
||||
<span class='ocrx_word' id='word_1_673' title='bbox 1250 2778 1282 2805; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_674' title='bbox 1290 2786 1307 2805; x_wconf 91'>a</span>
|
||||
<span class='ocrx_word' id='word_1_675' title='bbox 1317 2777 1567 2805; x_wconf 91'>Beat-Per-Minute</span>
|
||||
<span class='ocrx_word' id='word_1_674' title='bbox 1290 2786 1307 2805; x_wconf 93'>a</span>
|
||||
<span class='ocrx_word' id='word_1_675' title='bbox 1317 2777 1567 2805; x_wconf 92'>Beat-Per-Minute</span>
|
||||
<span class='ocrx_word' id='word_1_676' title='bbox 1577 2777 1748 2809; x_wconf 96'>increments,</span>
|
||||
<span class='ocrx_word' id='word_1_677' title='bbox 1760 2785 1792 2804; x_wconf 96'>or</span>
|
||||
<span class='ocrx_word' id='word_1_678' title='bbox 1803 2777 1839 2810; x_wconf 96'>by</span>
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+381
-373
@@ -9,459 +9,467 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.1ca2h7iv/000001_ocr.png"; bbox 0 0 1000 1520; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 126 101 547 145">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 126 101 547 145">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 126 101 547 125; baseline 0.005 -7; x_size 23; x_descenders 6; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_1' title='bbox 126 101 173 118; x_wconf 37'>41st</span>
|
||||
<span class='ocrx_word' id='word_1_2' title='bbox 181 101 303 124; x_wconf 16'>CONGRESS;</span>
|
||||
<span class='ocrx_word' id='word_1_3' title='bbox 329 123 331 125; x_wconf 42'>|</span>
|
||||
<span class='ocrx_word' id='word_1_4' title='bbox 443 103 547 120; x_wconf 94'>SENATE.</span>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.6nqy9raf/000001_ocr.png"; bbox 0 0 1000 1520; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 122 99 848 146">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 122 99 848 146">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 122 99 848 146; baseline 0 -26; x_size 22; x_descenders 5; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_1' title='bbox 122 104 169 121; x_wconf 29'>4ist</span>
|
||||
<span class='ocrx_word' id='word_1_2' title='bbox 177 103 291 125; x_wconf 54'>ConGREss,</span>
|
||||
<span class='ocrx_word' id='word_1_3' title='bbox 300 105 308 146; x_wconf 46'>}</span>
|
||||
<span class='ocrx_word' id='word_1_4' title='bbox 439 99 543 130; x_wconf 94'>SENATE.</span>
|
||||
<span class='ocrx_word' id='word_1_5' title='bbox 736 105 745 146; x_wconf 90'>{</span>
|
||||
<span class='ocrx_word' id='word_1_6' title='bbox 753 103 788 120; x_wconf 94'>Ex.</span>
|
||||
<span class='ocrx_word' id='word_1_7' title='bbox 798 103 848 121; x_wconf 95'>Doc,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_2' title="bbox 156 104 312 145; baseline 0.006 -5; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_5' title='bbox 156 124 180 140; x_wconf 89'>3d</span>
|
||||
<span class='ocrx_word' id='word_1_6' title='bbox 189 124 264 141; x_wconf 91'>Session.</span>
|
||||
<span class='ocrx_word' id='word_1_7' title='bbox 304 104 312 145; x_wconf 52'>}</span>
|
||||
<span class='ocr_line' id='line_1_2' title="bbox 152 125 838 143; baseline -0.001 0; x_size 21.943821; x_descenders 4.94382; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_8' title='bbox 152 126 176 142; x_wconf 93'>3d</span>
|
||||
<span class='ocrx_word' id='word_1_9' title='bbox 185 126 260 143; x_wconf 88'>Session.</span>
|
||||
<span class='ocrx_word' id='word_1_10' title='bbox 767 125 802 142; x_wconf 86'>No.</span>
|
||||
<span class='ocrx_word' id='word_1_11' title='bbox 810 126 838 142; x_wconf 76'>25.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_2' title="bbox 388 244 597 269">
|
||||
<p class='ocr_par' id='par_1_2' lang='eng' title="bbox 388 244 597 269">
|
||||
<span class='ocr_line' id='line_1_3' title="bbox 388 244 597 269; baseline 0.005 -1; x_size 32.400002; x_descenders 8.1000004; x_ascenders 8.1000004">
|
||||
<span class='ocrx_word' id='word_1_8' title='bbox 388 244 597 269; x_wconf 96'>MESSAGE</span>
|
||||
<div class='ocr_carea' id='block_1_2' title="bbox 384 245 594 269">
|
||||
<p class='ocr_par' id='par_1_2' lang='eng' title="bbox 384 245 594 269">
|
||||
<span class='ocr_line' id='line_1_3' title="bbox 384 245 594 269; baseline 0 0; x_size 32.666668; x_descenders 8.166667; x_ascenders 8.166667">
|
||||
<span class='ocrx_word' id='word_1_12' title='bbox 384 245 594 269; x_wconf 94'>MESSAGE</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_3' title="bbox 462 302 526 313">
|
||||
<p class='ocr_par' id='par_1_3' lang='eng' title="bbox 462 302 526 313">
|
||||
<span class='ocr_line' id='line_1_4' title="bbox 462 302 526 313; baseline 0 0; x_size 20; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_9' title='bbox 462 302 484 313; x_wconf 87'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_10' title='bbox 493 302 526 313; x_wconf 96'>THE</span>
|
||||
<div class='ocr_carea' id='block_1_3' title="bbox 459 302 523 313">
|
||||
<p class='ocr_par' id='par_1_3' lang='eng' title="bbox 459 302 523 313">
|
||||
<span class='ocr_line' id='line_1_4' title="bbox 459 302 523 313; baseline 0 0; x_size 20; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_13' title='bbox 459 302 481 313; x_wconf 87'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_14' title='bbox 490 302 523 313; x_wconf 96'>THE</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_4' title="bbox 151 337 842 377">
|
||||
<p class='ocr_par' id='par_1_4' lang='eng' title="bbox 151 337 842 377">
|
||||
<span class='ocr_line' id='line_1_5' title="bbox 151 337 842 377; baseline 0.009 -8; x_size 43.365078; x_descenders 10.841269; x_ascenders 10.841269">
|
||||
<span class='ocrx_word' id='word_1_11' title='bbox 151 337 361 370; x_wconf 96'>PRESIDENT</span>
|
||||
<span class='ocrx_word' id='word_1_12' title='bbox 382 338 425 370; x_wconf 96'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_13' title='bbox 447 338 521 371; x_wconf 96'>THE</span>
|
||||
<span class='ocrx_word' id='word_1_14' title='bbox 542 339 676 372; x_wconf 96'>UNITED</span>
|
||||
<span class='ocrx_word' id='word_1_15' title='bbox 697 340 842 377; x_wconf 95'>STATES,</span>
|
||||
<div class='ocr_carea' id='block_1_4' title="bbox 148 338 839 375">
|
||||
<p class='ocr_par' id='par_1_4' lang='eng' title="bbox 148 338 839 375">
|
||||
<span class='ocr_line' id='line_1_5' title="bbox 148 338 839 375; baseline 0.003 -3; x_size 43.490196; x_descenders 10.872549; x_ascenders 10.872549">
|
||||
<span class='ocrx_word' id='word_1_15' title='bbox 148 339 358 372; x_wconf 96'>PRESIDENT</span>
|
||||
<span class='ocrx_word' id='word_1_16' title='bbox 379 339 422 371; x_wconf 95'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_17' title='bbox 444 338 518 371; x_wconf 96'>THE</span>
|
||||
<span class='ocrx_word' id='word_1_18' title='bbox 539 338 673 371; x_wconf 96'>UNITED</span>
|
||||
<span class='ocrx_word' id='word_1_19' title='bbox 694 338 839 375; x_wconf 96'>STATES,</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_5' title="bbox 425 406 565 417">
|
||||
<p class='ocr_par' id='par_1_5' lang='eng' title="bbox 425 406 565 417">
|
||||
<span class='ocr_line' id='line_1_6' title="bbox 425 406 565 417; baseline 0 -1; x_size 20; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_16' title='bbox 425 406 565 417; x_wconf 94'>COMMUNICATING</span>
|
||||
<div class='ocr_carea' id='block_1_5' title="bbox 423 406 563 417">
|
||||
<p class='ocr_par' id='par_1_5' lang='eng' title="bbox 423 406 563 417">
|
||||
<span class='ocr_line' id='line_1_6' title="bbox 423 406 563 417; baseline 0 -1; x_size 20; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_20' title='bbox 423 406 563 417; x_wconf 95'>COMMUNICATING</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_6' title="bbox 125 445 861 494">
|
||||
<p class='ocr_par' id='par_1_6' lang='eng' title="bbox 125 445 861 494">
|
||||
<span class='ocr_line' id='line_1_7' title="bbox 125 445 861 472; baseline 0.008 -11; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_17' title='bbox 125 445 143 462; x_wconf 93'>A</span>
|
||||
<span class='ocrx_word' id='word_1_18' title='bbox 149 450 191 467; x_wconf 93'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_19' title='bbox 195 445 217 467; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_20' title='bbox 222 446 331 467; x_wconf 96'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_21' title='bbox 337 446 371 467; x_wconf 95'>for</span>
|
||||
<span class='ocrx_word' id='word_1_22' title='bbox 376 446 403 463; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_23' title='bbox 412 447 494 463; x_wconf 95'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_24' title='bbox 499 449 557 464; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_25' title='bbox 565 448 587 469; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_26' title='bbox 592 448 619 465; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_27' title='bbox 630 448 694 466; x_wconf 90'>United</span>
|
||||
<span class='ocrx_word' id='word_1_28' title='bbox 702 448 760 466; x_wconf 93'>States</span>
|
||||
<span class='ocrx_word' id='word_1_29' title='bbox 768 450 787 466; x_wconf 93'>in</span>
|
||||
<span class='ocrx_word' id='word_1_30' title='bbox 795 449 861 472; x_wconf 95'>Japan,</span>
|
||||
<div class='ocr_carea' id='block_1_6' title="bbox 123 447 859 492">
|
||||
<p class='ocr_par' id='par_1_6' lang='eng' title="bbox 123 447 859 492">
|
||||
<span class='ocr_line' id='line_1_7' title="bbox 123 447 859 470; baseline 0.001 -6; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_21' title='bbox 123 447 141 465; x_wconf 95'>A</span>
|
||||
<span class='ocrx_word' id='word_1_22' title='bbox 147 452 189 469; x_wconf 95'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_23' title='bbox 193 447 215 469; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_24' title='bbox 220 447 329 469; x_wconf 96'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_25' title='bbox 335 447 369 468; x_wconf 95'>for</span>
|
||||
<span class='ocrx_word' id='word_1_26' title='bbox 374 447 401 464; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_27' title='bbox 410 447 492 464; x_wconf 96'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_28' title='bbox 497 449 555 464; x_wconf 79'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_29' title='bbox 563 447 585 469; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_30' title='bbox 590 447 617 464; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_31' title='bbox 628 447 692 465; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_32' title='bbox 700 447 758 465; x_wconf 93'>States</span>
|
||||
<span class='ocrx_word' id='word_1_33' title='bbox 766 448 785 464; x_wconf 93'>in</span>
|
||||
<span class='ocrx_word' id='word_1_34' title='bbox 793 447 859 470; x_wconf 96'>Japan,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_8' title="bbox 147 468 834 494; baseline 0.006 -10; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_31' title='bbox 147 468 215 484; x_wconf 96'>decreed</span>
|
||||
<span class='ocrx_word' id='word_1_32' title='bbox 222 468 258 485; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_33' title='bbox 265 468 323 485; x_wconf 96'>issued</span>
|
||||
<span class='ocrx_word' id='word_1_34' title='bbox 331 468 353 489; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_35' title='bbox 361 468 388 485; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_36' title='bbox 395 468 476 486; x_wconf 95'>minister</span>
|
||||
<span class='ocrx_word' id='word_1_37' title='bbox 482 469 504 491; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_38' title='bbox 509 470 535 487; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_39' title='bbox 546 470 610 487; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_40' title='bbox 618 471 676 488; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_41' title='bbox 682 471 702 488; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_42' title='bbox 710 471 748 488; x_wconf 95'>that</span>
|
||||
<span class='ocrx_word' id='word_1_43' title='bbox 755 474 834 494; x_wconf 77'>country.</span>
|
||||
<span class='ocr_line' id='line_1_8' title="bbox 145 468 832 492; baseline 0 -6; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_35' title='bbox 145 470 213 486; x_wconf 96'>decreed</span>
|
||||
<span class='ocrx_word' id='word_1_36' title='bbox 220 470 256 487; x_wconf 95'>and</span>
|
||||
<span class='ocrx_word' id='word_1_37' title='bbox 263 469 321 487; x_wconf 95'>issued</span>
|
||||
<span class='ocrx_word' id='word_1_38' title='bbox 329 469 351 490; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_39' title='bbox 359 469 386 486; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_40' title='bbox 393 468 474 486; x_wconf 96'>minister</span>
|
||||
<span class='ocrx_word' id='word_1_41' title='bbox 480 469 502 491; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_42' title='bbox 507 470 533 487; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_43' title='bbox 544 469 608 487; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_44' title='bbox 616 470 674 487; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_45' title='bbox 680 470 700 487; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_46' title='bbox 708 470 746 487; x_wconf 96'>that</span>
|
||||
<span class='ocrx_word' id='word_1_47' title='bbox 753 472 832 492; x_wconf 83'>country.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_7' title="bbox 122 539 861 579">
|
||||
<p class='ocr_par' id='par_1_7' lang='eng' title="bbox 122 539 861 579">
|
||||
<span class='ocr_caption' id='line_1_9' title="bbox 122 539 861 579; baseline 0.008 -24; x_size 18; x_descenders 4; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_44' title='bbox 122 541 201 556; x_wconf 81'>January</span>
|
||||
<span class='ocrx_word' id='word_1_45' title='bbox 207 542 230 560; x_wconf 93'>27,</span>
|
||||
<span class='ocrx_word' id='word_1_46' title='bbox 237 542 343 560; x_wconf 39'>1871,—Read,</span>
|
||||
<span class='ocrx_word' id='word_1_47' title='bbox 347 542 414 557; x_wconf 96'>referred</span>
|
||||
<span class='ocrx_word' id='word_1_48' title='bbox 420 544 436 557; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_49' title='bbox 442 543 470 557; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_50' title='bbox 479 539 571 579; x_wconf 66'>Committee</span>
|
||||
<span class='ocrx_word' id='word_1_51' title='bbox 582 548 602 558; x_wconf 93'>on</span>
|
||||
<span class='ocrx_word' id='word_1_52' title='bbox 613 544 704 563; x_wconf 96'>Commerce,</span>
|
||||
<span class='ocrx_word' id='word_1_53' title='bbox 711 545 742 560; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_54' title='bbox 749 546 813 560; x_wconf 96'>ordered</span>
|
||||
<span class='ocrx_word' id='word_1_55' title='bbox 818 547 835 560; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_56' title='bbox 841 546 861 560; x_wconf 96'>be</span>
|
||||
<div class='ocr_carea' id='block_1_7' title="bbox 121 539 860 579">
|
||||
<p class='ocr_par' id='par_1_7' lang='eng' title="bbox 121 539 860 579">
|
||||
<span class='ocr_caption' id='line_1_9' title="bbox 121 539 860 579; baseline 0 -21; x_size 19; x_descenders 4; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_48' title='bbox 121 544 200 559; x_wconf 95'>JANUARY</span>
|
||||
<span class='ocrx_word' id='word_1_49' title='bbox 206 544 229 562; x_wconf 85'>27,</span>
|
||||
<span class='ocrx_word' id='word_1_50' title='bbox 236 543 342 561; x_wconf 58'>1871,—Read,</span>
|
||||
<span class='ocrx_word' id='word_1_51' title='bbox 346 543 413 558; x_wconf 95'>referred</span>
|
||||
<span class='ocrx_word' id='word_1_52' title='bbox 419 545 435 558; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_53' title='bbox 441 543 469 557; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_54' title='bbox 478 539 570 579; x_wconf 66'>Committee</span>
|
||||
<span class='ocrx_word' id='word_1_55' title='bbox 581 547 601 557; x_wconf 96'>on</span>
|
||||
<span class='ocrx_word' id='word_1_56' title='bbox 612 543 703 562; x_wconf 96'>Commerce,</span>
|
||||
<span class='ocrx_word' id='word_1_57' title='bbox 710 543 741 558; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_58' title='bbox 748 544 812 558; x_wconf 96'>ordered</span>
|
||||
<span class='ocrx_word' id='word_1_59' title='bbox 817 545 834 558; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_60' title='bbox 840 544 860 558; x_wconf 96'>be</span>
|
||||
</span>
|
||||
<span class='ocr_caption' id='line_1_10' title="bbox 459 565 525 579; baseline 0 -4; x_size 21.5; x_descenders 5.5; x_ascenders 5.5">
|
||||
<span class='ocrx_word' id='word_1_57' title='bbox 459 565 525 579; x_wconf 96'>printed.</span>
|
||||
<span class='ocr_caption' id='line_1_10' title="bbox 458 565 524 579; baseline 0 -4; x_size 18.782608; x_descenders 4; x_ascenders 4.782609">
|
||||
<span class='ocrx_word' id='word_1_61' title='bbox 458 565 524 579; x_wconf 93'>printed.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_8' title="bbox 122 629 858 769">
|
||||
<p class='ocr_par' id='par_1_8' lang='eng' title="bbox 124 629 566 652">
|
||||
<span class='ocr_line' id='line_1_11' title="bbox 124 629 566 652; baseline 0.005 -6; x_size 22.268028; x_descenders 5.2680273; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_58' title='bbox 124 629 150 646; x_wconf 92'>To</span>
|
||||
<span class='ocrx_word' id='word_1_59' title='bbox 158 629 186 646; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_60' title='bbox 194 629 256 646; x_wconf 96'>Senate</span>
|
||||
<span class='ocrx_word' id='word_1_61' title='bbox 264 630 301 647; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_62' title='bbox 307 630 368 647; x_wconf 96'>House</span>
|
||||
<span class='ocrx_word' id='word_1_63' title='bbox 376 630 398 652; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_64' title='bbox 405 630 555 652; x_wconf 93'>Representatives</span>
|
||||
<span class='ocrx_word' id='word_1_65' title='bbox 560 638 566 648; x_wconf 92'>:</span>
|
||||
<div class='ocr_carea' id='block_1_8' title="bbox 121 631 858 770">
|
||||
<p class='ocr_par' id='par_1_8' lang='eng' title="bbox 123 631 565 653">
|
||||
<span class='ocr_line' id='line_1_11' title="bbox 123 631 565 653; baseline 0 -5; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_62' title='bbox 123 631 149 649; x_wconf 96'>To</span>
|
||||
<span class='ocrx_word' id='word_1_63' title='bbox 157 631 185 648; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_64' title='bbox 193 631 255 648; x_wconf 95'>Senate</span>
|
||||
<span class='ocrx_word' id='word_1_65' title='bbox 263 631 300 649; x_wconf 95'>and</span>
|
||||
<span class='ocrx_word' id='word_1_66' title='bbox 306 631 367 648; x_wconf 95'>House</span>
|
||||
<span class='ocrx_word' id='word_1_67' title='bbox 375 631 397 653; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_68' title='bbox 404 631 554 652; x_wconf 74'>Representatives</span>
|
||||
<span class='ocrx_word' id='word_1_69' title='bbox 559 638 565 648; x_wconf 86'>:</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_9' lang='eng' title="bbox 122 656 858 726">
|
||||
<span class='ocr_line' id='line_1_12' title="bbox 146 656 858 681; baseline 0.008 -9; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_66' title='bbox 146 656 156 672; x_wconf 80'>I</span>
|
||||
<span class='ocrx_word' id='word_1_67' title='bbox 163 657 251 673; x_wconf 80'>transmit</span>
|
||||
<span class='ocrx_word' id='word_1_68' title='bbox 262 656 358 680; x_wconf 96'>herewith,</span>
|
||||
<span class='ocrx_word' id='word_1_69' title='bbox 366 657 395 674; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_70' title='bbox 402 658 435 674; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_71' title='bbox 442 658 578 676; x_wconf 96'>consideration</span>
|
||||
<span class='ocrx_word' id='word_1_72' title='bbox 587 659 608 676; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_73' title='bbox 617 659 715 681; x_wconf 96'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_74' title='bbox 724 665 735 677; x_wconf 96'>a</span>
|
||||
<span class='ocrx_word' id='word_1_75' title='bbox 743 661 806 681; x_wconf 96'>report</span>
|
||||
<span class='ocrx_word' id='word_1_76' title='bbox 811 660 858 678; x_wconf 96'>from</span>
|
||||
<p class='ocr_par' id='par_1_9' lang='eng' title="bbox 121 658 858 724">
|
||||
<span class='ocr_line' id='line_1_12' title="bbox 145 658 857 681; baseline 0.003 -7; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_70' title='bbox 145 658 155 674; x_wconf 92'>I</span>
|
||||
<span class='ocrx_word' id='word_1_71' title='bbox 162 659 250 675; x_wconf 92'>transmit</span>
|
||||
<span class='ocrx_word' id='word_1_72' title='bbox 261 658 357 681; x_wconf 94'>herewith,</span>
|
||||
<span class='ocrx_word' id='word_1_73' title='bbox 365 658 394 675; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_74' title='bbox 401 659 434 675; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_75' title='bbox 441 658 577 675; x_wconf 96'>consideration</span>
|
||||
<span class='ocrx_word' id='word_1_76' title='bbox 586 658 607 675; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_77' title='bbox 616 658 714 680; x_wconf 95'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_78' title='bbox 723 663 734 675; x_wconf 94'>a</span>
|
||||
<span class='ocrx_word' id='word_1_79' title='bbox 742 659 805 679; x_wconf 96'>report</span>
|
||||
<span class='ocrx_word' id='word_1_80' title='bbox 810 658 857 676; x_wconf 96'>from</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_13' title="bbox 122 678 858 704; baseline 0.008 -10; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_77' title='bbox 122 678 155 694; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_78' title='bbox 163 678 260 700; x_wconf 0'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_79' title='bbox 268 679 289 695; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_80' title='bbox 299 679 357 702; x_wconf 96'>State,</span>
|
||||
<span class='ocrx_word' id='word_1_81' title='bbox 366 680 403 696; x_wconf 95'>and</span>
|
||||
<span class='ocrx_word' id='word_1_82' title='bbox 411 680 444 697; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_83' title='bbox 457 681 524 701; x_wconf 96'>papers</span>
|
||||
<span class='ocrx_word' id='word_1_84' title='bbox 532 681 592 698; x_wconf 95'>which</span>
|
||||
<span class='ocrx_word' id='word_1_85' title='bbox 605 682 736 703; x_wconf 84'>accompanied</span>
|
||||
<span class='ocrx_word' id='word_1_86' title='bbox 744 682 765 704; x_wconf 93'>it,</span>
|
||||
<span class='ocrx_word' id='word_1_87' title='bbox 774 687 858 700; x_wconf 92'>concern-</span>
|
||||
<span class='ocr_line' id='line_1_13' title="bbox 121 680 858 703; baseline 0 -6; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_81' title='bbox 121 680 155 697; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_82' title='bbox 163 680 259 702; x_wconf 94'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_83' title='bbox 268 680 288 697; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_84' title='bbox 299 680 357 703; x_wconf 96'>State,</span>
|
||||
<span class='ocrx_word' id='word_1_85' title='bbox 366 681 403 697; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_86' title='bbox 410 681 444 698; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_87' title='bbox 456 681 524 701; x_wconf 95'>papers</span>
|
||||
<span class='ocrx_word' id='word_1_88' title='bbox 531 680 592 697; x_wconf 94'>which</span>
|
||||
<span class='ocrx_word' id='word_1_89' title='bbox 605 680 736 702; x_wconf 94'>accompanied</span>
|
||||
<span class='ocrx_word' id='word_1_90' title='bbox 744 680 765 702; x_wconf 93'>it,</span>
|
||||
<span class='ocrx_word' id='word_1_91' title='bbox 774 685 858 698; x_wconf 92'>concern-</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_14' title="bbox 122 700 835 726; baseline 0.007 -9; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_88' title='bbox 122 700 155 721; x_wconf 96'>ing</span>
|
||||
<span class='ocrx_word' id='word_1_89' title='bbox 163 700 277 721; x_wconf 96'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_90' title='bbox 285 701 314 718; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_91' title='bbox 321 702 354 719; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_92' title='bbox 361 702 446 719; x_wconf 96'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_93' title='bbox 453 703 516 720; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_94' title='bbox 524 703 546 720; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_95' title='bbox 552 704 583 720; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_96' title='bbox 591 704 661 721; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_97' title='bbox 669 704 732 721; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_98' title='bbox 740 704 759 721; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_99' title='bbox 768 705 835 726; x_wconf 94'>Japan.</span>
|
||||
<span class='ocr_line' id='line_1_14' title="bbox 122 702 835 724; baseline 0.001 -5; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_92' title='bbox 122 703 155 723; x_wconf 96'>ing</span>
|
||||
<span class='ocrx_word' id='word_1_93' title='bbox 163 702 277 723; x_wconf 96'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_94' title='bbox 285 702 314 719; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_95' title='bbox 321 703 354 720; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_96' title='bbox 361 703 446 720; x_wconf 96'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_97' title='bbox 453 703 516 720; x_wconf 95'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_98' title='bbox 524 703 546 720; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_99' title='bbox 552 704 583 720; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_100' title='bbox 591 703 661 720; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_101' title='bbox 669 703 732 720; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_102' title='bbox 740 702 759 719; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_103' title='bbox 768 703 835 724; x_wconf 90'>Japan.</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_10' lang='eng' title="bbox 682 726 835 745">
|
||||
<span class='ocr_line' id='line_1_15' title="bbox 682 726 835 745; baseline 0.007 -1; x_size 23.528408; x_descenders 5.5; x_ascenders 5.5">
|
||||
<span class='ocrx_word' id='word_1_100' title='bbox 682 726 705 744; x_wconf 85'>U.</span>
|
||||
<span class='ocrx_word' id='word_1_101' title='bbox 715 726 734 744; x_wconf 89'>8.</span>
|
||||
<span class='ocrx_word' id='word_1_102' title='bbox 743 727 835 745; x_wconf 80'>GRANT.</span>
|
||||
<p class='ocr_par' id='par_1_10' lang='eng' title="bbox 682 724 835 743">
|
||||
<span class='ocr_line' id='line_1_15' title="bbox 682 724 835 743; baseline 0 -1; x_size 23.573172; x_descenders 5.5365853; x_ascenders 5.5">
|
||||
<span class='ocrx_word' id='word_1_104' title='bbox 682 725 705 743; x_wconf 85'>U.</span>
|
||||
<span class='ocrx_word' id='word_1_105' title='bbox 715 724 734 743; x_wconf 89'>8.</span>
|
||||
<span class='ocrx_word' id='word_1_106' title='bbox 743 725 835 743; x_wconf 83'>GRANT.</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_11' lang='eng' title="bbox 144 744 482 769">
|
||||
<span class='ocr_line' id='line_1_16' title="bbox 144 744 482 769; baseline 0.006 -7; x_size 23; x_descenders 5; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_103' title='bbox 144 744 293 768; x_wconf 80'>‘WASHINGTON,</span>
|
||||
<span class='ocrx_word' id='word_1_104' title='bbox 302 745 385 767; x_wconf 96'>January</span>
|
||||
<span class='ocrx_word' id='word_1_105' title='bbox 393 747 422 769; x_wconf 93'>27,</span>
|
||||
<span class='ocrx_word' id='word_1_106' title='bbox 431 747 482 764; x_wconf 93'>1871.</span>
|
||||
<p class='ocr_par' id='par_1_11' lang='eng' title="bbox 144 746 482 770">
|
||||
<span class='ocr_line' id='line_1_16' title="bbox 144 746 482 770; baseline 0 -6; x_size 24; x_descenders 6; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_107' title='bbox 144 746 293 769; x_wconf 78'>‘WASHINGTON,</span>
|
||||
<span class='ocrx_word' id='word_1_108' title='bbox 302 746 385 768; x_wconf 96'>January</span>
|
||||
<span class='ocrx_word' id='word_1_109' title='bbox 393 748 422 770; x_wconf 92'>27,</span>
|
||||
<span class='ocrx_word' id='word_1_110' title='bbox 431 747 482 764; x_wconf 92'>1871.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_9' title="bbox 118 846 863 1226">
|
||||
<p class='ocr_par' id='par_1_12' lang='eng' title="bbox 442 846 833 893">
|
||||
<span class='ocr_line' id='line_1_17' title="bbox 442 846 709 870; baseline 0.007 -8; x_size 23; x_descenders 6; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_107' title='bbox 442 846 585 863; x_wconf 96'>DEPARTMENT</span>
|
||||
<span class='ocrx_word' id='word_1_108' title='bbox 598 850 623 864; x_wconf 96'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_109' title='bbox 635 847 709 870; x_wconf 95'>STATE,</span>
|
||||
<div class='ocr_carea' id='block_1_9' title="bbox 120 846 865 1225">
|
||||
<p class='ocr_par' id='par_1_12' lang='eng' title="bbox 443 846 834 891">
|
||||
<span class='ocr_line' id='line_1_17' title="bbox 443 846 710 869; baseline 0.004 -7; x_size 23; x_descenders 6; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_111' title='bbox 443 846 586 863; x_wconf 95'>DEPARTMENT</span>
|
||||
<span class='ocrx_word' id='word_1_112' title='bbox 599 849 624 863; x_wconf 96'>OF</span>
|
||||
<span class='ocrx_word' id='word_1_113' title='bbox 636 846 710 869; x_wconf 95'>STATE,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_18' title="bbox 445 868 833 893; baseline 0.008 -8; x_size 24; x_descenders 6; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_110' title='bbox 445 890 447 892; x_wconf 1'>.</span>
|
||||
<span class='ocrx_word' id='word_1_111' title='bbox 528 868 648 892; x_wconf 96'>Washington,</span>
|
||||
<span class='ocrx_word' id='word_1_112' title='bbox 656 869 739 891; x_wconf 96'>January</span>
|
||||
<span class='ocrx_word' id='word_1_113' title='bbox 747 870 774 893; x_wconf 95'>26,</span>
|
||||
<span class='ocrx_word' id='word_1_114' title='bbox 783 870 833 888; x_wconf 85'>1870,</span>
|
||||
<span class='ocr_line' id='line_1_18' title="bbox 529 868 834 891; baseline 0 -5; x_size 23.255997; x_descenders 5.2559972; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_114' title='bbox 529 868 649 891; x_wconf 95'>Washington,</span>
|
||||
<span class='ocrx_word' id='word_1_115' title='bbox 657 868 740 889; x_wconf 96'>January</span>
|
||||
<span class='ocrx_word' id='word_1_116' title='bbox 748 868 775 891; x_wconf 94'>26,</span>
|
||||
<span class='ocrx_word' id='word_1_117' title='bbox 784 868 834 886; x_wconf 85'>1870,</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_13' lang='eng' title="bbox 119 893 863 1050">
|
||||
<span class='ocr_line' id='line_1_19' title="bbox 145 893 856 915; baseline 0.006 -5; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_115' title='bbox 145 893 183 910; x_wconf 96'>The</span>
|
||||
<span class='ocrx_word' id='word_1_116' title='bbox 192 893 289 915; x_wconf 96'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_117' title='bbox 296 894 318 911; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_118' title='bbox 327 894 380 912; x_wconf 96'>State</span>
|
||||
<span class='ocrx_word' id='word_1_119' title='bbox 388 895 421 912; x_wconf 96'>has</span>
|
||||
<span class='ocrx_word' id='word_1_120' title='bbox 429 894 461 912; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_121' title='bbox 468 895 527 912; x_wconf 96'>honor</span>
|
||||
<span class='ocrx_word' id='word_1_122' title='bbox 534 897 554 912; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_123' title='bbox 563 896 632 913; x_wconf 96'>submit</span>
|
||||
<span class='ocrx_word' id='word_1_124' title='bbox 639 896 729 914; x_wconf 91'>herewith,</span>
|
||||
<span class='ocrx_word' id='word_1_125' title='bbox 738 897 767 914; x_wconf 91'>for</span>
|
||||
<span class='ocrx_word' id='word_1_126' title='bbox 775 897 856 914; x_wconf 96'>revision</span>
|
||||
<p class='ocr_par' id='par_1_13' lang='eng' title="bbox 121 894 865 1051">
|
||||
<span class='ocr_line' id='line_1_19' title="bbox 146 894 857 917; baseline 0 -5; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_118' title='bbox 146 895 184 912; x_wconf 96'>The</span>
|
||||
<span class='ocrx_word' id='word_1_119' title='bbox 193 895 290 917; x_wconf 96'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_120' title='bbox 297 895 319 912; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_121' title='bbox 328 895 381 913; x_wconf 96'>State</span>
|
||||
<span class='ocrx_word' id='word_1_122' title='bbox 389 896 422 913; x_wconf 96'>has</span>
|
||||
<span class='ocrx_word' id='word_1_123' title='bbox 430 894 462 912; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_124' title='bbox 469 895 528 912; x_wconf 96'>honor</span>
|
||||
<span class='ocrx_word' id='word_1_125' title='bbox 535 897 555 912; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_126' title='bbox 564 895 633 912; x_wconf 96'>submit</span>
|
||||
<span class='ocrx_word' id='word_1_127' title='bbox 640 895 730 913; x_wconf 90'>herewith,</span>
|
||||
<span class='ocrx_word' id='word_1_128' title='bbox 739 895 768 912; x_wconf 90'>for</span>
|
||||
<span class='ocrx_word' id='word_1_129' title='bbox 776 895 857 912; x_wconf 95'>revision</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_20' title="bbox 121 909 856 939; baseline 0.007 -7; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_127' title='bbox 121 915 147 937; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_128' title='bbox 159 915 257 938; x_wconf 96'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_129' title='bbox 265 916 284 933; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_130' title='bbox 293 917 402 938; x_wconf 96'>conformity</span>
|
||||
<span class='ocrx_word' id='word_1_131' title='bbox 411 917 455 934; x_wconf 96'>with</span>
|
||||
<span class='ocrx_word' id='word_1_132' title='bbox 463 917 495 934; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_133' title='bbox 504 918 606 939; x_wconf 96'>provisions</span>
|
||||
<span class='ocrx_word' id='word_1_134' title='bbox 614 918 635 935; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_135' title='bbox 645 919 714 936; x_wconf 96'>section</span>
|
||||
<span class='ocrx_word' id='word_1_136' title='bbox 723 909 735 936; x_wconf 91'>6</span>
|
||||
<span class='ocrx_word' id='word_1_137' title='bbox 748 919 769 936; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_138' title='bbox 778 920 811 937; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_139' title='bbox 825 921 856 937; x_wconf 96'>act</span>
|
||||
<span class='ocr_line' id='line_1_20' title="bbox 122 907 857 940; baseline 0 -5; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_130' title='bbox 122 918 148 939; x_wconf 95'>by</span>
|
||||
<span class='ocrx_word' id='word_1_131' title='bbox 160 917 258 940; x_wconf 96'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_132' title='bbox 266 918 285 935; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_133' title='bbox 294 918 403 939; x_wconf 96'>conformity</span>
|
||||
<span class='ocrx_word' id='word_1_134' title='bbox 412 917 456 935; x_wconf 96'>with</span>
|
||||
<span class='ocrx_word' id='word_1_135' title='bbox 464 917 496 934; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_136' title='bbox 505 918 607 939; x_wconf 96'>provisions</span>
|
||||
<span class='ocrx_word' id='word_1_137' title='bbox 615 917 636 934; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_138' title='bbox 646 918 715 935; x_wconf 97'>section</span>
|
||||
<span class='ocrx_word' id='word_1_139' title='bbox 724 907 736 934; x_wconf 92'>6</span>
|
||||
<span class='ocrx_word' id='word_1_140' title='bbox 749 917 770 934; x_wconf 94'>of</span>
|
||||
<span class='ocrx_word' id='word_1_141' title='bbox 779 918 812 935; x_wconf 94'>the</span>
|
||||
<span class='ocrx_word' id='word_1_142' title='bbox 826 919 857 935; x_wconf 96'>act</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_21' title="bbox 120 938 856 962; baseline 0.007 -8; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_140' title='bbox 120 938 216 959; x_wconf 95'>approved</span>
|
||||
<span class='ocrx_word' id='word_1_141' title='bbox 228 938 264 955; x_wconf 95'>22d</span>
|
||||
<span class='ocrx_word' id='word_1_142' title='bbox 277 938 298 956; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_143' title='bbox 312 939 367 961; x_wconf 96'>June,</span>
|
||||
<span class='ocrx_word' id='word_1_144' title='bbox 382 939 431 962; x_wconf 72'>1860,</span>
|
||||
<span class='ocrx_word' id='word_1_145' title='bbox 440 944 452 956; x_wconf 72'>a</span>
|
||||
<span class='ocrx_word' id='word_1_146' title='bbox 465 944 512 961; x_wconf 96'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_147' title='bbox 524 940 545 957; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_148' title='bbox 554 940 685 962; x_wconf 80'>“regulations</span>
|
||||
<span class='ocrx_word' id='word_1_149' title='bbox 692 941 721 958; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_150' title='bbox 729 942 761 958; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_151' title='bbox 769 942 856 959; x_wconf 96'>consular</span>
|
||||
<span class='ocr_line' id='line_1_21' title="bbox 121 939 857 962; baseline -0.001 -5; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_143' title='bbox 121 940 217 961; x_wconf 96'>approved</span>
|
||||
<span class='ocrx_word' id='word_1_144' title='bbox 229 940 265 957; x_wconf 95'>22d</span>
|
||||
<span class='ocrx_word' id='word_1_145' title='bbox 278 939 299 957; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_146' title='bbox 313 940 368 962; x_wconf 96'>June,</span>
|
||||
<span class='ocrx_word' id='word_1_147' title='bbox 383 940 432 962; x_wconf 57'>1860,</span>
|
||||
<span class='ocrx_word' id='word_1_148' title='bbox 441 944 453 956; x_wconf 57'>a</span>
|
||||
<span class='ocrx_word' id='word_1_149' title='bbox 466 944 513 961; x_wconf 96'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_150' title='bbox 525 940 546 957; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_151' title='bbox 555 940 686 961; x_wconf 82'>“regulations</span>
|
||||
<span class='ocrx_word' id='word_1_152' title='bbox 693 940 722 957; x_wconf 95'>for</span>
|
||||
<span class='ocrx_word' id='word_1_153' title='bbox 730 940 762 956; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_154' title='bbox 770 940 857 957; x_wconf 95'>consular</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_22' title="bbox 120 960 856 985; baseline 0.005 -8; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_152' title='bbox 120 961 183 977; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_153' title='bbox 197 960 218 977; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_154' title='bbox 227 961 260 977; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_155' title='bbox 271 961 341 978; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_156' title='bbox 355 961 418 979; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_157' title='bbox 429 962 449 979; x_wconf 94'>in</span>
|
||||
<span class='ocrx_word' id='word_1_158' title='bbox 464 962 543 983; x_wconf 96'>Japan,”</span>
|
||||
<span class='ocrx_word' id='word_1_159' title='bbox 555 963 632 980; x_wconf 96'>decreed</span>
|
||||
<span class='ocrx_word' id='word_1_160' title='bbox 644 964 682 980; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_161' title='bbox 694 963 758 981; x_wconf 96'>issued</span>
|
||||
<span class='ocrx_word' id='word_1_162' title='bbox 771 964 796 985; x_wconf 93'>by</span>
|
||||
<span class='ocrx_word' id='word_1_163' title='bbox 805 964 825 981; x_wconf 88'>C.</span>
|
||||
<span class='ocrx_word' id='word_1_164' title='bbox 834 964 856 981; x_wconf 70'>E.</span>
|
||||
<span class='ocr_line' id='line_1_22' title="bbox 121 962 857 983; baseline -0.001 -3; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_155' title='bbox 121 963 184 980; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_156' title='bbox 198 962 219 979; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_157' title='bbox 228 963 261 979; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_158' title='bbox 272 962 342 980; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_159' title='bbox 356 962 419 980; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_160' title='bbox 430 962 450 979; x_wconf 95'>in</span>
|
||||
<span class='ocrx_word' id='word_1_161' title='bbox 465 962 544 983; x_wconf 95'>Japan,”</span>
|
||||
<span class='ocrx_word' id='word_1_162' title='bbox 556 962 633 979; x_wconf 96'>decreed</span>
|
||||
<span class='ocrx_word' id='word_1_163' title='bbox 645 963 683 979; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_164' title='bbox 695 962 759 980; x_wconf 93'>issued</span>
|
||||
<span class='ocrx_word' id='word_1_165' title='bbox 772 962 797 983; x_wconf 92'>by</span>
|
||||
<span class='ocrx_word' id='word_1_166' title='bbox 806 962 826 979; x_wconf 81'>C.</span>
|
||||
<span class='ocrx_word' id='word_1_167' title='bbox 835 962 857 979; x_wconf 47'>BE.</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_23' title="bbox 120 982 856 1008; baseline 0.007 -9; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_165' title='bbox 120 982 150 999; x_wconf 96'>De</span>
|
||||
<span class='ocrx_word' id='word_1_166' title='bbox 156 982 215 1005; x_wconf 96'>Long,</span>
|
||||
<span class='ocrx_word' id='word_1_167' title='bbox 224 983 256 1000; x_wconf 93'>the</span>
|
||||
<span class='ocrx_word' id='word_1_168' title='bbox 264 984 348 1001; x_wconf 91'>miniater</span>
|
||||
<span class='ocrx_word' id='word_1_169' title='bbox 359 984 381 1001; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_170' title='bbox 389 984 421 1001; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_171' title='bbox 429 984 499 1001; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_172' title='bbox 507 985 570 1002; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_173' title='bbox 577 985 595 1002; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_174' title='bbox 604 985 646 1003; x_wconf 96'>that</span>
|
||||
<span class='ocrx_word' id='word_1_175' title='bbox 654 987 738 1008; x_wconf 96'>country,</span>
|
||||
<span class='ocrx_word' id='word_1_176' title='bbox 747 986 766 1003; x_wconf 93'>in</span>
|
||||
<span class='ocrx_word' id='word_1_177' title='bbox 775 986 856 1007; x_wconf 93'>Septem-</span>
|
||||
<span class='ocr_line' id='line_1_23' title="bbox 122 984 858 1007; baseline 0 -6; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_168' title='bbox 122 985 152 1001; x_wconf 96'>De</span>
|
||||
<span class='ocrx_word' id='word_1_169' title='bbox 158 984 217 1007; x_wconf 96'>Long,</span>
|
||||
<span class='ocrx_word' id='word_1_170' title='bbox 226 985 258 1002; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_171' title='bbox 266 985 350 1002; x_wconf 96'>minister</span>
|
||||
<span class='ocrx_word' id='word_1_172' title='bbox 361 985 383 1002; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_173' title='bbox 391 985 423 1002; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_174' title='bbox 431 984 501 1001; x_wconf 97'>United</span>
|
||||
<span class='ocrx_word' id='word_1_175' title='bbox 509 985 572 1002; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_176' title='bbox 579 984 597 1001; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_177' title='bbox 606 984 648 1002; x_wconf 96'>that</span>
|
||||
<span class='ocrx_word' id='word_1_178' title='bbox 656 986 740 1006; x_wconf 96'>country,</span>
|
||||
<span class='ocrx_word' id='word_1_179' title='bbox 749 984 768 1001; x_wconf 92'>in</span>
|
||||
<span class='ocrx_word' id='word_1_180' title='bbox 777 984 858 1005; x_wconf 91'>Septem-</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_24' title="bbox 119 1004 863 1040; baseline 0.007 -19; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_178' title='bbox 119 1004 158 1026; x_wconf 93'>ber,</span>
|
||||
<span class='ocrx_word' id='word_1_179' title='bbox 167 1005 221 1027; x_wconf 88'>1870;</span>
|
||||
<span class='ocrx_word' id='word_1_180' title='bbox 234 1006 271 1022; x_wconf 87'>and</span>
|
||||
<span class='ocrx_word' id='word_1_181' title='bbox 285 1006 324 1023; x_wconf 87'>also</span>
|
||||
<span class='ocrx_word' id='word_1_182' title='bbox 337 1006 369 1023; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_183' title='bbox 381 1011 448 1028; x_wconf 96'>papers</span>
|
||||
<span class='ocrx_word' id='word_1_184' title='bbox 459 1007 566 1024; x_wconf 96'>mentioned</span>
|
||||
<span class='ocrx_word' id='word_1_185' title='bbox 574 1007 593 1024; x_wconf 94'>in</span>
|
||||
<span class='ocrx_word' id='word_1_186' title='bbox 602 1008 633 1025; x_wconf 93'>the</span>
|
||||
<span class='ocrx_word' id='word_1_187' title='bbox 641 1008 739 1030; x_wconf 92'>subjoined</span>
|
||||
<span class='ocrx_word' id='word_1_188' title='bbox 746 1008 784 1030; x_wconf 97'>list,</span>
|
||||
<span class='ocrx_word' id='word_1_189' title='bbox 782 1005 863 1040; x_wconf 86'>which,</span>
|
||||
<span class='ocr_line' id='line_1_24' title="bbox 121 1006 865 1034; baseline 0 -11; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_181' title='bbox 121 1007 160 1028; x_wconf 91'>ber,</span>
|
||||
<span class='ocrx_word' id='word_1_182' title='bbox 169 1007 223 1029; x_wconf 95'>1870;</span>
|
||||
<span class='ocrx_word' id='word_1_183' title='bbox 236 1008 273 1024; x_wconf 84'>and</span>
|
||||
<span class='ocrx_word' id='word_1_184' title='bbox 287 1007 326 1024; x_wconf 95'>also</span>
|
||||
<span class='ocrx_word' id='word_1_185' title='bbox 339 1007 371 1024; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_186' title='bbox 383 1011 450 1029; x_wconf 96'>papers</span>
|
||||
<span class='ocrx_word' id='word_1_187' title='bbox 461 1007 568 1024; x_wconf 96'>mentioned</span>
|
||||
<span class='ocrx_word' id='word_1_188' title='bbox 576 1006 595 1023; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_189' title='bbox 604 1007 635 1024; x_wconf 93'>the</span>
|
||||
<span class='ocrx_word' id='word_1_190' title='bbox 643 1007 741 1029; x_wconf 92'>subjoined</span>
|
||||
<span class='ocrx_word' id='word_1_191' title='bbox 748 1006 786 1028; x_wconf 96'>list,</span>
|
||||
<span class='ocrx_word' id='word_1_192' title='bbox 794 1007 865 1034; x_wconf 86'>which,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_25' title="bbox 120 1027 555 1050; baseline 0.007 -7; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_190' title='bbox 120 1027 195 1044; x_wconf 96'>contain</span>
|
||||
<span class='ocrx_word' id='word_1_191' title='bbox 203 1028 322 1049; x_wconf 96'>suggestions</span>
|
||||
<span class='ocrx_word' id='word_1_192' title='bbox 330 1033 353 1045; x_wconf 95'>on</span>
|
||||
<span class='ocrx_word' id='word_1_193' title='bbox 361 1028 392 1045; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_194' title='bbox 400 1029 471 1050; x_wconf 96'>subject</span>
|
||||
<span class='ocrx_word' id='word_1_195' title='bbox 478 1029 555 1046; x_wconf 86'>thereof.</span>
|
||||
<span class='ocr_line' id='line_1_25' title="bbox 122 1029 557 1051; baseline 0 -5; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_193' title='bbox 122 1029 197 1046; x_wconf 96'>contain</span>
|
||||
<span class='ocrx_word' id='word_1_194' title='bbox 205 1029 324 1051; x_wconf 96'>suggestions</span>
|
||||
<span class='ocrx_word' id='word_1_195' title='bbox 332 1034 355 1046; x_wconf 96'>on</span>
|
||||
<span class='ocrx_word' id='word_1_196' title='bbox 363 1029 394 1046; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_197' title='bbox 402 1029 473 1050; x_wconf 93'>subject</span>
|
||||
<span class='ocrx_word' id='word_1_198' title='bbox 480 1029 557 1046; x_wconf 85'>thereof.</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_14' lang='eng' title="bbox 118 1050 854 1185">
|
||||
<span class='ocr_line' id='line_1_26' title="bbox 142 1050 853 1076; baseline 0.007 -11; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_196' title='bbox 142 1050 162 1065; x_wconf 96'>A</span>
|
||||
<span class='ocrx_word' id='word_1_197' title='bbox 169 1054 216 1071; x_wconf 96'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_198' title='bbox 224 1050 245 1066; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_199' title='bbox 251 1050 323 1067; x_wconf 81'>Article</span>
|
||||
<span class='ocrx_word' id='word_1_200' title='bbox 330 1050 397 1067; x_wconf 77'>XXVI</span>
|
||||
<span class='ocrx_word' id='word_1_201' title='bbox 405 1051 425 1068; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_202' title='bbox 431 1051 462 1068; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_203' title='bbox 470 1052 556 1068; x_wconf 94'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_204' title='bbox 560 1052 674 1073; x_wconf 96'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_205' title='bbox 680 1053 696 1069; x_wconf 94'>is</span>
|
||||
<span class='ocrx_word' id='word_1_206' title='bbox 701 1053 740 1070; x_wconf 96'>also</span>
|
||||
<span class='ocrx_word' id='word_1_207' title='bbox 747 1053 853 1076; x_wconf 96'>submitted,</span>
|
||||
<p class='ocr_par' id='par_1_14' lang='eng' title="bbox 120 1051 857 1185">
|
||||
<span class='ocr_line' id='line_1_26' title="bbox 144 1051 855 1074; baseline -0.001 -6; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_199' title='bbox 144 1052 164 1067; x_wconf 95'>A</span>
|
||||
<span class='ocrx_word' id='word_1_200' title='bbox 171 1056 218 1073; x_wconf 95'>copy</span>
|
||||
<span class='ocrx_word' id='word_1_201' title='bbox 226 1052 247 1068; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_202' title='bbox 253 1051 325 1068; x_wconf 93'>Article</span>
|
||||
<span class='ocrx_word' id='word_1_203' title='bbox 332 1051 399 1068; x_wconf 86'>XXVI</span>
|
||||
<span class='ocrx_word' id='word_1_204' title='bbox 407 1052 427 1069; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_205' title='bbox 433 1051 464 1068; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_206' title='bbox 472 1052 558 1068; x_wconf 95'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_207' title='bbox 562 1051 676 1072; x_wconf 95'>regulations</span>
|
||||
<span class='ocrx_word' id='word_1_208' title='bbox 682 1052 698 1068; x_wconf 96'>is</span>
|
||||
<span class='ocrx_word' id='word_1_209' title='bbox 703 1052 742 1068; x_wconf 94'>also</span>
|
||||
<span class='ocrx_word' id='word_1_210' title='bbox 749 1051 855 1074; x_wconf 95'>submitted,</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_27' title="bbox 119 1071 854 1097; baseline 0.007 -9; x_size 21; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_208' title='bbox 119 1071 156 1088; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_209' title='bbox 169 1071 202 1088; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_210' title='bbox 216 1072 313 1094; x_wconf 96'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_211' title='bbox 319 1073 340 1089; x_wconf 90'>of</span>
|
||||
<span class='ocrx_word' id='word_1_212' title='bbox 349 1073 402 1090; x_wconf 96'>State</span>
|
||||
<span class='ocrx_word' id='word_1_213' title='bbox 413 1073 532 1095; x_wconf 96'>respectfully</span>
|
||||
<span class='ocrx_word' id='word_1_214' title='bbox 540 1075 632 1097; x_wconf 96'>suggests,</span>
|
||||
<span class='ocrx_word' id='word_1_215' title='bbox 641 1075 670 1091; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_216' title='bbox 677 1075 710 1092; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_217' title='bbox 718 1074 854 1093; x_wconf 96'>consideration</span>
|
||||
<span class='ocr_line' id='line_1_27' title="bbox 121 1072 856 1096; baseline 0 -5; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_211' title='bbox 121 1073 158 1091; x_wconf 95'>and</span>
|
||||
<span class='ocrx_word' id='word_1_212' title='bbox 171 1073 204 1090; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_213' title='bbox 218 1074 315 1095; x_wconf 96'>Secretary</span>
|
||||
<span class='ocrx_word' id='word_1_214' title='bbox 321 1074 342 1090; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_215' title='bbox 351 1074 404 1091; x_wconf 96'>State</span>
|
||||
<span class='ocrx_word' id='word_1_216' title='bbox 415 1073 534 1095; x_wconf 96'>respectfully</span>
|
||||
<span class='ocrx_word' id='word_1_217' title='bbox 542 1074 634 1096; x_wconf 96'>suggests,</span>
|
||||
<span class='ocrx_word' id='word_1_218' title='bbox 643 1074 672 1090; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_219' title='bbox 679 1074 712 1091; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_220' title='bbox 720 1072 856 1091; x_wconf 96'>consideration</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_28' title="bbox 118 1093 852 1118; baseline 0.005 -8; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_218' title='bbox 118 1093 140 1110; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_219' title='bbox 149 1093 246 1116; x_wconf 94'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_220' title='bbox 255 1095 287 1111; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_221' title='bbox 300 1095 395 1117; x_wconf 96'>propriety</span>
|
||||
<span class='ocrx_word' id='word_1_222' title='bbox 406 1096 427 1112; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_223' title='bbox 435 1096 516 1117; x_wconf 96'>limiting</span>
|
||||
<span class='ocrx_word' id='word_1_224' title='bbox 528 1095 560 1113; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_225' title='bbox 571 1101 633 1118; x_wconf 96'>power</span>
|
||||
<span class='ocrx_word' id='word_1_226' title='bbox 641 1097 662 1114; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_227' title='bbox 671 1097 764 1114; x_wconf 96'>ministers</span>
|
||||
<span class='ocrx_word' id='word_1_228' title='bbox 772 1089 799 1122; x_wconf 95'>to</span>
|
||||
<span class='ocrx_word' id='word_1_229' title='bbox 798 1097 851 1115; x_wconf 95'>make</span>
|
||||
<span class='ocr_line' id='line_1_28' title="bbox 120 1095 854 1118; baseline -0.001 -5; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_221' title='bbox 120 1095 142 1113; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_222' title='bbox 151 1095 248 1118; x_wconf 96'>Congress,</span>
|
||||
<span class='ocrx_word' id='word_1_223' title='bbox 257 1097 289 1113; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_224' title='bbox 302 1096 397 1118; x_wconf 96'>propriety</span>
|
||||
<span class='ocrx_word' id='word_1_225' title='bbox 408 1096 429 1113; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_226' title='bbox 437 1096 518 1117; x_wconf 96'>limiting</span>
|
||||
<span class='ocrx_word' id='word_1_227' title='bbox 530 1095 562 1113; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_228' title='bbox 573 1100 635 1117; x_wconf 96'>power</span>
|
||||
<span class='ocrx_word' id='word_1_229' title='bbox 643 1096 664 1113; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_230' title='bbox 673 1096 766 1113; x_wconf 96'>ministers</span>
|
||||
<span class='ocrx_word' id='word_1_231' title='bbox 774 1091 801 1122; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_232' title='bbox 800 1095 854 1113; x_wconf 96'>make</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_29' title="bbox 119 1115 853 1141; baseline 0.007 -9; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_230' title='bbox 119 1115 194 1133; x_wconf 88'>decrees</span>
|
||||
<span class='ocrx_word' id='word_1_231' title='bbox 206 1116 243 1133; x_wconf 88'>and</span>
|
||||
<span class='ocrx_word' id='word_1_232' title='bbox 248 1116 358 1139; x_wconf 96'>regulation,</span>
|
||||
<span class='ocrx_word' id='word_1_233' title='bbox 367 1117 385 1134; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_234' title='bbox 393 1118 425 1135; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_235' title='bbox 433 1122 486 1135; x_wconf 96'>sense</span>
|
||||
<span class='ocrx_word' id='word_1_236' title='bbox 493 1118 513 1135; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_237' title='bbox 521 1118 581 1136; x_wconf 96'>which</span>
|
||||
<span class='ocrx_word' id='word_1_238' title='bbox 589 1119 605 1136; x_wconf 96'>it</span>
|
||||
<span class='ocrx_word' id='word_1_239' title='bbox 612 1119 629 1136; x_wconf 96'>is</span>
|
||||
<span class='ocrx_word' id='word_1_240' title='bbox 636 1118 708 1136; x_wconf 95'>limited</span>
|
||||
<span class='ocrx_word' id='word_1_241' title='bbox 716 1120 741 1141; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_242' title='bbox 747 1120 853 1141; x_wconf 96'>paragraph</span>
|
||||
<span class='ocr_line' id='line_1_29' title="bbox 121 1117 856 1140; baseline 0 -6; x_size 22; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_233' title='bbox 121 1118 197 1135; x_wconf 95'>decrees</span>
|
||||
<span class='ocrx_word' id='word_1_234' title='bbox 208 1118 246 1135; x_wconf 94'>and</span>
|
||||
<span class='ocrx_word' id='word_1_235' title='bbox 250 1117 361 1140; x_wconf 94'>regulation,</span>
|
||||
<span class='ocrx_word' id='word_1_236' title='bbox 369 1118 388 1135; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_237' title='bbox 395 1119 428 1136; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_238' title='bbox 435 1122 489 1135; x_wconf 96'>sense</span>
|
||||
<span class='ocrx_word' id='word_1_239' title='bbox 495 1118 516 1135; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_240' title='bbox 523 1118 584 1136; x_wconf 96'>which</span>
|
||||
<span class='ocrx_word' id='word_1_241' title='bbox 591 1118 608 1135; x_wconf 96'>it</span>
|
||||
<span class='ocrx_word' id='word_1_242' title='bbox 614 1118 632 1135; x_wconf 96'>is</span>
|
||||
<span class='ocrx_word' id='word_1_243' title='bbox 638 1117 711 1135; x_wconf 95'>limited</span>
|
||||
<span class='ocrx_word' id='word_1_244' title='bbox 718 1118 743 1139; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_245' title='bbox 750 1118 856 1139; x_wconf 96'>paragraph</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_30' title="bbox 119 1138 854 1164; baseline 0.007 -10; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_243' title='bbox 119 1138 153 1154; x_wconf 94'>431</span>
|
||||
<span class='ocrx_word' id='word_1_244' title='bbox 161 1138 183 1155; x_wconf 95'>of</span>
|
||||
<span class='ocrx_word' id='word_1_245' title='bbox 192 1139 224 1155; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_246' title='bbox 232 1139 297 1156; x_wconf 96'>article</span>
|
||||
<span class='ocrx_word' id='word_1_247' title='bbox 304 1139 366 1157; x_wconf 93'>before</span>
|
||||
<span class='ocrx_word' id='word_1_248' title='bbox 374 1140 505 1157; x_wconf 91'>named—that</span>
|
||||
<span class='ocrx_word' id='word_1_249' title='bbox 513 1141 534 1161; x_wconf 96'>is,</span>
|
||||
<span class='ocrx_word' id='word_1_250' title='bbox 544 1141 579 1158; x_wconf 87'>“to</span>
|
||||
<span class='ocrx_word' id='word_1_251' title='bbox 588 1142 628 1158; x_wconf 96'>acts</span>
|
||||
<span class='ocrx_word' id='word_1_252' title='bbox 635 1143 757 1164; x_wconf 95'>necessary</span>
|
||||
<span class='ocrx_word' id='word_1_253' title='bbox 732 1134 761 1168; x_wconf 95'>to</span>
|
||||
<span class='ocrx_word' id='word_1_254' title='bbox 767 1142 854 1164; x_wconf 96'>organize</span>
|
||||
<span class='ocr_line' id='line_1_30' title="bbox 122 1140 857 1162; baseline 0 -5; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_246' title='bbox 122 1140 156 1157; x_wconf 96'>431</span>
|
||||
<span class='ocrx_word' id='word_1_247' title='bbox 164 1140 186 1157; x_wconf 97'>of</span>
|
||||
<span class='ocrx_word' id='word_1_248' title='bbox 195 1141 227 1157; x_wconf 95'>the</span>
|
||||
<span class='ocrx_word' id='word_1_249' title='bbox 235 1140 300 1158; x_wconf 95'>article</span>
|
||||
<span class='ocrx_word' id='word_1_250' title='bbox 307 1140 369 1158; x_wconf 93'>before</span>
|
||||
<span class='ocrx_word' id='word_1_251' title='bbox 377 1140 508 1158; x_wconf 92'>named—that</span>
|
||||
<span class='ocrx_word' id='word_1_252' title='bbox 516 1141 537 1161; x_wconf 96'>is,</span>
|
||||
<span class='ocrx_word' id='word_1_253' title='bbox 547 1141 582 1158; x_wconf 85'>“to</span>
|
||||
<span class='ocrx_word' id='word_1_254' title='bbox 591 1141 631 1157; x_wconf 96'>acts</span>
|
||||
<span class='ocrx_word' id='word_1_255' title='bbox 638 1141 760 1162; x_wconf 95'>necessary</span>
|
||||
<span class='ocrx_word' id='word_1_256' title='bbox 738 1136 762 1167; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_257' title='bbox 770 1140 857 1162; x_wconf 96'>organize</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_31' title="bbox 118 1160 659 1185; baseline 0.007 -8; x_size 23; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_255' title='bbox 118 1160 156 1177; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_256' title='bbox 165 1160 207 1182; x_wconf 96'>give</span>
|
||||
<span class='ocrx_word' id='word_1_257' title='bbox 215 1161 309 1183; x_wconf 95'>efficiency</span>
|
||||
<span class='ocrx_word' id='word_1_258' title='bbox 317 1163 337 1179; x_wconf 95'>to</span>
|
||||
<span class='ocrx_word' id='word_1_259' title='bbox 345 1162 377 1179; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_260' title='bbox 385 1164 446 1180; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_261' title='bbox 455 1163 530 1180; x_wconf 96'>created</span>
|
||||
<span class='ocrx_word' id='word_1_262' title='bbox 536 1163 561 1185; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_263' title='bbox 571 1163 604 1181; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_264' title='bbox 612 1164 659 1181; x_wconf 94'>act.”</span>
|
||||
<span class='ocr_line' id='line_1_31' title="bbox 121 1162 662 1185; baseline 0.002 -6; x_size 22; x_descenders 4; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_258' title='bbox 121 1162 159 1180; x_wconf 96'>and</span>
|
||||
<span class='ocrx_word' id='word_1_259' title='bbox 168 1162 210 1184; x_wconf 97'>give</span>
|
||||
<span class='ocrx_word' id='word_1_260' title='bbox 218 1163 312 1184; x_wconf 96'>efficiency</span>
|
||||
<span class='ocrx_word' id='word_1_261' title='bbox 320 1164 340 1180; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_262' title='bbox 348 1163 380 1180; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_263' title='bbox 388 1164 449 1181; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_264' title='bbox 458 1163 533 1180; x_wconf 96'>created</span>
|
||||
<span class='ocrx_word' id='word_1_265' title='bbox 539 1163 564 1185; x_wconf 96'>by</span>
|
||||
<span class='ocrx_word' id='word_1_266' title='bbox 574 1162 607 1180; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_267' title='bbox 615 1163 662 1180; x_wconf 96'>act.”</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_15' lang='eng' title="bbox 141 1183 555 1205">
|
||||
<span class='ocr_line' id='line_1_32' title="bbox 141 1183 555 1205; baseline 0.007 -6; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_265' title='bbox 141 1183 268 1205; x_wconf 34'>Respectfully</span>
|
||||
<span class='ocrx_word' id='word_1_266' title='bbox 276 1183 383 1201; x_wconf 93'>submitted.</span>
|
||||
<span class='ocrx_word' id='word_1_267' title='bbox 553 1194 555 1196; x_wconf 0'>.</span>
|
||||
<p class='ocr_par' id='par_1_15' lang='eng' title="bbox 144 1184 386 1207">
|
||||
<span class='ocr_line' id='line_1_32' title="bbox 144 1184 386 1207; baseline 0 -5; x_size 23; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_268' title='bbox 144 1185 271 1207; x_wconf 86'>Respectfully</span>
|
||||
<span class='ocrx_word' id='word_1_269' title='bbox 279 1184 386 1202; x_wconf 93'>submitted.</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p class='ocr_par' id='par_1_16' lang='eng' title="bbox 622 1208 831 1226">
|
||||
<span class='ocr_line' id='line_1_33' title="bbox 622 1208 831 1226; baseline 0.005 -1; x_size 23.623137; x_descenders 5.52807; x_ascenders 5.5594797">
|
||||
<span class='ocrx_word' id='word_1_268' title='bbox 622 1208 757 1226; x_wconf 96'>HAMILTON</span>
|
||||
<span class='ocrx_word' id='word_1_269' title='bbox 765 1209 831 1226; x_wconf 96'>FISH.</span>
|
||||
<p class='ocr_par' id='par_1_16' lang='eng' title="bbox 625 1206 834 1225">
|
||||
<span class='ocr_line' id='line_1_33' title="bbox 625 1206 834 1225; baseline -0.005 0; x_size 23.69949; x_descenders 5.5158105; x_ascenders 5.590498">
|
||||
<span class='ocrx_word' id='word_1_270' title='bbox 625 1206 760 1225; x_wconf 96'>HAMILTON</span>
|
||||
<span class='ocrx_word' id='word_1_271' title='bbox 768 1207 834 1224; x_wconf 95'>FISH.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_10' title="bbox 140 1227 314 1246">
|
||||
<p class='ocr_par' id='par_1_17' lang='eng' title="bbox 140 1227 314 1246">
|
||||
<span class='ocr_line' id='line_1_34' title="bbox 140 1227 314 1246; baseline 0.011 -2; x_size 22.296295; x_descenders 5.2962961; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_270' title='bbox 140 1227 180 1244; x_wconf 96'>The</span>
|
||||
<span class='ocrx_word' id='word_1_271' title='bbox 188 1228 314 1246; x_wconf 81'>PRESIDENT,</span>
|
||||
<div class='ocr_carea' id='block_1_10' title="bbox 143 1229 317 1247">
|
||||
<p class='ocr_par' id='par_1_17' lang='eng' title="bbox 143 1229 317 1247">
|
||||
<span class='ocr_line' id='line_1_34' title="bbox 143 1229 317 1247; baseline 0.006 -1; x_size 22.296295; x_descenders 5.2962961; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_272' title='bbox 143 1229 183 1246; x_wconf 96'>The</span>
|
||||
<span class='ocrx_word' id='word_1_273' title='bbox 191 1230 317 1247; x_wconf 74'>PRESIDENT,</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_11' title="bbox 341 1307 628 1331">
|
||||
<p class='ocr_par' id='par_1_18' lang='eng' title="bbox 341 1307 628 1331">
|
||||
<span class='ocr_line' id='line_1_35' title="bbox 341 1307 628 1331; baseline 0.007 -7; x_size 23; x_descenders 5; x_ascenders 5">
|
||||
<span class='ocrx_word' id='word_1_272' title='bbox 341 1307 383 1324; x_wconf 95'>List</span>
|
||||
<span class='ocrx_word' id='word_1_273' title='bbox 389 1307 411 1330; x_wconf 92'>of</span>
|
||||
<span class='ocrx_word' id='word_1_274' title='bbox 419 1308 553 1330; x_wconf 90'>accompanying</span>
|
||||
<span class='ocrx_word' id='word_1_275' title='bbox 557 1313 628 1331; x_wconf 89'>papers.</span>
|
||||
<div class='ocr_carea' id='block_1_11' title="bbox 345 1308 632 1331">
|
||||
<p class='ocr_par' id='par_1_18' lang='eng' title="bbox 345 1308 632 1331">
|
||||
<span class='ocr_line' id='line_1_35' title="bbox 345 1308 632 1331; baseline 0 -6; x_size 22; x_descenders 5; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_274' title='bbox 345 1308 387 1325; x_wconf 91'>List</span>
|
||||
<span class='ocrx_word' id='word_1_275' title='bbox 393 1308 415 1331; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_276' title='bbox 423 1308 557 1330; x_wconf 96'>accompanying</span>
|
||||
<span class='ocrx_word' id='word_1_277' title='bbox 561 1312 632 1331; x_wconf 87'>papers.</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_12' title="bbox 138 1337 853 1395">
|
||||
<p class='ocr_par' id='par_1_19' lang='eng' title="bbox 138 1337 853 1395">
|
||||
<span class='ocr_line' id='line_1_36' title="bbox 138 1337 853 1372; baseline 0.007 -10; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_276' title='bbox 138 1346 155 1363; x_wconf 96'>1,</span>
|
||||
<span class='ocrx_word' id='word_1_277' title='bbox 166 1346 289 1368; x_wconf 96'>Regulations</span>
|
||||
<span class='ocrx_word' id='word_1_278' title='bbox 296 1337 325 1364; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_279' title='bbox 334 1339 366 1365; x_wconf 97'>the</span>
|
||||
<span class='ocrx_word' id='word_1_280' title='bbox 374 1348 459 1366; x_wconf 96'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_281' title='bbox 466 1350 529 1366; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_282' title='bbox 537 1349 558 1366; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_283' title='bbox 566 1349 599 1366; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_284' title='bbox 607 1349 678 1367; x_wconf 96'>United</span>
|
||||
<span class='ocrx_word' id='word_1_285' title='bbox 686 1349 749 1367; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_286' title='bbox 757 1349 777 1367; x_wconf 96'>in</span>
|
||||
<span class='ocrx_word' id='word_1_287' title='bbox 784 1350 853 1372; x_wconf 96'>Japan.</span>
|
||||
<div class='ocr_carea' id='block_1_12' title="bbox 142 1340 857 1393">
|
||||
<p class='ocr_par' id='par_1_19' lang='eng' title="bbox 142 1340 857 1393">
|
||||
<span class='ocr_line' id='line_1_36' title="bbox 142 1340 857 1370; baseline 0 -5; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_278' title='bbox 142 1348 159 1365; x_wconf 96'>1,</span>
|
||||
<span class='ocrx_word' id='word_1_279' title='bbox 170 1348 293 1370; x_wconf 96'>Regulations</span>
|
||||
<span class='ocrx_word' id='word_1_280' title='bbox 300 1348 329 1365; x_wconf 96'>for</span>
|
||||
<span class='ocrx_word' id='word_1_281' title='bbox 338 1340 370 1366; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_282' title='bbox 378 1348 463 1366; x_wconf 96'>consular</span>
|
||||
<span class='ocrx_word' id='word_1_283' title='bbox 470 1350 533 1366; x_wconf 96'>courts</span>
|
||||
<span class='ocrx_word' id='word_1_284' title='bbox 541 1349 562 1366; x_wconf 96'>of</span>
|
||||
<span class='ocrx_word' id='word_1_285' title='bbox 570 1348 603 1365; x_wconf 96'>the</span>
|
||||
<span class='ocrx_word' id='word_1_286' title='bbox 611 1348 682 1366; x_wconf 95'>United</span>
|
||||
<span class='ocrx_word' id='word_1_287' title='bbox 690 1348 753 1366; x_wconf 96'>States</span>
|
||||
<span class='ocrx_word' id='word_1_288' title='bbox 761 1347 781 1365; x_wconf 95'>in</span>
|
||||
<span class='ocrx_word' id='word_1_289' title='bbox 788 1348 857 1370; x_wconf 93'>Japan.</span>
|
||||
</span>
|
||||
<span class='ocr_line' id='line_1_37' title="bbox 138 1369 812 1395; baseline 0.007 -10; x_size 23; x_descenders 5; x_ascenders 6">
|
||||
<span class='ocrx_word' id='word_1_288' title='bbox 138 1369 155 1385; x_wconf 90'>2.</span>
|
||||
<span class='ocrx_word' id='word_1_289' title='bbox 166 1369 201 1385; x_wconf 95'>Mr.</span>
|
||||
<span class='ocrx_word' id='word_1_290' title='bbox 210 1369 256 1386; x_wconf 96'>Fish</span>
|
||||
<span class='ocrx_word' id='word_1_291' title='bbox 264 1370 284 1387; x_wconf 96'>to</span>
|
||||
<span class='ocrx_word' id='word_1_292' title='bbox 291 1370 326 1387; x_wconf 86'>Mr.</span>
|
||||
<span class='ocrx_word' id='word_1_293' title='bbox 334 1370 364 1387; x_wconf 96'>De</span>
|
||||
<span class='ocrx_word' id='word_1_294' title='bbox 371 1370 429 1393; x_wconf 96'>Long,</span>
|
||||
<span class='ocrx_word' id='word_1_295' title='bbox 438 1371 546 1392; x_wconf 96'>September</span>
|
||||
<span class='ocrx_word' id='word_1_296' title='bbox 553 1372 581 1394; x_wconf 96'>10,</span>
|
||||
<span class='ocrx_word' id='word_1_297' title='bbox 590 1372 640 1389; x_wconf 96'>1870.</span>
|
||||
<span class='ocrx_word' id='word_1_298' title='bbox 810 1393 812 1395; x_wconf 0'>.</span>
|
||||
<span class='ocr_line' id='line_1_37' title="bbox 142 1371 644 1393; baseline 0.004 -7; x_size 30.84; x_descenders 5; x_ascenders 8.8400002">
|
||||
<span class='ocrx_word' id='word_1_290' title='bbox 142 1371 159 1387; x_wconf 90'>2,</span>
|
||||
<span class='ocrx_word' id='word_1_291' title='bbox 170 1371 205 1387; x_wconf 96'>Mr.</span>
|
||||
<span class='ocrx_word' id='word_1_292' title='bbox 214 1371 260 1388; x_wconf 95'>Fish</span>
|
||||
<span class='ocrx_word' id='word_1_293' title='bbox 268 1372 288 1389; x_wconf 95'>to</span>
|
||||
<span class='ocrx_word' id='word_1_294' title='bbox 295 1371 330 1388; x_wconf 95'>Mr.</span>
|
||||
<span class='ocrx_word' id='word_1_295' title='bbox 338 1371 368 1388; x_wconf 96'>De</span>
|
||||
<span class='ocrx_word' id='word_1_296' title='bbox 375 1371 433 1393; x_wconf 96'>Long,</span>
|
||||
<span class='ocrx_word' id='word_1_297' title='bbox 442 1371 550 1392; x_wconf 95'>September</span>
|
||||
<span class='ocrx_word' id='word_1_298' title='bbox 557 1371 585 1393; x_wconf 95'>10,</span>
|
||||
<span class='ocrx_word' id='word_1_299' title='bbox 594 1371 644 1388; x_wconf 79'>1870,</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_13' title="bbox 0 0 1000 1520">
|
||||
<p class='ocr_par' id='par_1_20' lang='eng' title="bbox 0 0 1000 1520">
|
||||
<span class='ocr_line' id='line_1_38' title="bbox 0 0 1000 1520; baseline 0 9; x_size 770; x_descenders -385; x_ascenders 385">
|
||||
<span class='ocrx_word' id='word_1_299' title='bbox 0 0 1000 1520; x_wconf 95'> </span>
|
||||
<span class='ocr_line' id='line_1_38' title="bbox 0 0 1000 1520; baseline 0 2; x_size 763; x_descenders -381.5; x_ascenders 381.5">
|
||||
<span class='ocrx_word' id='word_1_300' title='bbox 0 0 1000 1520; x_wconf 95'> </span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_14' title="bbox 19 1496 978 1520">
|
||||
<p class='ocr_par' id='par_1_21' lang='eng' title="bbox 19 1496 978 1520">
|
||||
<span class='ocr_line' id='line_1_39' title="bbox 19 1496 978 1520; baseline 0 7; x_size 16; x_descenders -8; x_ascenders 8">
|
||||
<span class='ocrx_word' id='word_1_300' title='bbox 19 1496 978 1520; x_wconf 95'> </span>
|
||||
<div class='ocr_carea' id='block_1_14' title="bbox 24 1504 845 1520">
|
||||
<p class='ocr_par' id='par_1_21' lang='eng' title="bbox 24 1504 845 1520">
|
||||
<span class='ocr_line' id='line_1_39' title="bbox 24 1504 845 1520; baseline 0 0; x_size 8; x_descenders -4; x_ascenders 4">
|
||||
<span class='ocrx_word' id='word_1_301' title='bbox 24 1504 845 1520; x_wconf 95'> </span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class='ocr_carea' id='block_1_15' title="bbox 982 987 1000 1500">
|
||||
<p class='ocr_par' id='par_1_22' lang='eng' title="bbox 982 987 1000 1500">
|
||||
<span class='ocr_line' id='line_1_40' title="bbox 982 987 1000 1500; baseline 0 0; x_size 256.5; x_descenders -128.25; x_ascenders 128.25">
|
||||
<span class='ocrx_word' id='word_1_302' title='bbox 982 987 1000 1500; x_wconf 95'> </span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
+10
-8
@@ -1,5 +1,5 @@
|
||||
41st CONGRESS; | SENATE.
|
||||
3d Session. }
|
||||
4ist ConGREss, } SENATE. { Ex. Doc,
|
||||
3d Session. No. 25.
|
||||
|
||||
MESSAGE
|
||||
|
||||
@@ -12,7 +12,7 @@ COMMUNICATING
|
||||
A copy of regulations for the consular courts of the United States in Japan,
|
||||
decreed and issued by the minister of the United States in that country.
|
||||
|
||||
January 27, 1871,—Read, referred to the Committee on Commerce, and ordered to be
|
||||
JANUARY 27, 1871,—Read, referred to the Committee on Commerce, and ordered to be
|
||||
printed.
|
||||
|
||||
To the Senate and House of Representatives :
|
||||
@@ -26,13 +26,13 @@ U. 8. GRANT.
|
||||
‘WASHINGTON, January 27, 1871.
|
||||
|
||||
DEPARTMENT OF STATE,
|
||||
. Washington, January 26, 1870,
|
||||
Washington, January 26, 1870,
|
||||
|
||||
The Secretary of State has the honor to submit herewith, for revision
|
||||
by Congress, in conformity with the provisions of section 6 of the act
|
||||
approved 22d of June, 1860, a copy of “regulations for the consular
|
||||
courts of the United States in Japan,” decreed and issued by C. E.
|
||||
De Long, the miniater of the United States in that country, in Septem-
|
||||
courts of the United States in Japan,” decreed and issued by C. BE.
|
||||
De Long, the minister of the United States in that country, in Septem-
|
||||
ber, 1870; and also the papers mentioned in the subjoined list, which,
|
||||
contain suggestions on the subject thereof.
|
||||
|
||||
@@ -43,7 +43,7 @@ decrees and regulation, in the sense in which it is limited by paragraph
|
||||
431 of the article before named—that is, “to acts necessary to organize
|
||||
and give efficiency to the courts created by the act.”
|
||||
|
||||
Respectfully submitted. .
|
||||
Respectfully submitted.
|
||||
|
||||
HAMILTON FISH.
|
||||
|
||||
@@ -52,7 +52,9 @@ The PRESIDENT,
|
||||
List of accompanying papers.
|
||||
|
||||
1, Regulations for the consular courts of the United States in Japan.
|
||||
2. Mr. Fish to Mr. De Long, September 10, 1870. .
|
||||
2, Mr. Fish to Mr. De Long, September 10, 1870,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.wyikj5nw/000001_ocr.png"; bbox 0 0 512 512; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.tyuf6jbx/000001_ocr.png"; bbox 0 0 512 512; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 0 0 477 512">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 0 0 477 512">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 0 0 477 512; baseline 0 0; x_size 684; x_descenders 171; x_ascenders 171">
|
||||
|
||||
BIN
Binary file not shown.
Vendored
+44
-64
@@ -1,64 +1,44 @@
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/francais.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/2400dpi.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/jbig2.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/graph_ocred.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/ccitt.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/ccitt.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/aspect.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/palette.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000001_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000001_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000003_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000003_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000004_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000004_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000002_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000002_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/aspect.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/jbig2.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000004_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000004_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000001_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000001_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000003_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000003_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000002_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000002_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/palette.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/palette.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__--psm__7__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "--psm", "7", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__--psm__7__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "--psm", "7", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__osd__--psm__0__000001_rasterize_preview.jpg__stdout", "sourcefile": "resources/poster.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000001_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "Darwin-18.7.0-x86_64-i386-64bit", "python": "3.7.7", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/poster.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/francais.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__--psm__7__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "--psm", "7", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__--psm__7__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "--psm", "7", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/aspect.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/ccitt.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/jbig2.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/palette.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_hocr__hocr__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/2400dpi.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/aspect.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/ccitt.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/graph_ocred.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/jbig2.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/palette.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/poster.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/skew.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000002_ocr.png", "$TMPDIR/000002_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/3small.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000003_ocr.png", "$TMPDIR/000003_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_hocr__hocr__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000004_ocr.png", "$TMPDIR/000004_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000005_ocr.png__000005_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000005_ocr.png", "$TMPDIR/000005_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_hocr__hocr__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_hocr", "hocr", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__eng__000006_ocr.png__000006_ocr_tess__pdf__txt", "sourcefile": "resources/multipage.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000006_ocr.png", "$TMPDIR/000006_ocr_tess", "pdf", "txt"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__osd__--psm__0__000001_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000001_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__osd__--psm__0__000001_rasterize_preview.jpg__stdout", "sourcefile": "resources/poster.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000001_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__osd__--psm__0__000002_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000002_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__osd__--psm__0__000003_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000003_rasterize_preview.jpg", "stdout"]}
|
||||
{"tesseract_version": "4.1.1", "platform": "macOS-10.14.6-x86_64-i386-64bit", "python": "3.9.0", "argv_slug": "__-l__osd__--psm__0__000004_rasterize_preview.jpg__stdout", "sourcefile": "resources/cardinal.pdf", "args": ["-l", "osd", "--psm", "0", "$TMPDIR/000004_rasterize_preview.jpg", "stdout"]}
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.asx0dv8k/000001_ocr.png"; bbox 0 0 1600 1962; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sh2wg519/000001_ocr.png"; bbox 0 0 1600 1962; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 84 216 786 1605">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 84 216 786 1605">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 84 216 786 1605; baseline 0 0; x_size 694.5; x_descenders -347.25; x_ascenders 347.25">
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.asx0dv8k/000003_ocr.png"; bbox 0 0 2272 1848; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sh2wg519/000003_ocr.png"; bbox 0 0 2272 1848; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 201 38 2167 118">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 201 38 2167 118">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 201 38 2167 118; baseline -0.001 -17; x_size 79; x_descenders 17; x_ascenders 16">
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.asx0dv8k/000004_ocr.png"; bbox 0 0 2272 1848; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sh2wg519/000004_ocr.png"; bbox 0 0 2272 1848; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 200 38 2168 120">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 200 38 2168 120">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 200 38 2168 120; baseline 0 -18; x_size 80; x_descenders 18; x_ascenders 16">
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.asx0dv8k/000005_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sh2wg519/000005_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 70 403 1182 833">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 70 403 1182 833">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 70 403 1180 461; baseline 0.002 -14; x_size 59; x_descenders 13; x_ascenders 15">
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.asx0dv8k/000006_ocr.png"; bbox 0 0 3300 2550; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.sh2wg519/000006_ocr.png"; bbox 0 0 3300 2550; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 438 20 1559 450">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 438 20 1559 450">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 438 20 1556 74; baseline 0 -12; x_size 54; x_descenders 12; x_ascenders 14">
|
||||
|
||||
BIN
Binary file not shown.
+2
-2
@@ -45,8 +45,8 @@ when that sufferer was put to death, already
|
||||
marked by the Woodman, Fate, to come down
|
||||
and be sawn into boards, to make a certain mov-
|
||||
able framework with a sack and a knife in it, ter-
|
||||
tible in history. It is likely enough that in the
|
||||
tough outhouses of some tillers of the heavy
|
||||
rible in history. It is likely enough that in the
|
||||
rough outhouses of some tillers of the heavy
|
||||
lands adjacent to Paris, there were sheltered
|
||||
from the weather that very day, rude carts,
|
||||
bespattered with rustic mire, snuffed about by
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.vwlt_pd8/000001_ocr.png"; bbox 0 0 1000 1520; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.__z8spg_/000001_ocr.png"; bbox 0 0 1000 1520; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 122 103 542 155">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 122 103 542 145">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 122 103 542 145; baseline 0.002 -26; x_size 22; x_descenders 5; x_ascenders 5">
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
-2
@@ -1,3 +1 @@
|
||||
Tesseract Open Source OCR Engine v4.1.1 with Leptonica
|
||||
Warning: Invalid resolution 10 dpi. Using 70 instead.
|
||||
Estimating resolution as 328
|
||||
|
||||
-2
@@ -2,7 +2,6 @@ The LinnSequencer
|
||||
32 Track MIDI Sequence Recorder
|
||||
|
||||
The LinnSequencer is a state-of-the-art composition and performance tool for the professional musician. It is
|
||||
|
||||
extremely powerful, yet amazingly simple to learn and use. It’s many remarkable features include:
|
||||
|
||||
© Operation is similar to multi-track tape recorder with PLAY, STOP, RECORD, FAST
|
||||
@@ -54,7 +53,6 @@ Editing
|
||||
To erase a wrong note, simply hold ERASE and press
|
||||
the note to be erased just before it plays in the sequence—
|
||||
when played back, it will be gone. Notes may also be
|
||||
|
||||
added, erased, or changed using the SINGLE STEP func-
|
||||
tion. To overdub notes at specific points within a sequence,
|
||||
|
||||
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
Warning: Invalid resolution 10 dpi. Using 70 instead.
|
||||
Estimating resolution as 328
|
||||
Warning. Invalid resolution 10 dpi. Using 70 instead.
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.3ul2sron/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.j369pad1/000001_ocr.png"; bbox 0 0 2550 3300; ppageno 0'>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -9,7 +9,7 @@
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word ocrp_wconf'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/com.github.ocrmypdf.pdbmcg_o/000001_ocr.png"; bbox 0 0 2975 3850; ppageno 0'>
|
||||
<div class='ocr_page' id='page_1' title='image "/var/folders/2s/7t022mgj0h5cprbq0dtb1ksm0000gn/T/ocrmypdf.io.vgw3lwtz/000001_ocr.png"; bbox 0 0 2975 3850; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 732 141 2349 361">
|
||||
<p class='ocr_par' id='par_1_1' lang='eng' title="bbox 732 141 2349 361">
|
||||
<span class='ocr_line' id='line_1_1' title="bbox 1086 141 1990 259; baseline 0.032 -38; x_size 102; x_descenders 20; x_ascenders 24">
|
||||
|
||||
BIN
Binary file not shown.
@@ -17,40 +17,25 @@ from ocrmypdf import api, pdfinfo
|
||||
from ocrmypdf._exec import unpaper
|
||||
from ocrmypdf._plugin_manager import get_parser_options_plugins
|
||||
|
||||
pytest_plugins = ['helpers_namespace']
|
||||
|
||||
|
||||
# pylint: disable=E1101
|
||||
# pytest.helpers is dynamic so it confuses pylint
|
||||
|
||||
if sys.version_info < (3, 5):
|
||||
print("Requires Python 3.5+")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def is_linux():
|
||||
return platform.system() == 'Linux'
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def is_macos():
|
||||
return platform.system() == 'Darwin'
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def running_in_docker():
|
||||
# Docker creates a file named /.dockerenv (newer versions) or
|
||||
# /.dockerinit (older) -- this is undocumented, not an offical test
|
||||
return Path('/.dockerenv').exists() or Path('/.dockerinit').exists()
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def running_in_travis():
|
||||
return os.environ.get('TRAVIS') == 'true'
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def have_unpaper():
|
||||
try:
|
||||
unpaper.version()
|
||||
@@ -93,7 +78,6 @@ def no_outpdf(tmp_path):
|
||||
return tmp_path / 'no_output.pdf'
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def check_ocrmypdf(input_file, output_file, *args):
|
||||
"""Run ocrmypdf and confirmed that a valid file was created"""
|
||||
args = [str(input_file), str(output_file)] + [
|
||||
@@ -111,7 +95,6 @@ def check_ocrmypdf(input_file, output_file, *args):
|
||||
return output_file
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def run_ocrmypdf_api(input_file, output_file, *args):
|
||||
"""Run ocrmypdf via API and let caller deal with results
|
||||
|
||||
@@ -127,7 +110,6 @@ def run_ocrmypdf_api(input_file, output_file, *args):
|
||||
return api.run_pipeline(options, plugin_manager=None, api=False)
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def run_ocrmypdf(input_file, output_file, *args, text=True):
|
||||
"Run ocrmypdf and let caller deal with results"
|
||||
|
||||
@@ -150,7 +132,6 @@ def run_ocrmypdf(input_file, output_file, *args, text=True):
|
||||
return p, p.stdout, p.stderr
|
||||
|
||||
|
||||
@pytest.helpers.register
|
||||
def first_page_dimensions(pdf):
|
||||
info = pdfinfo.PdfInfo(pdf)
|
||||
page0 = info[0]
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# © 2020 James R. Barlow: github.com/jbarlow83
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"""Tesseract no-op/fixed rotate plugin
|
||||
|
||||
To quickly run tests where getting OCR output is not necessary and we want to test
|
||||
the rotation pipeline.
|
||||
|
||||
In 'hocr' mode, create a .hocr file that specifies no text found.
|
||||
|
||||
In 'pdf' mode, convert the image to PDF using another program.
|
||||
|
||||
In orientation check mode, report 0, 90, 180, 270... based on page number.
|
||||
"""
|
||||
|
||||
import pikepdf
|
||||
from PIL import Image
|
||||
|
||||
from ocrmypdf import OcrEngine, OrientationConfidence, hookimpl
|
||||
from ocrmypdf.helpers import page_number
|
||||
|
||||
HOCR_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='ocr-system' content='tesseract 4.0.0' />
|
||||
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word'/>
|
||||
</head>
|
||||
<body>
|
||||
<div class='ocr_page' id='page_1' title='image "x.tif"; bbox 0 0 {0} {1}; ppageno 0'>
|
||||
<div class='ocr_carea' id='block_1_1' title="bbox 0 1 {0} {1}">
|
||||
<p class='ocr_par' dir='ltr' id='par_1' title="bbox 0 1 {0} {1}">
|
||||
<span class='ocr_line' id='line_1' title="bbox 0 1 {0} {1}"><span class='ocrx_word' id='word_1' title="bbox 0 1 {0} {1}"> </span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>'''
|
||||
|
||||
|
||||
class FixedRotateNoopOcrEngine(OcrEngine):
|
||||
@staticmethod
|
||||
def version():
|
||||
return '4.0.0'
|
||||
|
||||
@staticmethod
|
||||
def creator_tag(options):
|
||||
tag = '-PDF' if options.pdf_renderer == 'sandwich' else ''
|
||||
return f"NO-OP {tag} {FixedRotateNoopOcrEngine.version()}"
|
||||
|
||||
def __str__(self):
|
||||
return f"NO-OP {FixedRotateNoopOcrEngine.version()}"
|
||||
|
||||
@staticmethod
|
||||
def languages(options):
|
||||
return {'eng'}
|
||||
|
||||
@staticmethod
|
||||
def get_orientation(input_file, options):
|
||||
page = page_number(input_file)
|
||||
|
||||
angle = ((page - 1) * 90) % 360
|
||||
|
||||
return OrientationConfidence(angle=angle, confidence=99.9)
|
||||
|
||||
@staticmethod
|
||||
def generate_hocr(input_file, output_hocr, output_text, options):
|
||||
with Image.open(input_file) as im, open(
|
||||
output_hocr, 'w', encoding='utf-8'
|
||||
) as f:
|
||||
w, h = im.size
|
||||
f.write(HOCR_TEMPLATE.format(str(w), str(h)))
|
||||
with open(output_text, 'w') as f:
|
||||
f.write('')
|
||||
|
||||
@staticmethod
|
||||
def generate_pdf(input_file, output_pdf, output_text, options):
|
||||
with Image.open(input_file) as im:
|
||||
dpi = im.info['dpi']
|
||||
pagesize = im.size[0] / dpi[0], im.size[1] / dpi[1]
|
||||
ptsize = pagesize[0] * 72, pagesize[1] * 72
|
||||
pdf = pikepdf.new()
|
||||
pdf.add_blank_page(page_size=ptsize)
|
||||
pdf.save(output_pdf, static_id=True)
|
||||
output_text.write_text('')
|
||||
|
||||
|
||||
@hookimpl
|
||||
def get_ocr_engine():
|
||||
return FixedRotateNoopOcrEngine()
|
||||
@@ -11,7 +11,9 @@ import pytest
|
||||
|
||||
import ocrmypdf
|
||||
|
||||
check_ocrmypdf = pytest.helpers.check_ocrmypdf
|
||||
from .conftest import check_ocrmypdf
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import os
|
||||
from subprocess import PIPE, run
|
||||
|
||||
import pytest
|
||||
|
||||
from .conftest import running_in_docker
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
pytest.helpers.running_in_docker(), # pylint: disable=no-member
|
||||
running_in_docker(),
|
||||
reason="docker can't complete",
|
||||
)
|
||||
|
||||
@@ -29,6 +32,9 @@ def test_fish():
|
||||
pytest.xfail('fish is not installed')
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
os.name == 'nt', reason="Windows CI workers have bash but are best left alone"
|
||||
)
|
||||
def test_bash():
|
||||
try:
|
||||
proc = run(
|
||||
|
||||
@@ -16,9 +16,7 @@ from ocrmypdf._exec.ghostscript import rasterize_pdf
|
||||
from ocrmypdf.exceptions import ExitCode
|
||||
from ocrmypdf.helpers import Resolution
|
||||
|
||||
check_ocrmypdf = pytest.helpers.check_ocrmypdf # pylint: disable=no-member
|
||||
run_ocrmypdf = pytest.helpers.run_ocrmypdf # pylint: disable=no-member
|
||||
run_ocrmypdf_api = pytest.helpers.run_ocrmypdf_api # pylint: disable=no-member
|
||||
from .conftest import check_ocrmypdf, run_ocrmypdf
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user