[FIX] отбивки заголовков, маркер переноса строк кода, неразрывные инициалы
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from markdown_it.token import Token
|
from markdown_it.token import Token
|
||||||
@@ -32,9 +33,25 @@ def escape_latex(text: str) -> str:
|
|||||||
return text.translate(_LATEX_SPECIAL)
|
return text.translate(_LATEX_SPECIAL)
|
||||||
|
|
||||||
|
|
||||||
|
# Инициалы не должны отрываться друг от друга и от фамилии переносом строки:
|
||||||
|
# «/ И.» на одной строке и «В. Гилев» на следующей — ошибка оформления списка
|
||||||
|
# источников. Связывается одиночная заглавная буква с точкой и следующее слово,
|
||||||
|
# начинающееся с заглавной.
|
||||||
|
_INITIALS_RE = re.compile(r"(?<![\w.])([A-ZА-ЯЁ]\.)\s+(?=[A-ZА-ЯЁ])")
|
||||||
|
|
||||||
|
|
||||||
|
def bind_initials(text: str) -> str:
|
||||||
|
"""Заменить пробел после инициала на неразрывный."""
|
||||||
|
previous = None
|
||||||
|
while previous != text:
|
||||||
|
previous = text
|
||||||
|
text = _INITIALS_RE.sub(r"\1~", text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
@inline("text")
|
@inline("text")
|
||||||
def _text(tok: Token) -> str:
|
def _text(tok: Token) -> str:
|
||||||
return escape_latex(tok.content)
|
return bind_initials(escape_latex(tok.content))
|
||||||
|
|
||||||
|
|
||||||
@inline("strong_open")
|
@inline("strong_open")
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
% комментарий распадался бы на прямые русские и курсивные латинские слова.
|
% комментарий распадался бы на прямые русские и курсивные латинские слова.
|
||||||
commentstyle=\color{lstcomment},
|
commentstyle=\color{lstcomment},
|
||||||
stringstyle=\color{lststring},
|
stringstyle=\color{lststring},
|
||||||
numberstyle=\tiny\color{lstlineno},
|
numberstyle=\scriptsize\color{lstlineno},
|
||||||
identifierstyle=,
|
identifierstyle=,
|
||||||
breakatwhitespace=false,
|
breakatwhitespace=false,
|
||||||
breaklines=true,
|
breaklines=true,
|
||||||
@@ -67,7 +67,10 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
frame=single,
|
frame=single,
|
||||||
keepspaces=true,
|
keepspaces=true,
|
||||||
numbers=left,
|
numbers=left,
|
||||||
numbersep=5pt,
|
numbersep=7pt,
|
||||||
|
aboveskip=0.7\baselineskip,
|
||||||
|
belowskip=0.4\baselineskip,
|
||||||
|
postbreak=\mbox{\textcolor{lstlineno}{$\hookrightarrow$}\space},
|
||||||
xleftmargin=25pt,
|
xleftmargin=25pt,
|
||||||
xrightmargin=25pt,
|
xrightmargin=25pt,
|
||||||
showspaces=false,
|
showspaces=false,
|
||||||
@@ -91,9 +94,9 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
\titleformat{\section}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesection. }
|
\titleformat{\section}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesection. }
|
||||||
\titleformat{\subsection}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesubsection. }
|
\titleformat{\subsection}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesubsection. }
|
||||||
\titleformat{\subsubsection}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesubsubsection. }
|
\titleformat{\subsubsection}{\fontsize{14pt}{18pt}\selectfont\bfseries}{}{0em}{\thesubsubsection. }
|
||||||
\titlespacing*{\section}{1.25cm}{0.5ex plus 0.2ex minus 0.2ex}{0.3ex plus 0.1ex minus 0.1ex}
|
\titlespacing*{\section}{1.25cm}{1ex plus 0.3ex minus 0.2ex}{0.6ex plus 0.2ex minus 0.1ex}
|
||||||
\titlespacing*{\subsection}{1.25cm}{0.5ex plus 0.2ex minus 0.2ex}{0.3ex plus 0.1ex minus 0.1ex}
|
\titlespacing*{\subsection}{1.25cm}{1ex plus 0.3ex minus 0.2ex}{0.6ex plus 0.2ex minus 0.1ex}
|
||||||
\titlespacing*{\subsubsection}{1.25cm}{0.5ex plus 0.2ex minus 0.2ex}{0.3ex plus 0.1ex minus 0.1ex}
|
\titlespacing*{\subsubsection}{1.25cm}{1ex plus 0.3ex minus 0.2ex}{0.6ex plus 0.2ex minus 0.1ex}
|
||||||
\usepackage{tocloft}
|
\usepackage{tocloft}
|
||||||
\addto\captionsrussian{%
|
\addto\captionsrussian{%
|
||||||
\renewcommand{\contentsname}{СОДЕРЖАНИЕ}%
|
\renewcommand{\contentsname}{СОДЕРЖАНИЕ}%
|
||||||
|
|||||||
@@ -498,3 +498,14 @@ def test_bare_listing_does_not_float() -> None:
|
|||||||
"""Фрагмент без подписи — часть абзаца, ему плавать незачем."""
|
"""Фрагмент без подписи — часть абзаца, ему плавать незачем."""
|
||||||
tex = body(render("```cpp\nint x;\n```\n"))
|
tex = body(render("```cpp\nint x;\n```\n"))
|
||||||
assert "float=" not in tex
|
assert "float=" not in tex
|
||||||
|
|
||||||
|
|
||||||
|
def test_initials_are_not_split_across_lines() -> None:
|
||||||
|
"""«/ И.» на одной строке и «В. Гилев» на следующей — ошибка оформления."""
|
||||||
|
tex = body(render("Гилев, И. В. Использование технологии SDR.\n"))
|
||||||
|
assert "И.~В.~Использование" in tex
|
||||||
|
|
||||||
|
|
||||||
|
def test_lowercase_abbreviation_is_left_alone() -> None:
|
||||||
|
tex = body(render("В 3 т., Воронеж, 2025.\n"))
|
||||||
|
assert "т.~Воронеж" not in tex
|
||||||
|
|||||||
Reference in New Issue
Block a user