Bessere Standardwerte: EPUB-Sprache, Titel/Autor, Prozesszahl

- --lang ohne Angabe aus der ersten OCR-Sprache ableiten (eng -> en)
- Fehlen Titel/Autor in den PDF-Metadaten: aus dem Dateinamen nach dem
  Muster "Autor_-_Titel" übernehmen, sonst Dateiname mit Leerzeichen
- --jobs: halbe Kernzahl, höchstens 8 (bisher 4)
- Tests (tests/test_defaults.py), README und Bedienungsanleitung

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-02 15:20:08 +02:00
commit fa90050535

View file

@ -1057,6 +1057,39 @@ def heading_depth(markdown: str) -> int:
return min(max(levels, default=1), 3)
# Tesseract-Sprachcode -> Sprachcode im EPUB (ISO 639-1)
EPUB_LANGUAGES = {
"deu": "de", "deu_latf": "de", "frk": "de", "eng": "en", "fra": "fr",
"spa": "es", "ita": "it", "nld": "nl", "por": "pt", "pol": "pl",
"ces": "cs", "dan": "da", "swe": "sv", "nor": "no", "fin": "fi",
"rus": "ru", "ukr": "uk", "lat": "la", "ell": "el", "tur": "tr",
}
def epub_language(ocr_language: str) -> str:
"""EPUB-Sprache aus der (ersten) OCR-Sprache: "eng+deu" -> "en"."""
first = ocr_language.split("+")[0].strip().lower()
return EPUB_LANGUAGES.get(first, "de")
def default_jobs() -> int:
"""Halbe Kernzahl, höchstens 8: Jeder Prozess lädt das Layout-Modell."""
return max(1, min(8, (os.cpu_count() or 2) // 2))
def title_author_from_filename(stem: str) -> tuple[str, str]:
"""Titel und Autor aus einem Dateinamen nach dem Muster "Autor_-_Titel".
"Katja_Adler_-_Rolle_rückwärts" -> ("Rolle rückwärts", "Katja Adler");
ohne " - " ist der ganze Name der Titel.
"""
name = re.sub(r"\s+", " ", stem.replace("_", " ")).strip()
author, sep, title = name.partition(" - ")
if sep and author.strip() and title.strip():
return title.strip(), author.strip()
return name, ""
def write_epub(
markdown_path: Path,
epub_path: Path,
@ -1142,8 +1175,9 @@ def main() -> int:
parser.add_argument(
"--jobs",
type=int,
default=min(4, os.cpu_count() or 1),
help="Anzahl paralleler Prozesse (Standard: %(default)s)",
default=default_jobs(),
help="Anzahl paralleler OCR-Prozesse (Standard: halbe Kernzahl, "
"höchstens 8; hier %(default)s)",
)
parser.add_argument(
"--images",
@ -1169,8 +1203,8 @@ def main() -> int:
)
parser.add_argument(
"--lang",
default="de",
help="Sprache im EPUB (Standard: de)",
help="Sprache im EPUB, z. B. en (Standard: aus --ocr-language, "
"deu -> de, eng -> en)",
)
parser.add_argument(
"--keep-headers",
@ -1183,6 +1217,7 @@ def main() -> int:
help="Seitenfüße/Seitenzahlen übernehmen",
)
args = parser.parse_args()
args.lang = args.lang or epub_language(args.ocr_language)
source = args.pdf.expanduser()
target = (args.markdown or source.with_suffix(".md")).expanduser()
@ -1206,8 +1241,9 @@ def main() -> int:
outline = load_outline(doc)
uris = load_link_uris(doc)
page_count = doc.page_count
title = (doc.metadata or {}).get("title") or source.stem
author = (doc.metadata or {}).get("author") or ""
file_title, file_author = title_author_from_filename(source.stem)
title = ((doc.metadata or {}).get("title") or "").strip() or file_title
author = ((doc.metadata or {}).get("author") or "").strip() or file_author
counts = Counter(kinds)
print(