10

How do I create two lstlisting environments that each have its own counter?

If I use for example

\lstnewenvironment{algorithm}[2]{
    \renewcommand\lstlistingname{Algorithm}
    \lstset{ ... }
} {}

\lstnewenvironment{program}[2]{
    \renewcommand\lstlistingname{Program}
    \lstset{ ... }
} {}

And then

\begin{algorithm}{Algorithm caption}{alg-label}
...
\end{algorithm}

\begin{program}{Program caption}{prg-label}
...
\end{program}

Then they will share the counter, i.e. it will result for example in

Algorithm 1.1
    ...
Program 1.2
    ...

I would like the counting to be independent for different listing environments.

I also use the caption package to create a nice caption. I've already tried many things but none really successfuly. The only way that I found that indicates how to change the counter/file extension is via i.e. \DeclareCaptionType[fileext=alg]{algorithm} but the problem is that this command already defines a new environment so I don't know how to use it together with a new listings environment and the caption package. I'm using for example the following settings:

\DeclareCaptionFont{white}{\color{white}}
\DeclareCaptionFormat{listing}{\colorbox[cmyk]{0.43, 0.35, 0.35,0.01}{\parbox{\textwidth}{\hspace{15pt}#1#2#3}}}
\captionsetup[lstlisting]{format=listing,labelfont=white,textfont=white, singlelinecheck=false, margin=0pt, font={bf,footnotesize}}
7

A solution in the spirit of Elenaher's comment:

\newcounter{algorithm}
\lstnewenvironment{algorithm}[2]{
    \renewcommand\lstlistingname{Algorithm}
    \setcounter{lstlisting}{\value{algorithm}}
    \lstset{ ... }
} {\addtocounter{algorithm}{1}}

\newcounter{program}
\lstnewenvironment{program}[2]{
    \renewcommand\lstlistingname{Program}
    \setcounter{lstlisting}{\value{program}}
    \lstset{ ... }
} {\addtocounter{program}{1}}

Then the following:

\begin{algorithm}{Algorithm caption}{alg-label}
...
\end{algorithm}

\begin{algorithm}{Another algorithm caption}{another-alg-label}
...
\end{algorithm}

\begin{program}{Program caption}{prg-label}
...
\end{program}

results in:

Algorithm 1.1
    ...
Algorithm 1.2
    ...
Program 1.1
    ...
5

Maybe you should try to invoke manually the command setcounter to change the counter of lstlisting like that :

\setcounter{lstlisting}{value}

Thus, you will be able to re-initialize the counter for each new environments.

Then you could do more complicated things like automating the invocation of setcounter with the values of the label.

  • You are right,thanks! I looked at this and related commands before but I didn't see a clean way to use them. Well, I guess that letting all new environments share the same counter and changing it is not very clean, more of a hack, but then again, I don't know that much about LaTeX. I'll post the solution as a separate answer. – fraktalek Oct 13 '10 at 12:26
0

Not everything in fraktalek's answer was explicitly shown. I could not use the code provided and replicate his output. Specifically, the captions and (I assume) labels are missing.

I found this answer which helped me out, noting that there is a caption field in lstset. So here's a full working example with both captions and labels in two custom lstnewenvironments.

\documentclass[11pt, english, letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage[scaled=0.9]{couriers}  % Typewriter font which supports bold
\usepackage[scaled]{helvet}

\usepackage{listings}

\newcounter{algorithm}
\lstnewenvironment{algorithm}[2]{
    \renewcommand\lstlistingname{Algorithm}
    \setcounter{lstlisting}{\value{algorithm}}
    \lstset
    {
        language=C,
        basicstyle=\ttfamily,
        frame = tb,
        caption={[#1]{#1}},      % <------------- NOTICE
        label={#2},              % <------------- NOTICE
    }
}{\addtocounter{algorithm}{1}}

\newcounter{program}
\lstnewenvironment{program}[2]{
    \renewcommand\lstlistingname{Program}
    \setcounter{lstlisting}{\value{program}}
    \lstset
    {
        language=Python,
        basicstyle=\ttfamily,
        frame = tb,
        caption={[#1]{#1}},
        label={#2},
    }
}{\addtocounter{program}{1}}


\begin{document}

Text before, referencing Algorithm \ref{alg-label}.

\begin{algorithm}{Something descriptive}{alg-label}
#include <stddef.h>
\end{algorithm}

\begin{algorithm}{Something descriptive}{alg-label2}
char * foo(unsigned char bar);
\end{algorithm}

\begin{program}{Something descriptive}{prog-label}
def foo(bar: int) -> str:
    print(bar)
\end{program}

Text after, referencing Algorithm \ref{alg-label2} and Program \ref{prog-label}.

\end{document}

Which generates...

LaTeX Listings different counters with captions and labels

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.