[FIX] шапка титульника, ширина номера в оглавлении и перечень сокращений в пределах поля
This commit is contained in:
@@ -39,9 +39,14 @@ def abbreviations(text: str) -> str:
|
|||||||
for abbr, desc in rows:
|
for abbr, desc in rows:
|
||||||
pad = max_abbr - len(abbr) + 2
|
pad = max_abbr - len(abbr) + 2
|
||||||
tabular_rows.append(
|
tabular_rows.append(
|
||||||
f"{abbr} {' ' * pad}& \\hangafter=1\\hangindent=2em ------ {desc} \\\\"
|
f"{abbr} {' ' * pad}& \\hangafter=1\\hangindent=2em --- {desc} \\\\"
|
||||||
)
|
)
|
||||||
|
|
||||||
col_spec = f"@{{\\hspace{{0pt}}}}p{{{abbr_col}em}}@{{\\hspace{{0pt}}}}p{{\\dimexpr\\linewidth-{abbr_col}em\\relax}}"
|
# Отбивки колонок убраны с обеих сторон и между ними: иначе сумма ширин
|
||||||
|
# превышает \linewidth на 2\tabcolsep и перечень выходит за правое поле.
|
||||||
|
col_spec = (
|
||||||
|
f"@{{\\hspace{{0pt}}}}p{{{abbr_col}em}}"
|
||||||
|
f"@{{}}p{{\\dimexpr\\linewidth-{abbr_col}em\\relax}}@{{\\hspace{{0pt}}}}"
|
||||||
|
)
|
||||||
body = "\n".join(tabular_rows)
|
body = "\n".join(tabular_rows)
|
||||||
return f"\\noindent\\begin{{tabular}}{{{col_spec}}}\n{body}\n\\end{{tabular}}"
|
return f"\\noindent\\begin{{tabular}}{{{col_spec}}}\n{body}\n\\end{{tabular}}"
|
||||||
|
|||||||
@@ -84,12 +84,15 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
\renewcommand{\cftsecpagefont}{\mdseries}
|
\renewcommand{\cftsecpagefont}{\mdseries}
|
||||||
\renewcommand{\cftsubsecfont}{\mdseries}
|
\renewcommand{\cftsubsecfont}{\mdseries}
|
||||||
\renewcommand{\cftsubsubsecfont}{\mdseries}
|
\renewcommand{\cftsubsubsecfont}{\mdseries}
|
||||||
|
% Ширина поля номера в оглавлении измеряется по шрифту, а не задаётся
|
||||||
|
% константой: при фиксированных 1.5em номер 2.10. не помещается и печатается
|
||||||
|
% поверх названия главы, а у остальных пропадает пробел после точки.
|
||||||
\setlength{\cftsecindent}{0em}
|
\setlength{\cftsecindent}{0em}
|
||||||
\setlength{\cftsecnumwidth}{1em}
|
|
||||||
\setlength{\cftsubsecindent}{0em}
|
\setlength{\cftsubsecindent}{0em}
|
||||||
\setlength{\cftsubsecnumwidth}{1.5em}
|
|
||||||
\setlength{\cftsubsubsecindent}{0em}
|
\setlength{\cftsubsubsecindent}{0em}
|
||||||
\setlength{\cftsubsubsecnumwidth}{2.1em}
|
\settowidth{\cftsecnumwidth}{\cftsecfont 9.\enspace}
|
||||||
|
\settowidth{\cftsubsecnumwidth}{\cftsubsecfont 9.99.\enspace}
|
||||||
|
\settowidth{\cftsubsubsecnumwidth}{\cftsubsubsecfont 9.99.99.\enspace}
|
||||||
|
|
||||||
\newcommand{\sigline}[3][4cm]{%
|
\newcommand{\sigline}[3][4cm]{%
|
||||||
\begin{tabular}[t]{@{}c@{}}%
|
\begin{tabular}[t]{@{}c@{}}%
|
||||||
@@ -99,6 +102,17 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
\end{tabular}%
|
\end{tabular}%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
% Ширины шапки титульного листа. Колонка эмблемы задаётся явно, ширина
|
||||||
|
% текстовой части — остаток от текстового поля за вычетом рамки и отбивок,
|
||||||
|
% поэтому шапка не может вылезти за рамку при смене полей страницы.
|
||||||
|
\newlength{\ptpemblemwidth}
|
||||||
|
\newlength{\ptpheadwidth}
|
||||||
|
\newlength{\ptpheadpad}
|
||||||
|
\setlength{\ptpemblemwidth}{0.14\textwidth}
|
||||||
|
\setlength{\ptpheadpad}{4pt}
|
||||||
|
\setlength{\ptpheadwidth}{%
|
||||||
|
\dimexpr\textwidth-\ptpemblemwidth-4\ptpheadpad-3\arrayrulewidth\relax}
|
||||||
|
|
||||||
\newcommand{\ptpfieldw}[4][4.5cm]{%
|
\newcommand{\ptpfieldw}[4][4.5cm]{%
|
||||||
\par\noindent
|
\par\noindent
|
||||||
\makebox[#1][l]{#2}%
|
\makebox[#1][l]{#2}%
|
||||||
@@ -113,7 +127,10 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
|
|||||||
\newcommand{\ptpfieldnote}[4][4.5cm]{%
|
\newcommand{\ptpfieldnote}[4][4.5cm]{%
|
||||||
\ptpfield[#1]{#2}{#3}%
|
\ptpfield[#1]{#2}{#3}%
|
||||||
\par\vspace{-0.45em}%
|
\par\vspace{-0.45em}%
|
||||||
\hspace*{#1}\makebox[\dimexpr\textwidth-#1\relax][c]{\footnotesize\itshape #4}\par}
|
% \noindent обязателен: иначе к строке подписи прибавляется абзацный отступ,
|
||||||
|
% и она ровно на \parindent выходит за правое поле.
|
||||||
|
\noindent\hspace*{#1}%
|
||||||
|
\makebox[\dimexpr\textwidth-#1\relax][c]{\footnotesize\itshape #4}\par}
|
||||||
|
|
||||||
\newcommand{\ptpfieldpar}[3][4.5cm]{%
|
\newcommand{\ptpfieldpar}[3][4.5cm]{%
|
||||||
\par\noindent
|
\par\noindent
|
||||||
|
|||||||
@@ -27,13 +27,14 @@ def render(fm: dict[str, str]) -> str:
|
|||||||
"% --- Шапка в рамке с разделителем, как в бланке ---\n"
|
"% --- Шапка в рамке с разделителем, как в бланке ---\n"
|
||||||
"\\vspace*{-45pt}\n"
|
"\\vspace*{-45pt}\n"
|
||||||
"\\noindent\\begin{tabular}"
|
"\\noindent\\begin{tabular}"
|
||||||
"{|@{\\hspace{4pt}}c@{\\hspace{4pt}}|@{\\hspace{4pt}}c@{\\hspace{4pt}}|}\n"
|
"{|@{\\hspace{\\ptpheadpad}}c@{\\hspace{\\ptpheadpad}}"
|
||||||
|
"|@{\\hspace{\\ptpheadpad}}c@{\\hspace{\\ptpheadpad}}|}\n"
|
||||||
"\\hline\n"
|
"\\hline\n"
|
||||||
"\\begin{minipage}{0.16\\textwidth}\\centering\\vspace{3pt}\n"
|
"\\begin{minipage}{\\ptpemblemwidth}\\centering\\vspace{3pt}\n"
|
||||||
"\\includegraphics[width=0.92\\textwidth]{emblem}\n"
|
"\\includegraphics[width=0.92\\textwidth]{emblem}\n"
|
||||||
"\\vspace{3pt}\\end{minipage}\n"
|
"\\vspace{3pt}\\end{minipage}\n"
|
||||||
"&\n"
|
"&\n"
|
||||||
"\\begin{minipage}{0.775\\textwidth}\\small\\bfseries\n"
|
"\\begin{minipage}{\\ptpheadwidth}\\small\\bfseries\n"
|
||||||
"\\vspace*{2pt}\n"
|
"\\vspace*{2pt}\n"
|
||||||
f"{ministry_lines(fm)}\n"
|
f"{ministry_lines(fm)}\n"
|
||||||
"\\vspace*{0.5ex}\n"
|
"\\vspace*{0.5ex}\n"
|
||||||
|
|||||||
@@ -460,3 +460,23 @@ def test_all_short_columns_stay_plain_tabular() -> None:
|
|||||||
tex = body(render("| a | b |\n| :--- | :--- |\n| ping | сервер |\n"))
|
tex = body(render("| a | b |\n| :--- | :--- |\n| ping | сервер |\n"))
|
||||||
assert "\\begin{tabular}{|l|l|}" in tex
|
assert "\\begin{tabular}{|l|l|}" in tex
|
||||||
assert "\\begin{tabularx}" not in tex
|
assert "\\begin{tabularx}" not in tex
|
||||||
|
|
||||||
|
|
||||||
|
ABBR_MD = (
|
||||||
|
"# ПЕРЕЧЕНЬ ПРИНЯТЫХ СОКРАЩЕНИЙ\n\n"
|
||||||
|
"SDR — Software-Defined Radio — программно-определяемая радиосистема\n"
|
||||||
|
"PSO — Particle Swarm Optimisation — метод роевой оптимизации\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_abbreviation_dash_is_single() -> None:
|
||||||
|
"""Шесть дефисов дают в LaTeX два длинных тире подряд вместо одного."""
|
||||||
|
tex = body(render(ABBR_MD))
|
||||||
|
assert "------" not in tex
|
||||||
|
assert "--- Software-Defined Radio" in tex
|
||||||
|
|
||||||
|
|
||||||
|
def test_abbreviation_table_has_no_extra_column_padding() -> None:
|
||||||
|
"""Отбивка между колонками добавляется к \\linewidth и роняет строку за поле."""
|
||||||
|
tex = body(render(ABBR_MD))
|
||||||
|
assert "@{}p{\\dimexpr\\linewidth" in tex
|
||||||
|
|||||||
Reference in New Issue
Block a user