3

Is it possible to group listings by type?

I have a document with two types of listings, namely one for source-code and one for series of shell-commands (and their outputs).

So is it possible to have \lstlistingname refer to one type as "listing" and the other as "shell-transcript"? Ideally I would also like to seperate these types in the \lstlistoflistings for each type. (Similar to what \printbibliography[type=book] does - So I would end up with one list of listings of actual source-code and one for the shell-demonstrations)

  • Welcome to TeX.SX. You can use \lstnewenvironment to define specific listing environments for any programming language and as such provide a new \lstlistingname in the starter code – user31729 Jun 26 '16 at 16:56
3

Using a separate listing environment for shell-scripts with a specific name is quite easy, see the \lstnewenvironment code.

More difficult is the splitting of the .lol and .los settings: \lst@MakeCaption must be redefined and changed to use los instead of lol.

Please note: The current version does not work well with hyperref due to the anchors!

\documentclass{article}

\usepackage{listings}
\newcounter{shelllistcntr}[section]

\makeatletter
\def\lst@MakeOtherCaption#1{%
  \lst@ifdisplaystyle
  \ifx #1t%
  \ifx\lst@@caption\@empty\expandafter\lst@HRefStepCounter \else
  \expandafter\refstepcounter
  \fi {lstlisting}%
  \ifx\lst@label\@empty\else \label{\lst@label}\fi
  \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl
  \global\let\lst@name\lst@arg \global\let\lstname\lst@name
  \lst@ifnolol\else
  \ifx\lst@@caption\@empty
  \ifx\lst@caption\@empty
  \ifx\lst@intname\@empty \else \def\lst@temp{ }%
  \ifx\lst@intname\lst@temp \else
  \addcontentsline{los}{lstlisting}\lst@name
  \fi\fi
  \fi
  \else
  \addcontentsline{los}{lstlisting}%
  {\protect\numberline{\thelstlisting}\lst@@caption}%
  \fi
  \fi
  \fi
  \ifx\lst@caption\@empty\else
  \lst@IfSubstring #1\lst@captionpos
  {\begingroup \let\@@vskip\vskip
    \def\vskip{\afterassignment\lst@vskip \@tempskipa}%
    \def\lst@vskip{\nobreak\@@vskip\@tempskipa\nobreak}%
    \par\@parboxrestore\normalsize\normalfont % \noindent (AS)
    \ifx #1t\allowbreak \fi
    \ifx\lst@title\@empty
    \lst@makecaption\fnum@lstlisting{\ignorespaces \lst@caption}
    \else
    \lst@maketitle\lst@title % (AS)
    \fi
    \ifx #1b\allowbreak \fi
    \endgroup}{}%
  \fi
  \fi
}

\AtBeginDocument{%    
\lstnewenvironment{shellstuff}[1][]{%
  \let\lst@MakeCaption\lst@MakeOtherCaption%
  \let\c@lstlisting\c@shelllistcntr% Use the other counter
  \let\thelstlisting\theshelllistcntr% Use a different counter format if really needed
  \lstset{language={bash},#1}% Define the language etc. 
  \renewcommand{\lstlistingname}{Shell stuff}%
}{%
}
}

\newcommand{\lstshellscriptlistingname}{List of Shell Scripts}

\newcommand{\lstshellscriptlistings}{% The `\tableofshellscripts` ;-)
  \bgroup
  \let\contentsname\lstshellscriptlistingname%
  \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{los}}%
  \tableofcontents \egroup
}


\makeatother



\begin{document}

\lstlistoflistings
\lstshellscriptlistings
\begin{shellstuff}[caption={Foo shell}]
  rm *.*
  ls -l
  echo ``Ooops''
\end{shellstuff}

\begin{lstlisting}[language={C},caption={Hello world}]
#include<stdio.h>

int main(int argc,char **argv)
{
  printf("Hello World!\n");
  return(0);
}
\end{lstlisting}


\end{document}

enter image description here

Update with 'limited' hyperref support and addition to Toc

\documentclass{book}

\usepackage{tocbibind}
\usepackage{listings}

\makeatletter
\newif\ifclassprovideschapter

\@ifundefined{chapter}{%
  \global\classprovideschapterfalse
  \newcounter{shelllistcntr}[section]
}{%
  \global\classprovideschaptertrue
  \newcounter{shelllistcntr}[chapter]
}

\makeatother


\usepackage{hyperref}


\makeatletter
\def\lst@MakeOtherCaption#1{%
  \lst@ifdisplaystyle
  \ifx #1t%
  \ifx\lst@@caption\@empty\expandafter\lst@HRefStepCounter \else
  \expandafter\refstepcounter
  \fi {shelllistcntr}%
  \ifx\lst@label\@empty\else \label{\lst@label}\fi
  \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl
  \global\let\lst@name\lst@arg \global\let\lstname\lst@name
  \lst@ifnolol\else
  \ifx\lst@@caption\@empty
  \ifx\lst@caption\@empty
  \ifx\lst@intname\@empty \else \def\lst@temp{ }%
  \ifx\lst@intname\lst@temp \else
  \addcontentsline{los}{lstlisting}\lst@name
  \fi\fi
  \fi
  \else
  \addcontentsline{los}{lstlisting}%
  {\protect\numberline{\theshelllistcntr}\lst@@caption}%
  \fi
  \fi
  \fi
  \ifx\lst@caption\@empty\else
  \lst@IfSubstring #1\lst@captionpos
  {\begingroup \let\@@vskip\vskip
    \def\vskip{\afterassignment\lst@vskip \@tempskipa}%
    \def\lst@vskip{\nobreak\@@vskip\@tempskipa\nobreak}%
    \par\@parboxrestore\normalsize\normalfont % \noindent (AS)
    \ifx #1t\allowbreak \fi
    \ifx\lst@title\@empty
    \lst@makecaption\fnum@lstlisting{\ignorespaces \lst@caption}
    \else
    \lst@maketitle\lst@title % (AS)
    \fi
    \ifx #1b\allowbreak \fi
    \endgroup}{}%
  \fi
  \fi
}


\AtBeginDocument{%
\lstnewenvironment{shellstuff}[1][]{%
  \let\lst@MakeCaption\lst@MakeOtherCaption%
  \let\c@lstlisting\c@shelllistcntr%
  \let\thelstlisting\theshelllistcntr%
  \renewcommand{\theHlstlisting}{shelllist.\theshelllistcntr}%
  \lstset{language={bash},#1}%
  \renewcommand{\lstlistingname}{Shell stuff}%
}{%
}
}

\newcommand{\lstshellscriptlistingname}{List of Shell Scripts}

\newcommand{\lstshellscriptlistings}{%
  \bgroup
  \let\contentsname\lstshellscriptlistingname%
  \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{los}}%
  \tableofcontents 
  \egroup
}


\makeatother



\begin{document}
\tableofcontents
\clearpage
\lstlistoflistings
\lstshellscriptlistings

\clearpage

\begin{shellstuff}[caption={Foo shell}]
  rm *.*
  ls -l
  echo ``Ooops''
\end{shellstuff}

\clearpage

\begin{lstlisting}[language={C},caption={Hello world}]
#include<stdio.h>

int main(int argc,char **argv)
{
  printf("Hello World!\n");
  return(0);
}
\end{lstlisting}


\end{document}

  \begingroup
  \section*{Foo}
  \@starttoc{los}
  \endgroup
}
  • Thanks, only one small remark: the list of shell listings doesn't get added to my table of contents (Im using a KOMA-Class with listof=totoc) – MalteJ Jun 26 '16 at 17:47
  • 1
    @MalteJ: Well, that was not in your question! That's why we like to have a compilable document by the O.P. in advance. – user31729 Jun 26 '16 at 17:49
  • Sorry about that (As you can see I already accepted your answer to my original question ;)) I managed to manually add it via \addcontentsline, which works fine. – MalteJ Jun 26 '16 at 17:53
  • @MalteJ: See the update at the end – user31729 Jun 26 '16 at 17:57

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.