diff --git a/epub2md/html_converter.py b/epub2md/html_converter.py
index 3e619cf..fb8f6ff 100644
--- a/epub2md/html_converter.py
+++ b/epub2md/html_converter.py
@@ -221,6 +221,8 @@ def _box_type(hint: str) -> str:
return "important"
if re.search(r"tipp|\btip|hint", h):
return "tip"
+ if re.search(r"hinweis|\bnote|notiz|anmerkung|\binfo", h):
+ return "note"
return ""
diff --git a/epub2md/normalize.py b/epub2md/normalize.py
index 8f9dc66..78db4e1 100644
--- a/epub2md/normalize.py
+++ b/epub2md/normalize.py
@@ -3,6 +3,7 @@
from __future__ import annotations
import re
+from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any
@@ -80,7 +81,8 @@ def book_uses_title_tables(docs: list[Doc]) -> bool:
return False
-def normalize_doc(doc: Doc, diag: Diagnostics, title_tables: bool) -> None:
+def normalize_doc(doc: Doc, diag: Diagnostics, title_tables: bool,
+ hidden: Callable[[Any], bool] | None = None) -> None:
body = doc.body
for el in list(iter_elements(body)):
if not _attached(el, body):
@@ -107,19 +109,19 @@ def normalize_doc(doc: Doc, diag: Diagnostics, title_tables: bool) -> None:
doc.toc_ids.update(e.get("id") for e in iter_elements(el) if e.get("id"))
remove_keep_tail(el)
diag.info("html-toc-removed", "HTML-Inhaltsverzeichnis entfernt (ersetzt durch README.md).", doc.path)
- separated = _separate_field_spans(body)
+ separated = _separate_field_spans(body, hidden or (lambda el: False))
if separated:
diag.info("inline-separator-added",
f"{separated} Leerzeichen zwischen aneinanderstoßenden Feld-Spans eingefügt.", doc.path)
-def _separate_field_spans(body: Any) -> int:
+def _separate_field_spans(body: Any, hidden: Callable[[Any], bool]) -> int:
"""Insert a space between adjacent class-styled "fields" that touch without whitespace.
Publishers sometimes lay out metadata as sibling spans (author | title | series) separated only by
CSS. Narrow rule to keep drop caps ("D|as") and split words ("Haupt|bahnhof") intact: both spans
carry different classes, no text between them, both have >= 2 characters and the right one starts
- with an uppercase letter or digit.
+ with an uppercase letter or digit. Spans hidden by the book's CSS (display:none) get no separator.
"""
count = 0
for parent in iter_elements(body):
@@ -132,7 +134,7 @@ def _separate_field_spans(body: Any) -> int:
lt, rt = text_content(left), text_content(right)
if len(lt.strip()) < 2 or len(rt.strip()) < 2 or lt[-1].isspace() or rt[0].isspace():
continue
- if rt[0].isupper() or rt[0].isdigit():
+ if (rt[0].isupper() or rt[0].isdigit()) and not hidden(left) and not hidden(right):
left.tail = " "
count += 1
return count
diff --git a/epub2md/pipeline.py b/epub2md/pipeline.py
index c9021b4..bc10e24 100644
--- a/epub2md/pipeline.py
+++ b/epub2md/pipeline.py
@@ -8,6 +8,7 @@ import re
import shutil
import sys
import tempfile
+from collections.abc import Callable
from dataclasses import asdict, dataclass, field
from datetime import datetime, timezone
from pathlib import Path
@@ -16,7 +17,7 @@ from typing import Any
from . import TOOL_NAME, __version__
from .chapters import ChapterBuilder
from .diagnostics import Diagnostics
-from .css import StyleSheet, base_style
+from .css import StyleSheet, base_style, emphasis
from .epub_reader import EpubReader, decode_markup, parse_xml
from .errors import ContainerError, InputError, StructureError
from .footnotes import collect_notes
@@ -140,7 +141,8 @@ def _convert(reader: EpubReader, input_path: Path, output_dir: Path, opts: Optio
diag.step(f"EPUB {package.version}: {package.metadata.title!r}, {len(package.spine)} Spine-Dokumente")
docs = _load_docs(reader, package, diag)
stylesheet = _load_stylesheet(reader, package, docs, diag) # before normalization drops