Скрытие комментариев Python с помощью Listings

Скрытие комментариев Python с помощью Listings

Я хочу включить код Python, который будет отформатирован с помощью листингов, но я просто хочу, чтобы код был аккуратным и компактным. Комментарии вообще не должны печататься, как и пустые строки.

TheлегкийВыходом было бы убрать комментарии из кода, но это обход проблемы и не поиск решения. Мне нужно решение. Решение означало бы, что мне НЕ нужно редактировать исходный файл, который импортируется.

Я попробовал следующее:

Подход 1

\lstdefinestyle{py_without_comments}{%
    language     = python,
    morecomment  = [l][\nullfont]{\#},
    emptylines   = *1,
}

Который не печатает комментарии, но строки остаются там с тех пор, как текст достигает вывода, просто LaTeX печатает его с помощью nullfont.

Подход 2

\lstdefinestyle{py_without_comments}{%
    language     = python,
    morecomment  = [is]{\#}{\^^M},
    emptylines   = *1,
}

Подход 2 игнорирует все строки комментариев от #до конца строки. Проблема в том, что конец строки также исчезает! Допустим, у вас есть этот код:

def foo():
    if cond1: bar() #Some explanation
    if cond2: baz() #Some other explanation
    if cond3: bye() #Even more explanations

Это будет напечатано так:

def foo():
    if cond1: bar()        if cond2: baz()        if cond3: bye()

Что нежелательно, нетипично и некрасиво.

Подход 3

\lstdefinestyle{py_without_comments}{%
    language     = python,
    morecomment  = [il]{\#},
    emptylines   = *1,
}

Этот код должен работать как часы, но по какой-то причине он стирает весь код из первого комментария (см. foo()пример).

Поэтому я ищу что-то еще, чтобы попробовать. Может ли быть, что это невозможно с листингами?

Заранее спасибо и привет.


Редактировать 1:

MWE можно найтиздесь

решение1

Вот что работает. Оно играет с некоторыми listingsвнутренними компонентами. Я не уверен, есть ли лучшее решение. Использование разделителя конца строки (ваш подход 2 выше) и добавление его обратно, если строка не пустая, похоже, не работает.

\documentclass[11pt]{article}
\usepackage{xcolor}
\usepackage{listings}

% Default settings.
\lstset{
  basicstyle=\ttfamily,
  numbers=left,
  numbersep=5pt,
  numberstyle=\tiny\color{gray},
  rulecolor=\color{black},
}

% The \incomment macro and auxiliary stuff.
\newif\ifnocomment
\newif\ifemptyline
\makeatletter
% When a line starts, it's empty and we're not in a comment.
\lst@AddToHook{InitVarsBOL}{\global\emptylinetrue\global\nocommenttrue}
% When something is printed, the line is not empty.
\lst@AddToHook{PostOutput}{\global\emptylinefalse}
% When we're in a comment...
\def\incomment#1{%
  % if we just entered...
  \ifnocomment%
    \global\nocommentfalse%
    % and the line is empty, then remove this line.
    \ifemptyline\global\advance\lst@newlines\m@ne\fi%
  \fi}
\makeatother

\lstdefinestyle{python_without_comments}{%
  language=python,
  morecomment=[l][\incomment]{\#},
}

\begin{document}
\begin{lstlisting}[style=python_without_comments]
def f(x): return x + 1 #

# This is function foo...
def foo():
  if cond1: bar()  # Some explanation
  if cond2: baz()  # Some other explanation
  if cond3: bye()  # Even more explanations

# And this is function bar
def bar():  # let's see
  # some more comment
  return 42 # here?
\end{lstlisting}
\end{document}

Результат: Результат

Он может вывести пустую строку в конце текста, если там есть комментарии; я не уверен, как это удалить.


Редактировать: В моем первоначальном ответе OutputBoxвместо использовалось hook PostOutput. Это не очень хорошо работало с вкладками.

Связанный контент