90

I wanted to tidy up a TeX document and was curious if you can use \lstinputlisting or a similar function to include a certain part of a source-code file.

Example, I have a 500 or so line source file and I want to include just lines 300-400.

Is there a way to do this?

4 Answers 4

100

Each "listing" environment understands the firstline and lastline keys:

\lstinputlisting[firstline=300,lastline=500]{file.cc}
4
  • Thanks =) I also just found this in the reference (4.4 - The printed range). But I asked because I had trouble finding it :)
    – Supernovah
    Commented Nov 10, 2011 at 7:57
  • 2
    Personally I think linerange is more succinct Commented Nov 15, 2011 at 18:37
  • 1
    Only as an expansion of egreg answer, I would add that using the matlab-prettifier package works also pretty well. It is intended for Matlab (and compatible) language only, but the command \lstinputlisting[label={code:label},caption={Caption},firstline=100, lastline=300]{Matlab_Code/file.m} works greatly Commented Mar 14, 2018 at 15:35
  • As a remark, I would suggest that also the option firstnumber=100 is really nice; it allows you to keep track of the code you cutted. Commented Mar 14, 2018 at 15:45
53

listings supports line ranges not only with firstline and lastline (see egregs answer) but even with linerange={<first1>-<last1>,<first2>-<last2> …}. Note, that first2 has to be greater than last1 and so on. So

\lstinputlisting[linerange={1-4,7-9}]{file.cc}

would be valid but

\lstinputlisting[linerange={7-9,1-4}]{file.cc}% Don't do this!!!

is not allowed!

For more information see section 4.3.3 "The printed range" at the listings manual.

6
  • 1
    ...but note that the line numbering using this option will be continuous - so if you want to make it obvious that you haven't printed some code , using @egreg's approach multiple times (possibly with some explanatory text along the lines of "setup routine omitted" or even just $\vdots$ and specifying firstnumber= might be better. A firstnumber=firstline option would be nice.
    – Chris H
    Commented Apr 10, 2014 at 9:49
  • @ChrisH: You can also use my suggestion more than once with only one range every time and add something like $\vdots$ between. Commented Apr 16, 2014 at 14:52
  • @ChrisH: Unfortunately, the float argument cannot be used in that case, as the two listings need to stay together. Also, I fear there are conflicts with the frames, as listings puts frames around single listings, rather than the whole set of listings that should be considered as one listing (with omissions). Commented Sep 26, 2014 at 11:14
  • @O.R.Mapper, if you say so, I believe you - and I can see why it would be true. I've never floated my listings so haven't experienced this (my listings have all been in appendices and run to several pages each even with the most boring bits skipped).
    – Chris H
    Commented Sep 27, 2014 at 18:59
  • 1
    @yildizabdullah AFAIK the package does not support this. So in such a case you have to use multiple lstlisting environments and put the \dots or \vdots between them yourself. Commented Nov 17, 2017 at 9:59
20

As an addendum to egreg's answer: If you are typesetting line numbers and want these numbers to reflect the physical line numbers, the firstnumber key comes at your rescue:

\lstinputlisting[numbers=left,firstnumber=300,firstline=300,lastline=500]{file.cc}
3
  • Yup thanks, I have found that already in the reference, but didn't read section 4.4. Do you know how I can skip line 149 of my file as it contains a string too long for the bounding box. Error "Dimension too large " ... ""
    – Supernovah
    Commented Nov 10, 2011 at 8:09
  • @Supernovah: Use either linerange, or split your \lstinputlisting into two separate instances that skip line 149.
    – Werner
    Commented Nov 10, 2011 at 8:12
  • The compiler still hiccups with linerange splitting over 149 -Excuse me it actually doesn't, thanks - I had a syntax error and the IDE was using an old file
    – Supernovah
    Commented Nov 10, 2011 at 8:13
0

I'd like to add another way of addressing this question, somewhat complementary to the linerange, firstline/lastline neatly explained in the other answers.

My similar problem is that I wanted \lstinputlisting to omit particular blocks of code; but as I make some changes to the code, the lines corresponding to those blocks will change, and I'd have to update linerange accordingly every time.

The idea is to use the escapechar or escapeinside options in \lstinputlisting. As the manual says, "all code between two such characters is interpreted as LaTeX code". So we can give a \iffalse right after the initial escape character, and a \fi right before the final escape character.

Here is a minimal example with Octave code. We define the escape character to be @.

The script:

#### script.m

a = 1;
b = 2; # @\iffalse % we have escaped to LaTeX

## This doesn't appear in lstinputlisting
s = "this is a string";
disp(s); # now returning from LaTeX \fi@

## This does appear in lstinputlisting
c = a + b;
disp(c);

The minimal LaTeX file:

\documentclass{article}

\usepackage{listings}

\begin{document}

Some text.

\lstinputlisting[escapechar={\@}]{script.m}
% Note that the escape character @ must be preceded by '\'
% because it's a LaTeX special character

Some other text.

\end{document}

You see the result here: minimal document

One warning about this implementation: the final \fi must occur on a line that is not escaped as LaTeX % comment. This can be tricky depending on the coding language. Luckily Octave allows the use of # as comment.

The above implementation of the idea is quite rudimentary, it can surely be made neater. One might use ways different from \iffalse/\fi to omit printing blocks, and smarter escape characters.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .