0

I want to label and reference the modified listing environments namely Matlab Code and Matlab Output. However, when I add the \label command and try to reference the labelled modified listing environments, I get ?? which is something I do not desire. Below is my MWE which is a solution to my problem by @Tom found at Incorrect classification of multiple listings entries:

\documentclass[openany]{book}
\usepackage{regexpatch}
\usepackage[nottoc]{tocbibind}
\usepackage{caption}
\usepackage{listings}
\usepackage{hyperref}


% --------------------------------------- C++
\newcommand{\lstlistmatlaboutputname}{List of Matlab Output}
\newcommand{\lstlistofmatlaboutput}{\begingroup
    \tocfile{\lstlistmatlaboutputname}{loc}
    \endgroup}
% --------------------------------------- R
\newcommand{\lstlistmatlabcodename}{List of Matlab Code}
\newcommand{\lstlistofmatlabcode}{\begingroup
    \tocfile{\lstlistmatlabcodename}{lor}
    \endgroup}
% --------------------------------------- Pseudocode
\newcommand{\lstlistpseudocodename}{List of Pseudocode}
\newcommand{\lstlistofpseudocode}{\begingroup
    \tocfile{\lstlistpseudocodename}{lop}
    \endgroup}

\makeatletter
\lstnewenvironment{matlaboutput}[1][]{%
    \renewcommand{\lstlistingname}{Matlab Output}%
    \renewcommand{\ext@lstlisting}{loc}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{loc}{}{}% use this with earlier version caption package
    \lstset{language=C++,#1}}%
{}

\lstnewenvironment{matlabcode}[1][]{%
    \renewcommand{\lstlistingname}{Matlab Code}%
    \renewcommand{\ext@lstlisting}{lor}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{lor}{}{}% use this with earlier version caption package
    \lstset{language=R,#1}}
{}

\lstnewenvironment{pseudocode}[1][]{%
    \renewcommand{\lstlistingname}{Pseudocode}%
    \renewcommand{\ext@lstlisting}{lop}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{lop}{}{}% use this with earlier version caption package
    \lstset{basicstyle=\ttfamily,#1}}%
{}
\makeatother

\begin{document}
    
    \lstlistofmatlaboutput
    \lstlistofmatlabcode    
    \lstlistofpseudocode
    
    \chapter{Listings}
    \begin{matlaboutput}[caption = {Some class definition}]\label{outp:1}
        % example matlab output
    \end{matlaboutput}
    
    \begin{matlabcode}[caption = {For educational purposes}]\label{code:1}
        % example matlab code 1
    \end{matlabcode}

See Output \ref{outp:1} and Code \ref{code:1} above.

\end{document}

1 Answer 1

2

You should use the label argument to the listings environment, instead of trying to set a \label inside it. The later can be done, but it has to be properly escaped, and is usually to refer to the line number rather than the whole environment.

\documentclass[openany]{book}
\usepackage{regexpatch}
\usepackage[nottoc]{tocbibind}
\usepackage{caption}
\usepackage{listings}
\usepackage{hyperref}


% --------------------------------------- C++
\newcommand{\lstlistmatlaboutputname}{List of Matlab Output}
\newcommand{\lstlistofmatlaboutput}{\begingroup
    \tocfile{\lstlistmatlaboutputname}{loc}
    \endgroup}
% --------------------------------------- R
\newcommand{\lstlistmatlabcodename}{List of Matlab Code}
\newcommand{\lstlistofmatlabcode}{\begingroup
    \tocfile{\lstlistmatlabcodename}{lor}
    \endgroup}
% --------------------------------------- Pseudocode
\newcommand{\lstlistpseudocodename}{List of Pseudocode}
\newcommand{\lstlistofpseudocode}{\begingroup
    \tocfile{\lstlistpseudocodename}{lop}
    \endgroup}

\makeatletter
\lstnewenvironment{matlaboutput}[1][]{%
    \renewcommand{\lstlistingname}{Matlab Output}%
    \renewcommand{\ext@lstlisting}{loc}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{loc}{}{}% use this with earlier version caption package
    \lstset{language=C++,#1}}%
{}

\lstnewenvironment{matlabcode}[1][]{%
    \renewcommand{\lstlistingname}{Matlab Code}%
    \renewcommand{\ext@lstlisting}{lor}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{lor}{}{}% use this with earlier version caption package
    \lstset{language=R,#1}}
{}

\lstnewenvironment{pseudocode}[1][]{%
    \renewcommand{\lstlistingname}{Pseudocode}%
    \renewcommand{\ext@lstlisting}{lop}%
    %\xpatchcmd*{\caption@ORI@lst@MakeCaption}{lol}{lop}{}{}% use this with earlier version caption package
    \lstset{basicstyle=\ttfamily,#1}}%
{}
\makeatother

\begin{document}

    \lstlistofmatlaboutput
    \lstlistofmatlabcode
    \lstlistofpseudocode

    \chapter{Listings}
    \begin{matlaboutput}[caption = {Some class definition},label={outp:1}]
        % example matlab output
    \end{matlaboutput}

    \begin{matlabcode}[caption = {For educational purposes},label={code:1}]
        % example matlab code 1
    \end{matlabcode}

See Output \ref{outp:1} and Code \ref{code:1} above.

\end{document}

enter image description here

5
  • When I type the command \ref, I get a list of all my labels in my document. However, the labels assigned to the modified listings are not appearing. What could be the cause?
    – itc
    Feb 26 at 2:55
  • @itc A \ref produces a reference to a given label, not a list of them. I'm not sure I understand what you mean. Either way, what you asked was about the undefined labels, and that's what I answered about.
    – gusbrs
    Feb 26 at 3:23
  • If one is using texstudio, typing the command \ref will produce a dropdown list of all the labels in the document. That is what I mean. The solution you provided is working except that the labellings for matlab code and output are not appearing in that dropdown list.
    – itc
    Feb 26 at 3:27
  • 1
    Ah, that's a texstudio issue, perhaps it does not recognize a label if it is set as the argument of a custom environment, which is actually to be expected. There might be ways to configure it, but I don't know. Anyway, there's no point in setting "a label which texstudio recognizes" if it is wrong on the LaTeX side of things, is there?
    – gusbrs
    Feb 26 at 3:34
  • Thank you @gusbrs!
    – itc
    Feb 26 at 3:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .