Мягкий перенос U+00AD: русские PDF рвали слова пополам
Питер и ДМК переносят строку мягким дефисом, а не обычным. Ветка склейки проверяла только "-", поэтому строки соединялись через пробел: «введен ные», «Практиче ски». Теперь U+00AD снимается при склейке, остатки внутри строки удаляются, а в ошибочно опознанных листингах перенос со строкой схлопывается. Измерено на Шоттсе (Питер, 2020, 544 стр.): было 8 мягких переносов на проверенной выборке, стало ноль. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L2PNJCFFXvizoNjTFuTaqi
This commit is contained in:
+13
-2
@@ -39,6 +39,7 @@ MAX_IMG_SHARE = 0.6 # доля площади страницы: больше
|
|||||||
# Запасное опознание листинга, когда издатель вычистил и имена шрифтов, и флаги:
|
# Запасное опознание листинга, когда издатель вычистил и имена шрифтов, и флаги:
|
||||||
# кегль мельче основного текста плюс пунктуация, которой в прозе не бывает.
|
# кегль мельче основного текста плюс пунктуация, которой в прозе не бывает.
|
||||||
CODEY = re.compile(r"[{}();\[\]<>=*/#]|::|->")
|
CODEY = re.compile(r"[{}();\[\]<>=*/#]|::|->")
|
||||||
|
SOFT_HYPHEN = "\u00ad"
|
||||||
|
|
||||||
|
|
||||||
def style(font, flags=0):
|
def style(font, flags=0):
|
||||||
@@ -137,7 +138,10 @@ def block_text(b, pre=False):
|
|||||||
# слова. Ни склейки строк, ни де-дефисации здесь быть не должно.
|
# слова. Ни склейки строк, ни де-дефисации здесь быть не должно.
|
||||||
rows = ["".join(span_html(s, plain=True) for s in l["spans"])
|
rows = ["".join(span_html(s, plain=True) for s in l["spans"])
|
||||||
for l in b["lines"]]
|
for l in b["lines"]]
|
||||||
return "\n".join(rows).rstrip()
|
# В настоящем коде мягкого переноса не бывает: если он тут есть, блок
|
||||||
|
# опознан как листинг ошибочно (обычно это таблица опций), и слово надо
|
||||||
|
# склеить, а не оставить разорванным переводом строки.
|
||||||
|
return "\n".join(rows).replace(SOFT_HYPHEN + "\n", "").rstrip()
|
||||||
out = []
|
out = []
|
||||||
for i, l in enumerate(b["lines"]):
|
for i, l in enumerate(b["lines"]):
|
||||||
line = "".join(span_html(s) for s in l["spans"])
|
line = "".join(span_html(s) for s in l["spans"])
|
||||||
@@ -145,7 +149,12 @@ def block_text(b, pre=False):
|
|||||||
continue
|
continue
|
||||||
if out:
|
if out:
|
||||||
prev = out[-1]
|
prev = out[-1]
|
||||||
if prev.endswith("-") and not prev.endswith("--"):
|
# Русские издания переносят мягким дефисом U+00AD, а не обычным:
|
||||||
|
# без этой ветки строки склеиваются через пробел и слово рвётся
|
||||||
|
# пополам («введен ные»). Измерено на Шоттсе (Питер, 2020).
|
||||||
|
if prev.endswith(SOFT_HYPHEN):
|
||||||
|
out[-1] = prev[:-1]
|
||||||
|
elif prev.endswith("-") and not prev.endswith("--"):
|
||||||
out[-1] = prev[:-1] # de-hyphenate
|
out[-1] = prev[:-1] # de-hyphenate
|
||||||
else:
|
else:
|
||||||
out.append(" ")
|
out.append(" ")
|
||||||
@@ -154,6 +163,8 @@ def block_text(b, pre=False):
|
|||||||
txt = re.sub(r"</i>(\s*)<i>", r"\1", txt)
|
txt = re.sub(r"</i>(\s*)<i>", r"\1", txt)
|
||||||
txt = re.sub(r"</b>(\s*)<b>", r"\1", txt)
|
txt = re.sub(r"</b>(\s*)<b>", r"\1", txt)
|
||||||
txt = re.sub(r"(?<=\S) {2,}(?=\S)", " ", txt)
|
txt = re.sub(r"(?<=\S) {2,}(?=\S)", " ", txt)
|
||||||
|
# Мягкие переносы внутри строки читалке не нужны и ломают поиск по тексту.
|
||||||
|
txt = txt.replace(SOFT_HYPHEN, "")
|
||||||
return txt.strip()
|
return txt.strip()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user