6

I have something that looks as follows:

\documentclass{article}
\usepackage{listings}

\lstnewenvironment{shellsession}[1][]
{\lstset{language=bash,
    basicstyle=\small\ttfamily,
    numbers=none,
    #1
  }}
{}

\begin{document}
\begin{shellsession}
  first line
  second line
  third line
\end{shellsession}
\end{document}

This gives me the following output:

basic output

No surprises there, but I'm wondering whether there is a way to prepend a character to each line. Just to be clear, the output I'd like to get is

$ first line
$ second line
$ third line
  • You might abuse line numbers, defining \thelstnumber to produce \texttt{\$}, but why not adding $ to the lines? – egreg Jan 5 '15 at 17:52
  • 1
    I don't really mind adding the $ myself. I was just thinking, if there is a way to do it, I would take advantage of it. I don't think I will abuse the line numbers. Thanks for the advice. – Justin Wood Jan 5 '15 at 17:59
  • Whatever editor you are using probably has a "column editor" mode, that lets you type the same text in a column of the text file... you might look into that, if you are going to do it manually – darthbith Jan 5 '15 at 18:13
  • 1
    @darthbirth: I'm using emacs. So I can easily edit multiple lines. Part of the issue in this case is that emacs thinks that I am still in math mode because of the uneven number of $ within the file. So it gives me a false error. – Justin Wood Jan 5 '15 at 18:56
9

You can prepend something to every "real" line (i.e. not a line created by listings's breaklines option) via a listings hook called EveryPar.

Note that, because listings hooks are global, some precautions must be taken if you're typesetting code in multiple listings languages but you only want to prepend stuff to lines of listings in a subset of those languages (only one, bash, here).

Also, be aware that, without using any countermeasures, e.g.

any indentation present in your listing environment will be typeset in the output; this may end up "pushing" your listing to the right, which is undesirable.

enter image description here

\documentclass{article}
\usepackage{listings}

\makeatletter

% define custom macro that expands to the language name
% (for comparison purposes)
\newcommand\langname@bash{}
\def\langname@bash{bash}

% define custom prompt
\newcommand\prompt@bash{\$\ }

% define a macro (initially empty) and insert it at the beginning
% of every paragraph
\newcommand\addedToEveryPar@bash{}
\lst@AddToHook{EveryPar}{\addedToEveryPar@bash}

% redefine the macro by the custom prompt, but only if the language in use
% be `bash'
\lst@AddToHook{PreInit}{%
  \ifx\lst@language\langname@bash%
    \let\addedToEveryPar@bash\prompt@bash%
  \fi
}

\makeatother


\lstnewenvironment{shellsession}[1][]
{\lstset{language=bash,
    basicstyle=\small\ttfamily,
    numbers=none,
    #1
  }}
{}

\begin{document}
\begin{shellsession}
first line
second line
third line
\end{shellsession}

% just to check that your prompt doesn't find its way into unrelated language...
% (code taken from http://stackoverflow.com/a/14560801/2541573)
\begin{lstlisting}[language=Python, basicstyle=\ttfamily]
def memo(f):
    cache = {}
    def memoized(n):
        nonlocal cache
        if n not in cache:
            cache[n] = f(n)
        return cache[n]
    return memoized
\end{lstlisting}

\end{document}

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.