listings
我一直在尝试使用范围标记(命名行)和 PGF 的宏来包含来自唯一源文件的多个代码片段\foreach
:
\foreach \x in {1,2,...,8} {
\lstinputlisting[linerange=P\x-FIN\ P\x]{programas.py}
}
它不起作用:根本没有插入任何代码。当明确将范围名称传递给\lstinputlisting
(不使用\foreach
计数器)时,代码会正确插入:
\lstinputlisting[linerange=P1-FIN\ P1]{programas.py}
最小(非)工作示例: https://gist.github.com/1371840
我该如何让它工作?是 listing 还是 foreach 的错误?
答案1
\lstinputlisting
似乎没有扩展其参数,因此\x
不会被当前数字替换。您可以使用\edef
(“扩展定义”)来定义一个包含带有\lstinputlisting
扩展参数的行的新宏,然后调用该宏来解决此问题。
线条
\edef\dolisting{\noexpand\lstinputlisting[linerange=P\x-FIN\ P\x]{programas.py}}
\dolisting
首先定义一个新的宏\dolisting
,除了\lstinputlisting
关键字之外的所有内容都展开,然后调用该新宏。
这是一个完整的例子:
\documentclass{article}
\usepackage{listings}
\usepackage{pgffor}
\usepackage{filecontents}
\begin{filecontents}{programas.py}
# P\x
s = {78, 15, 91, 15}
print len(s)
# FIN P\x
# P2
d = {78: 15, 91: 15}
print len(d)
# FIN P2
# P3
n = (17, 3, 1993)
h = (14, 5, 2011)
print n < h
# FIN P3
# P4
x, y = ((27, 3), 9)
z, w = x
print y + w
# FIN P4
# P5
a = 'acabase'
b = set(a)
c = list(b)
c.sort()
print c[2]
# FIN P5
# P6
t = 'papagayo'
w = t.split('a')
print w[3]
# FIN P6
# P7
def f(a, b):
return a + 2 * b
a = 5
b = 2
print f(b, a)
# FIN P7
# P8
def f(a):
return x + a
def g(x):
return x + a
x = 5
a = 7
print f(x) + g(x)
# FIN P8
\end{filecontents}
\usepackage{courier}
\lstset{basicstyle=\ttfamily}
\lstset{language=python}
\lstset{rangeprefix=\#\ }
\lstset{includerangemarker=false}
\begin{document}
\foreach \x in {1,2,...,8} {
\noindent
\begin{minipage}[b]{19.8em}
\edef\dolisting{\noexpand\lstinputlisting[linerange=P\x-FIN\ P\x]{programas.py}}
\dolisting
\framebox[18em]{\rule[6ex]{0pt}{0pt}}
\vspace{0.7em}
\end{minipage}
}
\end{document}