---: minor
This commit is contained in:
39
README.md
39
README.md
@@ -17,7 +17,7 @@
|
|||||||
* [GitHub](https://github.com/erjemin/etpgrf) (Главное зеркало)
|
* [GitHub](https://github.com/erjemin/etpgrf) (Главное зеркало)
|
||||||
* [GitVerse](https://gitverse.ru/erjemin/etpgrf) (Зеркало на GitVerse)
|
* [GitVerse](https://gitverse.ru/erjemin/etpgrf) (Зеркало на GitVerse)
|
||||||
|
|
||||||
## Демострация / Demo
|
## Демонстрация / Demo
|
||||||
|
|
||||||
Работа etpgrf-типографа представлена по адресу: [typograph.cube2.ru](https://typograph.cube2.ru/). Подготовьте верстку
|
Работа etpgrf-типографа представлена по адресу: [typograph.cube2.ru](https://typograph.cube2.ru/). Подготовьте верстку
|
||||||
вашего текста, сайтов, статей и постов к публикации в интернете за один клик.
|
вашего текста, сайтов, статей и постов к публикации в интернете за один клик.
|
||||||
@@ -34,7 +34,7 @@ import etpgrf
|
|||||||
# Создаем типограф с настройками по умолчанию
|
# Создаем типограф с настройками по умолчанию
|
||||||
typo = etpgrf.Typographer(langs='ru')
|
typo = etpgrf.Typographer(langs='ru')
|
||||||
# Обрабатываем текст
|
# Обрабатываем текст
|
||||||
result = typo.process(text="\"Пример текста для типографирования!\" - сказал он.")
|
result = typo.process(text="\"Пример текста для типографа!\" - сказал он.")
|
||||||
print(result)
|
print(result)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -45,9 +45,9 @@ print(result)
|
|||||||
некоторых специфических символов (например, кавычек, тире, стрелочек, математических символов) используют
|
некоторых специфических символов (например, кавычек, тире, стрелочек, математических символов) используют
|
||||||
html-мнемоники (например, `—` для длинного тире, `«` для открывающей кавычки-ёлочки и т.д.).
|
html-мнемоники (например, `—` для длинного тире, `«` для открывающей кавычки-ёлочки и т.д.).
|
||||||
|
|
||||||
tpgrf имеет три режима работы с кодировками:
|
Библиотека etpgrf имеет три режима работы с кодировками:
|
||||||
- Режим `unicode` — весь вывод осуществляется в кодировке UTF-8. ВЕСЬ! Включая невидимые символы, типа неразрывных и нулевых
|
- Режим `unicode` — весь вывод осуществляется в кодировке UTF-8. ВЕСЬ! Включая невидимые символы, типа неразрывных
|
||||||
пробелов, мягких переносов и т.д. Это не всегда удобно зато типографированый текст (строки) будет максимально
|
и нулевых пробелов, мягких переносов и т.д. Это не всегда удобно зато типографированый текст (строки) будет максимально
|
||||||
компактен и занимать меньше места в памяти. В этом режиме в html-мнемоники преобразуются только опасные символы:
|
компактен и занимать меньше места в памяти. В этом режиме в html-мнемоники преобразуются только опасные символы:
|
||||||
* `<` — знак меньше `<`;
|
* `<` — знак меньше `<`;
|
||||||
* `>` — знак больше `>`;
|
* `>` — знак больше `>`;
|
||||||
@@ -95,16 +95,15 @@ result = typo_mixed_mode.process(text="Этот текст будет обраб
|
|||||||
короткое из них (для компактности), а значит:
|
короткое из них (для компактности), а значит:
|
||||||
* если в исходном тексте были html-мнемоники, то они будут заменены на более короткие;
|
* если в исходном тексте были html-мнемоники, то они будут заменены на более короткие;
|
||||||
* если html-мнемоники использовались как элементы семантической разметки (например, для математических выражений),
|
* если html-мнемоники использовались как элементы семантической разметки (например, для математических выражений),
|
||||||
то после замены на более короткие html-мнемоники, текст может потерять такую семантику. Например _F = A ⋂ B_:
|
то после замены на более короткие html-мнемоники, текст может потерять такую семантику. Например `F = A ⋂ B` (_F = A ⋂ B_) будет преобразовано в `F = A ⋂ B`;
|
||||||
`F = A ⋂ B` будет преобразовано в `F = A ⋂ B`;
|
|
||||||
3. Мнемоники для русских букв не используются в типографе. Все мнемоники русских букв будут преобразованы в русские
|
3. Мнемоники для русских букв не используются в типографе. Все мнемоники русских букв будут преобразованы в русские
|
||||||
буквы и останутся в тексте в виде русских букв.
|
буквы и останутся в тексте в виде русских букв.
|
||||||
4. Все исходные html-мнемоники, которые превращаются в два unicode-символа будут превращены обратно в мнемоники каждый
|
4. Все исходные html-мнемоники, которые превращаются в два unicode-символа будут превращены обратно в мнемоники каждый
|
||||||
как отдельный символ. Например, множество собственное другого подмножества `⊊︀` в unicode отображается
|
как отдельный символ. Например, множество собственное другого подмножества `⊊︀` в unicode отображается
|
||||||
двумя символами `\u228a\ufe00` и превратится в `⊊\ufe00`. Символ `\ufe00` — это невидимый символ, cелектор
|
двумя символами `\u228a\ufe00` и превратится в `⊊\ufe00`. Символ `\ufe00` — это невидимый символ, селектор
|
||||||
варианта начертания (Variant Selector), который изменяет начертание предыдущего символа и для него нет
|
варианта начертания (Variant Selector), который изменяет начертание предыдущего символа и для него нет
|
||||||
html-мнемоники. К счастью, в стандарте таких мнемоник (превращающихся в два символа) исчезающе мало и они крайне
|
html-мнемоники. К счастью, в стандарте таких мнемоник (превращающихся в два символа) исчезающе мало и они крайне
|
||||||
редко применляются в тексте, поэтому это не должно вызывать проблем.
|
редко применяются в тексте, поэтому это не должно вызывать проблем.
|
||||||
|
|
||||||
|
|
||||||
### Переносы слов
|
### Переносы слов
|
||||||
@@ -171,7 +170,7 @@ result = typo_hyp.process(text="Электрофоретическое иссл
|
|||||||
слева или справа от кавычки.
|
слева или справа от кавычки.
|
||||||
|
|
||||||
Преобразование рядом с цифрами (например, когда обозначаются дюймы (`17"`) или секунды (`3' 25"`)) не производится. Также
|
Преобразование рядом с цифрами (например, когда обозначаются дюймы (`17"`) или секунды (`3' 25"`)) не производится. Также
|
||||||
не обрабатываются кавычки окруженные пробелами. Все кавычки которые в исходном тексте уже были оформлены в виде
|
не обрабатываются кавычки, окруженные пробелами. Все кавычки, которые в исходном тексте уже были оформлены в виде
|
||||||
«ёлочек» или “лапок” — тоже не обрабатываются.
|
«ёлочек» или “лапок” — тоже не обрабатываются.
|
||||||
|
|
||||||
ВАЖНО1: По правилам орфографии перед закрывающей кавычкой разрешены только определенные знаки препинания:
|
ВАЖНО1: По правилам орфографии перед закрывающей кавычкой разрешены только определенные знаки препинания:
|
||||||
@@ -183,7 +182,7 @@ result = typo_hyp.process(text="Электрофоретическое иссл
|
|||||||
кавычкой.**
|
кавычкой.**
|
||||||
|
|
||||||
ВАЖНО2: Если в настройке типографа указано несколько языков (`langs='ru+en'`), то кавычки будут преобразованы по правилам
|
ВАЖНО2: Если в настройке типографа указано несколько языков (`langs='ru+en'`), то кавычки будут преобразованы по правилам
|
||||||
для языка который идет первым в списке. Например, для `langs='ru+en'` кавычки будут преобразованы в «ёлочки»,
|
для языка, который идет первым в списке. Например, для `langs='ru+en'` кавычки будут преобразованы в «ёлочки».
|
||||||
|
|
||||||
Если при типорафировании преобразование не требуется, то можно обработку кавычек можно отключить с помощью
|
Если при типорафировании преобразование не требуется, то можно обработку кавычек можно отключить с помощью
|
||||||
параметра `quotes=False`:
|
параметра `quotes=False`:
|
||||||
@@ -202,8 +201,8 @@ result = typo_no_quotes.process(text='Этот "текст" будет обра
|
|||||||
|
|
||||||
#### Тире
|
#### Тире
|
||||||
|
|
||||||
По правилам русской типографики, длинное тире (—) должно отбиваться пробелами от соседних слов. Чтобы тире не "повисло"
|
По правилам русской типографики, длинное тире (`—`) должно отбиваться пробелами от соседних слов. Чтобы тире не "повисло"
|
||||||
в начале строки и визуально не смешивалось с диалогами, etpgrf заменяет пробел перед тире на неразрывный ( ).
|
в начале строки и визуально не смешивалось с диалогами, etpgrf заменяет пробел перед тире на неразрывный (` `).
|
||||||
|
|
||||||
* `слово — слово` → `слово — слово`
|
* `слово — слово` → `слово — слово`
|
||||||
|
|
||||||
@@ -227,7 +226,7 @@ result = typo_no_quotes.process(text='Этот "текст" будет обра
|
|||||||
* Неразрывный пробел (` `) ставится между фамилией и инициалом/инициалами (`А. Пушкин` → `А. Пушкин`).
|
* Неразрывный пробел (` `) ставится между фамилией и инициалом/инициалами (`А. Пушкин` → `А. Пушкин`).
|
||||||
Неважно стоят ли инициалы перед фамилией или после неё. Важно наличие точки и буквы (инициала), написанного
|
Неважно стоят ли инициалы перед фамилией или после неё. Важно наличие точки и буквы (инициала), написанного
|
||||||
с заглавной буквы.
|
с заглавной буквы.
|
||||||
* Тонкая шпация ( ) ставится между самими инициалами, если они написаны слитно, для улучшения внешнего вида
|
* Тонкая шпация (` `) ставится между самими инициалами, если они написаны слитно, для улучшения внешнего вида
|
||||||
(`Пушкин А. С. ` → `Пушкин А. С.`). Число инициалов не ограничено (`J.R.R. Tolkien` →
|
(`Пушкин А. С. ` → `Пушкин А. С.`). Число инициалов не ограничено (`J.R.R. Tolkien` →
|
||||||
`J. R. R. Tolkien`), наличие или отсутствие пробелов между инициалами в исходном тексте неважно.
|
`J. R. R. Tolkien`), наличие или отсутствие пробелов между инициалами в исходном тексте неважно.
|
||||||
* Акронимы, написанные через точку (не слитно, например, **Н.Л.О.**), разделяются так же, как инициалы, через тонкую шпацию
|
* Акронимы, написанные через точку (не слитно, например, **Н.Л.О.**), разделяются так же, как инициалы, через тонкую шпацию
|
||||||
@@ -262,7 +261,7 @@ result = typo.process("А. С. Пушкин") # Останется без изм
|
|||||||
```python
|
```python
|
||||||
# Передаем список
|
# Передаем список
|
||||||
typo = etpgrf.Typographer(process_units=['бочек', 'вёдер'])
|
typo = etpgrf.Typographer(process_units=['бочек', 'вёдер'])
|
||||||
# Можно передавать и с помощзью строки через пробелы
|
# Можно передавать и с помощью строки через пробелы
|
||||||
typo = etpgrf.Typographer(process_units='бочек вёдер аршин сажен')
|
typo = etpgrf.Typographer(process_units='бочек вёдер аршин сажен')
|
||||||
result = typo.process("Нужно 10 бочек.") # -> "Нужно 10 бочек."
|
result = typo.process("Нужно 10 бочек.") # -> "Нужно 10 бочек."
|
||||||
```
|
```
|
||||||
@@ -294,7 +293,7 @@ result = typo.process("100 км/ч") # Останется без
|
|||||||
### Висячая типографика
|
### Висячая типографика
|
||||||
|
|
||||||
Висячая типографика — это приём из классической вёрстки, когда некоторые знаки препинания (кавычки, скобки, иногда
|
Висячая типографика — это приём из классической вёрстки, когда некоторые знаки препинания (кавычки, скобки, иногда
|
||||||
tире и маркеры списков) выносятся на левое (и иногда и по правому) поле текста. Это создаёт идеально ровный край не по
|
тире и маркеры списков) выносятся на левое (и иногда и по правому) поле текста. Это создаёт идеально ровный край не по
|
||||||
формальным границам знаков, а по оптическому краю — по первым буквам строк. Текст выглядит гораздо аккуратнее и
|
формальным границам знаков, а по оптическому краю — по первым буквам строк. Текст выглядит гораздо аккуратнее и
|
||||||
профессиональнее.
|
профессиональнее.
|
||||||
|
|
||||||
@@ -308,7 +307,7 @@ Safari), поэтому на него полагаться нельзя. Поэ
|
|||||||
Оборачивая "висячий" символ или слово в `<span>` и применяя к нему, например, отрицательный `text-indent` или
|
Оборачивая "висячий" символ или слово в `<span>` и применяя к нему, например, отрицательный `text-indent` или
|
||||||
`margin-left` (`<span style="margin-left:-0.44em">«</span>`), мы можем сместить сам символ, но нужно ещё и
|
`margin-left` (`<span style="margin-left:-0.44em">«</span>`), мы можем сместить сам символ, но нужно ещё и
|
||||||
сохранить расстояние до соседнего слова. Поэтому типограф оборачивает не только сам висячий символ, но и ближайшее слово
|
сохранить расстояние до соседнего слова. Поэтому типограф оборачивает не только сам висячий символ, но и ближайшее слово
|
||||||
(до пробела или границы узла), а также, при необходимости, окружающий пробел. Сама визуальная компенсация оформляется через
|
(до пробела или границы узла), а также при необходимости, окружающий пробел. Сама визуальная компенсация оформляется через
|
||||||
отрицательные `margin`/`padding` в CSS-классах — никаких `position:absolute`, чтобы не нарушать поток текста.
|
отрицательные `margin`/`padding` в CSS-классах — никаких `position:absolute`, чтобы не нарушать поток текста.
|
||||||
|
|
||||||
По умолчанию эта функция висячей типографики **отключена**. Чтобы её включить, нужно задать параметр
|
По умолчанию эта функция висячей типографики **отключена**. Чтобы её включить, нужно задать параметр
|
||||||
@@ -327,7 +326,7 @@ typo = etpgrf.Typographer(hanging_punctuation='left')
|
|||||||
с размещением пробелов и делает невозможным контролировать визуальное выравнивание (см. блок про `text-justify`).
|
с размещением пробелов и делает невозможным контролировать визуальное выравнивание (см. блок про `text-justify`).
|
||||||
|
|
||||||
Также через `hanging_punctuation` можно задать список тегов, внутри которых висячая типографика будет применяться
|
Также через `hanging_punctuation` можно задать список тегов, внутри которых висячая типографика будет применяться
|
||||||
(всегда в режиме `'both'`). Это нерекомендованный способ, потому что он предполагает знание структуры HTML и неизбежно
|
(всегда в режиме `'both'`). Это не рекомендованный способ, потому что он предполагает знание структуры HTML и неизбежно
|
||||||
выпадает из общей логики вложенности и пробельных узлов.
|
выпадает из общей логики вложенности и пробельных узлов.
|
||||||
|
|
||||||
### Как работает оборачивание
|
### Как работает оборачивание
|
||||||
@@ -340,7 +339,7 @@ typo = etpgrf.Typographer(hanging_punctuation='left')
|
|||||||
слово (`<span class="etp-laquo">«АукЫон»</span>`);
|
слово (`<span class="etp-laquo">«АукЫон»</span>`);
|
||||||
* если перед символом внутри узла есть пробел, то пробел оборачивается в `<span class="etp-sp-laquo"> </span>`, а
|
* если перед символом внутри узла есть пробел, то пробел оборачивается в `<span class="etp-sp-laquo"> </span>`, а
|
||||||
символ вместе со словом — в `<span class="etp-laquo">...</span>`;
|
символ вместе со словом — в `<span class="etp-laquo">...</span>`;
|
||||||
* если пробел оказалось в соседнем узле, то он тоже оборачивается в `etp-sp-*`, чтобы не нарушить последовательность;
|
* если пробел оказался в соседнем узле, то он тоже оборачивается в `etp-sp-*`, чтобы не нарушить последовательность;
|
||||||
* если компенсирующий пробел является "непереносимым пробелом" (или любым другим: шпацией, em-пробелом и т.п.), то тогда, для правильного выравнивания, оборачивается он, например: `<span class="etp-sp-laquo"> </span><span class="etp-laquo">«АукЫон»</span>`.
|
* если компенсирующий пробел является "непереносимым пробелом" (или любым другим: шпацией, em-пробелом и т.п.), то тогда, для правильного выравнивания, оборачивается он, например: `<span class="etp-sp-laquo"> </span><span class="etp-laquo">«АукЫон»</span>`.
|
||||||
* Для `hanging_punctuation='right'`:
|
* Для `hanging_punctuation='right'`:
|
||||||
* слово с висячим символом оборачивается в соответствующий класс (`.etp-raquo`, `.etp-rpar` и т.д.);
|
* слово с висячим символом оборачивается в соответствующий класс (`.etp-raquo`, `.etp-rpar` и т.д.);
|
||||||
@@ -391,7 +390,7 @@ typo = etpgrf.Typographer(hanging_punctuation='left')
|
|||||||
|
|
||||||
При обработке сложного HTML-кода типограф стремится сохранить структуру документа, но некоторые пограничные случаи могут обрабатываться не так, как ожидается. В частности:
|
При обработке сложного HTML-кода типограф стремится сохранить структуру документа, но некоторые пограничные случаи могут обрабатываться не так, как ожидается. В частности:
|
||||||
|
|
||||||
* **Обработка на стыке тегов:** Правила, требующие анализа контекста (например, расстановка неразрывных пробелов у тире или единиц измерения), могут работать некорректно, если анализируемые части текста разделены тегами . Например, конструкция `$<b>100</b>` не будет обработана (между $ и 100 не будет вставлен неразрывный пробел), так как типограф не видит их как соседние элементы.
|
* **Обработка на стыке тегов:** Правила, требующие анализа контекста (например, расстановка неразрывных пробелов у тире или единиц измерения), могут работать некорректно, если анализируемые части текста разделены тегами. Например, конструкция `$<b>100</b>` не будет обработана (между $ и 100 не будет вставлен неразрывный пробел), так как типограф не видит их как соседние элементы.
|
||||||
* **"Ремонт" HTML:** Библиотека использует `BeautifulSoup` для парсинга, который может "чинить" невалидный HTML (например, закрывать незакрытые теги). Это может привести к неожиданным изменениям в структуре, если исходный код был некорректен. Так же может меняться порядок атрибутов тега.
|
* **"Ремонт" HTML:** Библиотека использует `BeautifulSoup` для парсинга, который может "чинить" невалидный HTML (например, закрывать незакрытые теги). Это может привести к неожиданным изменениям в структуре, если исходный код был некорректен. Так же может меняться порядок атрибутов тега.
|
||||||
|
|
||||||
Мы знаем об этих особенностях и работаем над улучшением алгоритмов для более точной обработки сложных случаев.
|
Мы знаем об этих особенностях и работаем над улучшением алгоритмов для более точной обработки сложных случаев.
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ TYPOGRAPHER_HTML_TEST_CASES = [
|
|||||||
f'<p>Он{CHAR_NBSP}сказал: «В{CHAR_NBSP}1941{CHAR_NDASH}1945{CHAR_NBSP}гг.{CHAR_NBSP}{CHAR_NDASH} было'
|
f'<p>Он{CHAR_NBSP}сказал: «В{CHAR_NBSP}1941{CHAR_NDASH}1945{CHAR_NBSP}гг.{CHAR_NBSP}{CHAR_NDASH} было'
|
||||||
f' 100{CHAR_NBSP}тыс.{CHAR_THIN_SP}руб. и{CHAR_NBSP}т.{CHAR_THIN_SP}д.»</p>'),
|
f' 100{CHAR_NBSP}тыс.{CHAR_THIN_SP}руб. и{CHAR_NBSP}т.{CHAR_THIN_SP}д.»</p>'),
|
||||||
# --- Теги внутри кавычек ---
|
# --- Теги внутри кавычек ---
|
||||||
('mnemonic', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы требующие ответа.</p>',
|
('mnemonic', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы, требующие ответа.</p>',
|
||||||
'<p>«<u>Почему</u>», «<u>зачем</u>» и «<u>кому это выгодно</u>'
|
'<p>«<u>Почему</u>», «<u>зачем</u>» и «<u>кому это выгодно</u>'
|
||||||
'» – вопросы требующие ответа.</p>'),
|
'» – вопросы, требующие ответа.</p>'),
|
||||||
('mixed', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы требующие ответа.</p>',
|
('mixed', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы требующие ответа.</p>',
|
||||||
'<p>«<u>Почему</u>», «<u>зачем</u>» и «<u>кому это выгодно</u>» – вопросы требующие ответа.</p>'),
|
'<p>«<u>Почему</u>», «<u>зачем</u>» и «<u>кому это выгодно</u>» – вопросы требующие ответа.</p>'),
|
||||||
('unicode', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы требующие ответа.</p>',
|
('unicode', '<p>"<u>Почему</u>", "<u>зачем</u>" и "<u>кому это выгодно</u>" -- вопросы требующие ответа.</p>',
|
||||||
@@ -86,7 +86,7 @@ TYPOGRAPHER_HTML_TEST_CASES = [
|
|||||||
|
|
||||||
# --- Самозакрывающиеся теги и теги с атрибутами ---
|
# --- Самозакрывающиеся теги и теги с атрибутами ---
|
||||||
# ВАЖНО: 1. Порядок атрибутов в типографированном тексте может быть произвольным
|
# ВАЖНО: 1. Порядок атрибутов в типографированном тексте может быть произвольным
|
||||||
# 2. Любое число пробельных символов внутри "пустых" тегов будут редуцированы до одного пробела или
|
# 2. Любое число пробельных символов внутри "пустых" тегов будет редуцировано до одного пробела или
|
||||||
# перевода строки.
|
# перевода строки.
|
||||||
# 3. Самозакрывающиеся теги будут приведены к единому виду с косой чертой в конце. Типа <br/>
|
# 3. Самозакрывающиеся теги будут приведены к единому виду с косой чертой в конце. Типа <br/>
|
||||||
# 4. Все это "проделки" связаны с использованием библиотеки BeautifulSoup для парсинга HTML,
|
# 4. Все это "проделки" связаны с использованием библиотеки BeautifulSoup для парсинга HTML,
|
||||||
|
|||||||
Reference in New Issue
Block a user