2

Please note that I am quite new to tex/latex.

For my paper I need to reference specific parts of my source code as one code listing. This allows me to skip specific lines of the source code that are to detailed for a code listing.

My initial Question led me to a solution that almost works.

I have special markes in my source code (like '//#< code:1 >#') to reference the relevant lines. I use multiple listings that look like one listing and add a caption.

There is one problem, though, that my code listing is sometimes continued on the next page (see the code example below). This is the case, because to latex my code listing is actually four separate code listings.

Is there a way to fix this, e.g., to tell latex to treat my 4 different code listings as one?

I am not sure how to describe the problem better, and I hope my code listing is clear. I search online for quite some time, but I could not find anything that would help.


\documentclass[a5paper,22pt]{article}

\usepackage[english]{babel} \usepackage{listings} \usepackage{filecontents}

\lstset{rangeprefix=#<\ ,% curly left brace plus space rangesuffix=\ >#,% includerangemarker=false,% escapeinside={@}{\^^M}}% space plus curly right brace

\lstdefinestyle{JStyle} { boxpos=c,% breaklines=true,% showlines=false,% numbers=none,%numbers=left,% numberstyle=\tiny,% firstnumber=1,% frame=none,%frame=single,% basicstyle=\scriptsize\ttfamily, captionpos=b,% }

\begin{document}

\begin{filecontents*}{foo.java} //#< code:1 ># public int nextInt(int n) { //#< end ># //#< code:2 ># if (n<=0) throw new IllegalArgumentException("n must be positive"); //#< end ># //#< code:3 ># if ((n & -n) == n) // i.e., n is a power of 2 return (int)((n * (long)next(31)) >> 31); //#< end ># //#< code:4 ># int bits, val; do { bits = next(31); val = bits % n; } while(bits - val + (n-1) < 0); //#< end ># //#< code:5 ># return val; } //#< end ># \end{filecontents*}

\begin{filecontents*}{empty.java}

\end{filecontents*}

\newcommand*{\ShowListingMarker}[2]{% \vspace{-#2\baselineskip}{} \lstinputlisting[ style=JStyle, linerange={#1-end},% emphstyle={[2]\underbar},% ]{foo.java} }

\newcommand*{\ShowListingMarkerCaption}[4]{% \vspace{-#2\baselineskip}{} \lstinputlisting[language=Tcl,% label=#4,% linerange={0-0},% caption=#3 ]{empty.java} }

\section{Introduction} Lorem Ipsum is simply dummy text of the printing and typesetting industry.

\section{Methods} Lorem Ipsum is simply dummy text of the printing and typesetting industry. \section{Background} Lorem Ipsum is simply dummy text of the printing and typesetting industry.

\section{Approach A}

Lorem Ipsum is simply dummy text of the printing and typesetting industry.

\section{Results}

\ShowListingMarker{code:1}{0} \ShowListingMarker{code:2}{1} % code:3 is not shown in the figure, this is the flexibility of the approach! \ShowListingMarker{code:4}{1} \ShowListingMarker{code:5}{1} \ShowListingMarkerCaption{code:5}{1.4}{The Program}{fig:program}

\end{document}

mrsteve
  • 303

1 Answers1

2

Your example doesn't works because you made a mistake inside this definition:

\lstset{rangeprefix=#<\ ,% curly left brace plus space
rangesuffix=\ >#,%
includerangemarker=false,%
escapeinside={@}{\^^M}}% space plus curly right brace

The symbol # is a special character inside TeX and must be escape. In the documentation of listings you will find the following hint:

Note that TeX’s special characters like the curly braces, the space, the percent sign, and such must be escaped with a backslash.

The correct one is:

\lstset{rangeprefix=\#<\ ,% curly left brace plus space
rangesuffix=\ >\#,%
includerangemarker=false,%
escapeinside={@}{\^^M}}% space plus curly right brace

To prevent your code from being splitting you can simple use the minipage environment.

This is well discussed in the question:

Unbreakable block

Next improvement is to use the package caption. Instead of defining ShowListingMarkerCaption you can simple use the command \captionof{lstlisting}{....} to get a caption.

The output is:

enter image description here

\documentclass[a5paper,22pt]{article}

\usepackage[english]{babel}
\usepackage{listings}
\usepackage{caption}
\usepackage{filecontents}

\lstset{rangeprefix=\#<\ ,% curly left brace plus space
rangesuffix=\ >\#,%
includerangemarker=false,%
escapeinside={@}{\^^M}}% space plus curly right brace

\lstdefinestyle{JStyle} {
    boxpos=c,%
    breaklines=true,%
    showlines=false,%
    numbers=none,%numbers=left,%
    numberstyle=\tiny,%
    firstnumber=1,%
    frame=none,%frame=single,%
    basicstyle=\scriptsize\ttfamily,
    captionpos=b,%
    }    

\begin{document}


\begin{filecontents*}{foo.java}
//#< code:1 >#
 public int nextInt(int n) {
//#< end >#
//#< code:2 >#
     if (n<=0)
        throw new IllegalArgumentException("n must be positive");
//#< end >#
//#< code:3 >#
     if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);
//#< end >#
//#< code:4 >#
     int bits, val;
     do {
         bits = next(31);
         val = bits % n;
     } while(bits - val + (n-1) < 0);
//#< end >#
//#< code:5 >#
     return val;
 }
//#< end >#
\end{filecontents*}



\newcommand*{\ShowListingMarker}[2]{%
    \vspace{-#2\baselineskip}{}
    \lstinputlisting[
      style=JStyle,
      linerange={#1-end},%
      emphstyle={[2]\underbar},%
      ]{foo.java}
}


\section{Introduction}
Lorem Ipsum is simply dummy text of the printing and typesetting industry.


\section{Methods}
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
\section{Background}
Lorem Ipsum is simply dummy text of the printing and typesetting industry.


\section{Approach A}


Lorem Ipsum is simply dummy text of the printing and typesetting industry.


\section{Results}

\noindent\begin{minipage}{\linewidth}
\ShowListingMarker{code:1}{0}
\ShowListingMarker{code:2}{1}
\ShowListingMarker{code:4}{1}
\ShowListingMarker{code:5}{1}

\captionof{lstlisting}{The Program}
\label{fig:program}
\end{minipage}
\end{document}
Marco Daniel
  • 95,681