
Quiero incluir código Python para formatear con listados, pero solo quiero que el código sea limpio y compacto. No se imprimirán comentarios ni líneas vacías.
ElfácilLa manera sería quitarle el código de comentarios, pero eso es pasar por alto el problema y no encontrar una solución. Quiero una solución. Una solución significaría que NO tengo que editar el archivo fuente que se está importando.
He probado lo siguiente:
Enfoque 1
\lstdefinestyle{py_without_comments}{%
language = python,
morecomment = [l][\nullfont]{\#},
emptylines = *1,
}
Lo cual no imprime los comentarios, pero las líneas permanecen ahí desde que el texto llega a la salida, solo LaTeX lo imprime con nullfont
.
Enfoque 2
\lstdefinestyle{py_without_comments}{%
language = python,
morecomment = [is]{\#}{\^^M},
emptylines = *1,
}
El método 2 ignora todas las líneas de comentarios desde el #
final de la línea. ¡El problema es que el final de la línea también desaparece! Digamos que tienes este código:
def foo():
if cond1: bar() #Some explanation
if cond2: baz() #Some other explanation
if cond3: bye() #Even more explanations
Se imprimiría así:
def foo():
if cond1: bar() if cond2: baz() if cond3: bye()
Lo cual es indeseable, poco pitónico y feo.
Enfoque 3
\lstdefinestyle{py_without_comments}{%
language = python,
morecomment = [il]{\#},
emptylines = *1,
}
Este debería funcionar de maravilla, pero por alguna razón borra todo el código del primer comentario (ver foo()
ejemplo).
Por eso estoy buscando algo más para probar. ¿Será que esto no es posible con los listados?
Saludos y gracias de antemano.
Edición 1:
MWE se puede encontraraquí
Respuesta1
Aquí hay algo que funciona. Juega con algunas de listings
las partes internas. No estoy seguro de si hay una solución mejor. Consumir el delimitador de fin de línea (su método 2, arriba) y agregarlo nuevamente si la línea no está vacía no parece funcionar.
\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}
Puede imprimir una línea vacía al final del texto, si hay comentarios allí; No estoy seguro de cómo eliminar esto.
Editar: Mi respuesta original usaba gancho OutputBox
en lugar de PostOutput
. Esto no funcionó bien con las pestañas.