Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've been trying to include multiple code snippets from a unique source file by using listings's range markers (named lines) and PGF's \foreach macro:

\foreach \x in {1,2,...,8} {
  \lstinputlisting[linerange=P\x-FIN\ P\x]{programas.py}
}

It doesn't work: no code is inserted at all. When passing the range name explicitly to \lstinputlisting (without using \foreach's counter), then the code is inserted correctly:

\lstinputlisting[linerange=P1-FIN\ P1]{programas.py}

Minimum (non-)working example: https://gist.github.com/1371840

How could I make it work? Is it listing's or foreach's fault?

share|improve this question

1 Answer 1

up vote 6 down vote accepted

\lstinputlisting doesn't seem to expand its arguments, so the \x is not replaced with the current number. You can work around this by using an \edef (an "expanded definition") to define a new macro that contains your \lstinputlisting line with expanded arguments, and then call that.

The lines

    \edef\dolisting{\noexpand\lstinputlisting[linerange=P\x-FIN\ P\x]{programas.py}}
    \dolisting

first define a new macro \dolisting, with everything except for the \lstinputlisting keyword expanded, and then call that new macro.

Here's a complete example:

\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}
share|improve this answer
    
I didn't know about \edef. Thanks! –  Roberto Bonvallet Nov 16 '11 at 23:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.