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.

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.

share|improve this question
add comment

2 Answers

up vote 8 down vote accepted

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 …

share|improve this answer
    
Thanks for your help! –  Henry DeYoung Apr 23 '12 at 21:00
add comment

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.

share|improve this answer
    
Thanks for your help! –  Henry DeYoung Apr 23 '12 at 21:06
add comment

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.