17

I am using listings with these settings:

\lstset{language=C++,basicstyle=\small\sffamily,
  numbers=none,
  frame=tb,
  columns=fullflexible,
  showstringspaces=false
}

I like the proportionally set font, but I want to be able to align comments of different lines. Is it possible to do some kind of tabbing with the lstlisting environment?

\begin{lstlisting}
  float f;  // A float
  int anAptlyNamedInteger;  // An integer
\end{lstlisting}

I would like the two comments to be aligned horizontally.

Werner
  • 603,163
Arne
  • 1,243
  • 2
    That might be quite difficult to achieve with columns=fullflexible, which tells listings not to even try to achieve any sort of column alignment. Perhaps it can be done by using the comment sequence // as an "escape", which exits the pseudocode syntax hilighting and admits TeX commands to be used. – Niel de Beaudrap Oct 12 '11 at 15:20
  • Good idea, I think that is more or less what Peter just did below. – Arne Oct 12 '11 at 15:23

2 Answers2

20

If you are willing to change the code, then you could define an escapechar=\&, which allows you to enter a & to escape back to LaTeX ande execute a macro. Then wrap the comments in something such as:

\newcommand*{\Comment}[1]{\hfill\makebox[3.0cm][l]{#1}}%

to get the alignment you desire:

enter image description here

\documentclass{article}
\usepackage{listings}

\newcommand*{\Comment}[1]{\hfill\makebox[3.0cm][l]{#1}}%
\lstset{language=C++,basicstyle=\small\sffamily,
  numbers=none,
  frame=tb,
  columns=fullflexible,
  showstringspaces=false,
  escapechar=\&% char to escape out of listings and back to LaTeX
}

\begin{document}
\begin{lstlisting}
  float f;  &\Comment{// A float}&
  int anAptlyNamedInteger;  &\Comment{// An integer}&
\end{lstlisting}
\end{document}
Peter Grill
  • 223,288
8

This uses code from I want to indent the next line by an exactly specified position to save the position of a comment (using \SP) and re-use the position later (using \UP). It uses the savepos module from zref:

enter image description here

\documentclass{article}
\usepackage{zref-savepos}% http://ctan.org/pkg/zref
\makeatletter
% Taken from: https://tex.stackexchange.com/a/69076/5764
% \zsaveposx is defined since 2011/12/05 v2.23 of zref-savepos
\@ifundefined{zsaveposx}{\let\zsaveposx\zsavepos}{}
\makeatother
\newcounter{hposcnt}
\renewcommand*{\thehposcnt}{hpos\number\value{hposcnt}}
\newcommand*{\SP}{% set position
  \stepcounter{hposcnt}%
  \zsaveposx{\thehposcnt s}%
}
\makeatletter
\newcommand*{\UP}{% use previous position
  \zsaveposx{\thehposcnt u}%
  \zref@refused{\thehposcnt s}%
  \zref@refused{\thehposcnt u}%
  \kern\zposx{\thehposcnt s}sp\relax
  \kern-\zposx{\thehposcnt u}sp\relax
}
\makeatother

\usepackage{listings}% http://ctan.org/pkg/listings
\lstset{language=C++,basicstyle=\small\sffamily,
  numbers=none,
  frame=tb,
  columns=fullflexible,
  showstringspaces=false,
  mathescape
}
\begin{document}

\begin{lstlisting}
  float f; $\hspace{250pt}\SP$// A float
  int anAptlyNamedInteger;  $\UP$// An integer
\end{lstlisting}

\end{document}

In the example above (note that listings's mathescape option has been made active) the first comment is set at a specific position, and that position is saved using \SP. Subsequent horizontal alignment is achieved using \UP.

The solution requires at least two compiles, since it uses a \label-\ref-like system/reading from the .aux file.

Werner
  • 603,163