15

Is there a way to input particular sections of source code using \lstinputlisting (from the listings package) in a flexible way? It's possible to use the firstline and lastline options to input particular line ranges, but this isn't robust to changes to the source file.

For example, suppose that the input source file is:

int square(int x) {
  return x * x;
}

int cube(int x) {
  return x * x * x;
}

In my LaTeX document, I can include the cube procedure using the command \lstinputlisting[firstline=5,lastline=7]{source.c}.

But suppose I later decide to rewrite the cube procedure. The input source file becomes:

int square(int x) {
  return x * x;
}

int cube(int x) {
  int x2;
  x2 = square(x);
  return x * x2;
}

Now my LaTeX document will not show the final two lines of cube because the listing uses only lines 5-7. I could manually update the line range, but this is tedious and error-prone.

Is there a way to mark sections of source code with some kind of label so that the listing will be robust to these sorts of changes? For instance, perhaps the input source file would be something like

int square(int x) {
  return x * x;
}

/**\beginlabel{lst:cube} **/
int cube(int x) {
  int x2;
  x2 = square(x);
  return x * x2;
}
/**\endlabel{lst:cube} **/

so that I could use something like \lstinputlisting[lines=lst:cube]{source.c} to include the section that I want and remain robust to changes.

I am open to using other packages for source code listings (e.g., minted) if helpful.

13

Short guide

  1. Set the prefixes and suffixes for your markers. Replace the space with \ (backslash plus space)
  2. Decide if the marker lines should be part of the output or not.
  3. Include the code and use the text between the prefixes and sufixes as “line numbers” for the linerange option.

% create the test file for this example
\begin{filecontents}{external.c}
int square(int x) {
  return x * x;
}

@@@START@@@
int cube(int x) {
  int x2;
  x2 = square(x);
  return x * x2;
}
@@@STOP@@@

\end{filecontents}

\documentclass{article}

\usepackage{listings}
\lstset{%
    rangeprefix=@@@,% [1]
    rangesuffix=@@@,
    includerangemarker=false,% [2]
}

\begin{document}
\lstinputlisting[linerange=START-STOP]{external.c}%[3]
\end{document}

For more details see section “5.7 Arbitrary linerange markers” in the manual …

12

The listings package provides an experimental feature for arbritrary linerange markers (see §5.7 of the listings manual).

// example.c
int square(int x) {
  return x * x;
}

/* BEGIN */
int cube(int x) {
  int x2;
  x2 = square(x);
  return x * x2;
}
/* END */

MWE to demonstrate the linerange option:

\documentclass{article}
\usepackage{listings}

\lstset{rangeprefix=\/\*\ ,rangesuffix=\ \* \/}

\begin{document}
Example.c

   \lstinputlisting[language=C, linerange=BEGIN-END]{example.c}

\end{document}

Output:

enter image description here

You can use the includerangemarker=false option to prevent that the line range markers (/* BEGIN */ and /* END */) itself become part of the output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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