Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ You can also skip translating the text layer (it is sometimes not translated wel

dpsprep --ocr '{"language": ["rus", "eng"]}' input.djvu

You can also configure how the outline/toc page numbers in the djvu is translated to page numbers in pdf. Sometimes, their numbering convention is not consistent. For example, when converting djvu whose page numbers are one page ahead of the pdf:

dpsprep --toc-pg-offset=-1 input.djvu

Consult the man file ([online](./dpsprep.1.ronn)) for details; there are a lot of options to consider.

See the next section for different ways to run the program.
Expand Down
3 changes: 2 additions & 1 deletion dpsprep.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ This tool, initially made specifically for use with Sony's Digital Paper System
* `-w`, `--preserve-working`: Preserve the working directory after script termination.
* `-d`, `--delete-working`: Delete any existing files in the working directory prior to writing to it.
* `-t`, `--no-text`: Disable the generation of text layers. Implied by --ocr.
* `--ocr` Perform OCR via OCRmyPDF rather than trying to convert the text layer. If this parameter has a value, it should be a JSON dictionary of options to be passed to OCRmyPDF.
* `--ocr`: Perform OCR via OCRmyPDF rather than trying to convert the text layer. If this parameter has a value, it should be a JSON dictionary of options to be passed to OCRmyPDF.
* `--toc-pg-offset`: Configure the page offset to be applied when translating outline/toc. This is to work with different djvu page numbering (starting from page 0 or page 1).
* `-O1`: Use the lossless PDF image optimization from OCRmyPDF (without performing OCR).
* `-O2`: Use the PDF image optimization from OCRmyPDF.
* `-O3`: Use the aggressive lossy PDF image optimization from OCRmyPDF.
Expand Down
6 changes: 4 additions & 2 deletions dpsprep/dpsprep.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ def process_text(workdir: WorkingDirectory):
@click.option('-p', '--pool-size', type=click.IntRange(min=0), default=4, help='Size of MultiProcessing pool for handling page-by-page operations.')
@click.option('-q', '--quality', type=click.IntRange(min=0, max=100), default=75, help="Quality of images in output. Used only for JPEG compression, i.e. RGB and Grayscale images. Passed directly to Pillow and to OCRmyPDF's optimizer.")
@click.option('--ocr', type=str, is_flag=False, flag_value='{}', help='Perform OCR via OCRmyPDF rather than trying to convert the text layer. If this parameter has a value, it should be a JSON dictionary of options to be passed to OCRmyPDF.')
@click.option('--toc-pg-offset', type=int, default=-1, help='The page offset to be applied when translating outline/toc.')
@click.argument('dest', type=click.Path(exists=False, resolve_path=True), required=False)
@click.argument('src', type=click.Path(exists=True, resolve_path=True), required=True)
@click.command()
@click.command(context_settings={'show_default': True})
def dpsprep(
src: str,
dest: Union[str, None],
Expand All @@ -94,6 +95,7 @@ def dpsprep(
no_text: bool,
optlevel: Union[int, None],
ocr: Union[str, None],
toc_pg_offset: int,
):
configure_loguru(verbose)
workdir = WorkingDirectory(src, dest)
Expand Down Expand Up @@ -165,7 +167,7 @@ def dpsprep(

if len(document.outline.sexpr) > 0:
logger.info('Processing metadata.')
outline = OutlineTransformVisitor().visit(document.outline.sexpr)
outline = OutlineTransformVisitor(toc_pg_offset, len(document.pages)).visit(document.outline.sexpr)
logger.info('Metadata processed.')
else:
logger.info('No metadata to process.')
Expand Down
20 changes: 15 additions & 5 deletions dpsprep/outline.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
from loguru import logger
from pdfrw import PdfName, PdfDict, IndirectPdfDict
import djvu.sexpr
import re

from .sexpr import SExpressionVisitor


# Based on
# https://github.com/pmaupin/pdfrw/issues/52#issuecomment-271190546
class OutlineTransformVisitor(SExpressionVisitor):
def __init__(self, toc_pg_offset: int, total_pages: int):
self.toc_pg_offset = toc_pg_offset
self.total_pages = total_pages
super().__init__()
def visit_plain_list(self, node: djvu.sexpr.StringExpression, parent: IndirectPdfDict):
title, page, *rest = node
# I have experimentally determined that we need to translate page indices. -- Ianis, 2023-05-03
try:
page_number = int(page.value[1:]) - 1
except ValueError:
# As far as I understand, python-djvulibre doesn't support Djvu's page titles. -- Ianis, 2023-12-09

# Translate the first valid number in the page title to be the page indices.
m = re.search(r'[0-9]+', page.value)
if m is not None:
page_number = int(m.group(0), base=10) + self.toc_pg_offset
else:
logger.warning(f'Could not determine page number from the page title {page.value}.')
return

if page_number < 0 or page_number >= self.total_pages:
logger.warning(f'Refuse to translate the page title \'{page.value}\' to an invalid number {page_number}.')
return

bookmark = IndirectPdfDict(
Parent = parent,
Title = title.value,
Expand Down