[ADD] подсветка синтаксиса C и C++ в листингах

This commit is contained in:
Arseny
2026-09-02 13:05:05 +03:00
parent 7f20bd9831
commit a3d41af022
3 changed files with 41 additions and 6 deletions
+2 -2
View File
@@ -15,8 +15,8 @@ _CAPTION_RE = re.compile(r"^\s*Листинг\s+\d+\s*[—–-]+\s*(.+?)\s*$")
# подсветки код набирается моноширинным без выделения ключевых слов. # подсветки код набирается моноширинным без выделения ключевых слов.
_LANGUAGES = { _LANGUAGES = {
"c": "C", "c": "C",
"c++": "C++", "c++": "[modern]C++",
"cpp": "C++", "cpp": "[modern]C++",
"bash": "bash", "bash": "bash",
"sh": "bash", "sh": "bash",
"shell": "bash", "shell": "bash",
+30 -1
View File
@@ -29,15 +29,44 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle}
\captionsetup[figure]{labelsep=emdash,font=onehalfspacing,position=bottom,name=Рисунок} \captionsetup[figure]{labelsep=emdash,font=onehalfspacing,position=bottom,name=Рисунок}
\captionsetup[table]{labelsep=emdash,font=onehalfspacing,position=top,name=Таблица,singlelinecheck=false,justification=raggedright} \captionsetup[table]{labelsep=emdash,font=onehalfspacing,position=top,name=Таблица,singlelinecheck=false,justification=raggedright}
\usepackage{listings} \usepackage{listings}
\usepackage{xcolor}
% Палитра подсветки. Тона различаются не только цветом, но и светлотой,
% поэтому листинг остаётся читаемым и на чёрно-белой печати.
\definecolor{lstkeyword}{RGB}{0,0,139}
\definecolor{lstcomment}{RGB}{110,110,110}
\definecolor{lststring}{RGB}{139,0,0}
\definecolor{lstnumber}{RGB}{0,100,0}
\definecolor{lstlineno}{RGB}{130,130,130}
% Встроенный диалект C++ в listings старше стандарта: auto, nullptr, override
% и прочее он не знает. Расширяем его, а не подменяем, чтобы сохранить разбор
% строк, комментариев и препроцессора.
\lstdefinelanguage[modern]{C++}[ISO]{C++}{%
morekeywords={%
auto,nullptr,constexpr,consteval,constinit,noexcept,override,final,%
decltype,static_assert,thread_local,alignas,alignof,concept,requires,%
co_await,co_yield,co_return,import,module,%
Q_OBJECT,Q_SLOTS,Q_SIGNALS,Q_PROPERTY,signals,slots,emit%
}%
}
\lstset{ \lstset{
basicstyle=\ttfamily\small\setstretch{1.0}, basicstyle=\ttfamily\small\setstretch{1.0},
keywordstyle=\bfseries\color{lstkeyword},
% Начертание прямое: курсива кириллицы в моноширинном шрифте нет, и
% комментарий распадался бы на прямые русские и курсивные латинские слова.
commentstyle=\color{lstcomment},
stringstyle=\color{lststring},
numberstyle=\tiny\color{lstlineno},
directivestyle=\color{lstnumber},
identifierstyle=,
breakatwhitespace=false, breakatwhitespace=false,
breaklines=true, breaklines=true,
captionpos=t, captionpos=t,
inputencoding=utf8, inputencoding=utf8,
frame=single, frame=single,
keepspaces=true, keepspaces=true,
keywordstyle=\bf,
numbers=left, numbers=left,
numbersep=5pt, numbersep=5pt,
xleftmargin=25pt, xleftmargin=25pt,
+9 -3
View File
@@ -334,7 +334,7 @@ LISTING_MD = (
def test_listing_with_caption() -> None: def test_listing_with_caption() -> None:
tex = render(LISTING_MD) tex = render(LISTING_MD)
assert "caption={Потокобезопасная очередь}" in tex assert "caption={Потокобезопасная очередь}" in tex
assert "language=C++" in tex assert "language=[modern]C++" in tex
assert "class ThreadSafeQueue {};" in tex assert "class ThreadSafeQueue {};" in tex
@@ -350,7 +350,7 @@ def test_listing_caption_paragraph_is_not_duplicated() -> None:
def test_listing_without_caption_stays_bare() -> None: def test_listing_without_caption_stays_bare() -> None:
tex = render("```cpp\nint main() {}\n```\n") tex = render("```cpp\nint main() {}\n```\n")
assert "\\begin{lstlisting}[language=C++]" in tex assert "\\begin{lstlisting}[language=[modern]C++]" in tex
assert "caption=" not in tex assert "caption=" not in tex
@@ -369,7 +369,7 @@ def test_paragraph_starting_with_listing_word_is_not_a_caption() -> None:
def test_listing_language_is_mapped_to_listings_name() -> None: def test_listing_language_is_mapped_to_listings_name() -> None:
"""listings не знает 'cpp', только 'C++'.""" """listings не знает 'cpp', только 'C++'."""
tex = render("```cpp\nint x;\n```\n") tex = render("```cpp\nint x;\n```\n")
assert "language=C++" in tex assert "language=[modern]C++" in tex
def test_listing_unsupported_language_falls_back_to_plain() -> None: def test_listing_unsupported_language_falls_back_to_plain() -> None:
@@ -480,3 +480,9 @@ def test_abbreviation_table_has_no_extra_column_padding() -> None:
"""Отбивка между колонками добавляется к \\linewidth и роняет строку за поле.""" """Отбивка между колонками добавляется к \\linewidth и роняет строку за поле."""
tex = body(render(ABBR_MD)) tex = body(render(ABBR_MD))
assert "@{}p{\\dimexpr\\linewidth" in tex assert "@{}p{\\dimexpr\\linewidth" in tex
def test_cpp_uses_extended_dialect() -> None:
"""Встроенный C++ в listings не знает auto, nullptr и override."""
tex = body(render("```cpp\nauto x = nullptr;\n```\n"))
assert "language=[modern]C++" in tex