6

I am writing code form different languages in one document. Because of that it would be nice, if it is possible to display the name of the language below the rule of an lstlisting.

This is my code

\documentclass{article}

\usepackage{listings}
\usepackage{xcolor}

\lstset{
%   backgroundcolor=\color{},
    commentstyle=\color{green},
    keywordstyle=\color{blue},
    stringstyle=\color{black!50!green},
    %        identifierstyle=\color{red},
    numbers=left,
    captionpos=t,
    showstringspaces=false,
    tabsize=2,
    frame=b,
    breaklines=true,
    xleftmargin=17pt,
    framexleftmargin=17pt,
}

\begin{document}


    Much text
    \begin{lstlisting}[language=C++]
#inlcude <iostream.h>

int end = 5;

for(int i = 0; i < end; i++)
{
    std::cout << "Hello world!";
}
    \end{lstlisting}

%This should happen automaticly
%----------------------------------------------------

 \begin{flushright}
    c++
 \end{flushright}

%----------------------------------------------------

\end{document}

1 Answer 1

6

With the package etoolbox you can hook to the lstlisting environment to store the language option in a macro. Then you can add code after the environment to display the flushright environment with the language.

MWE:

\documentclass{article}

\usepackage{listings}
\usepackage{xcolor}
\usepackage{etoolbox}

\makeatletter
\AtEndEnvironment{lstlisting}{\xdef\xlang{\lst@language}}
\AfterEndEnvironment{lstlisting}{\begin{flushright}\xlang\end{flushright}}
\makeatother

\lstset{
%   backgroundcolor=\color{},
    commentstyle=\color{green},
    keywordstyle=\color{blue},
    stringstyle=\color{black!50!green},
    %        identifierstyle=\color{red},
    numbers=left,
    captionpos=t,
    showstringspaces=false,
    tabsize=2,
    frame=b,
    breaklines=true,
    xleftmargin=17pt,
    framexleftmargin=17pt,
}

\begin{document}


    Much text
    \begin{lstlisting}[language=C++]
#include <iostream.h>

int end = 5;

for(int i = 0; i < end; i++)
{
    std::cout << "Hello world!";
}
    \end{lstlisting}

\begin{lstlisting}[language=bash]
echo "Hello world!"
\end{lstlisting}

\end{document}

Result:

enter image description here


For environments defined with \lstnewenvironment the idea is the same. The syntax is actually easier because \lstnewenvironment allows you to define what happens at the end of the environment in the third argument, so you can put the language name there instead of using \AtEndEnvironment and \AfterEndEnvironment. Note that you do need \makeatletter and \makeatother around \lstnewenvironment because \lst@language contains an @ symbol.

Relevant snippet (using the example pascalx environment from the listings manual):

\makeatletter
\lstnewenvironment{pascalx}[1][]
{\lstset{language=pascal,numbers=left,numberstyle=\tiny,#1}}
{\begin{flushright}\lst@language\end{flushright}}
\makeatother
8
  • Thank you for your answer. That is what I am looking for. Is it possible to reduce the distance between the environment and the language?
    – NelDav
    Commented Mar 20, 2018 at 8:41
  • @Ahrtaler an easy workaround is to add some negative vertical space at the start of the environment: \begin{flushright}\vspace{-5mm}\xlang\end{flushright}
    – Marijn
    Commented Mar 20, 2018 at 8:53
  • What should one do for a new environment from \lstnewenvironment{somename} ?
    – Qi Tianluo
    Commented Oct 16, 2022 at 10:05
  • @QiTianluo it is basically the same, see edit.
    – Marijn
    Commented Oct 16, 2022 at 10:54
  • @Marijn Thank you very much! So an additional question. Why not put the ``` \xdef ``` block also in the end section of the definition of new environment?
    – Qi Tianluo
    Commented Oct 17, 2022 at 13:41

You must log in to answer this question.

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