
Я хочу включить код 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
. Это не очень хорошо работало с вкладками.