From a3d41af0221b7e58768fffb4267940c362a107ac Mon Sep 17 00:00:00 2001 From: Arseny <20096ninja@gmail.com> Date: Wed, 2 Sep 2026 13:05:05 +0300 Subject: [PATCH] =?UTF-8?q?[ADD]=20=D0=BF=D0=BE=D0=B4=D1=81=D0=B2=D0=B5?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=81=D0=B8=D0=BD=D1=82=D0=B0=D0=BA=D1=81?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=20C=20=D0=B8=20C++=20=D0=B2=20=D0=BB=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D0=BD=D0=B3=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- md2gost/handlers/code.py | 4 ++-- md2gost/latex/preamble.py | 31 ++++++++++++++++++++++++++++++- tests/test_render.py | 12 +++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/md2gost/handlers/code.py b/md2gost/handlers/code.py index c30e17e..44314bd 100644 --- a/md2gost/handlers/code.py +++ b/md2gost/handlers/code.py @@ -15,8 +15,8 @@ _CAPTION_RE = re.compile(r"^\s*Листинг\s+\d+\s*[—–-]+\s*(.+?)\s*$") # подсветки код набирается моноширинным без выделения ключевых слов. _LANGUAGES = { "c": "C", - "c++": "C++", - "cpp": "C++", + "c++": "[modern]C++", + "cpp": "[modern]C++", "bash": "bash", "sh": "bash", "shell": "bash", diff --git a/md2gost/latex/preamble.py b/md2gost/latex/preamble.py index 1c1eacc..53229bf 100644 --- a/md2gost/latex/preamble.py +++ b/md2gost/latex/preamble.py @@ -29,15 +29,44 @@ PREAMBLE = r"""\documentclass[a4paper, 14pt]{extarticle} \captionsetup[figure]{labelsep=emdash,font=onehalfspacing,position=bottom,name=Рисунок} \captionsetup[table]{labelsep=emdash,font=onehalfspacing,position=top,name=Таблица,singlelinecheck=false,justification=raggedright} \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{ 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, breaklines=true, captionpos=t, inputencoding=utf8, frame=single, keepspaces=true, - keywordstyle=\bf, numbers=left, numbersep=5pt, xleftmargin=25pt, diff --git a/tests/test_render.py b/tests/test_render.py index 407fa40..70b7a5f 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -334,7 +334,7 @@ LISTING_MD = ( def test_listing_with_caption() -> None: tex = render(LISTING_MD) assert "caption={Потокобезопасная очередь}" in tex - assert "language=C++" in tex + assert "language=[modern]C++" 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: 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 @@ -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: """listings не знает 'cpp', только 'C++'.""" 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: @@ -480,3 +480,9 @@ def test_abbreviation_table_has_no_extra_column_padding() -> None: """Отбивка между колонками добавляется к \\linewidth и роняет строку за поле.""" tex = body(render(ABBR_MD)) 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