This question led to a new package:
lstautogobble
(lstaddons
bundle)
For my programming lecture slides I heavily use the listings
package with \lstnewenvironment
to typeset source code. It's a great package (no, I do not want to switch to minted
), the only thing that bugs me is that I have to pass the gobble=<indent>
option to get well formatted source as well as output:
\documentclass{beamer}
\usepackage{listings}
\lstloadlanguages{C}
\lstnewenvironment{C}[1][] {\lstset{language=C, basicstyle=\scriptsize\ttfamily, #1}}{}
\begin{document}
\begin{frame}[fragile]{A simple truth\ldots}
\begin{C}[gobble=4] % <-- ** This is annoying! **
#include <stdio.h>
int main(){
printf("tex.stackexchange.com: the coolest community ever!\n");
}
\end{C}
\end{frame}
\end{document}
Manual handling of gobble
is especially painful, if one moves code examples around and changes the nesting level. I constantly forget to update the parameter in this situations. Ideally, the C
environment in the above example would automatically determine the gobble
by the preceeding indentation (that is, number of spaces) before it in the source. Something like the following (pseudo code):
\lstnewenvironment{C}[1][] {\PreceedingWS{\WScount}%
\lstset{language=C, basicstyle=\scriptsize\ttfamily,
gobble=\the\numexpr\WScount+2\relax, #1}}{}
The idea is that \PreceedingWS
magically determines the number of spaces in the current line before the \begin{C}
and stores it in some macro (\WScount
).
Is this possible?
Summary of Results (2011-06-27)
I got three answers, two of which did actually help me:
- Aditya's solution is based on ConTeXt, which doesn't help me, but may be a good reference for those guys who actually use ConTeXt.
- Bruno's solution is a bit hacky, but has the advantage that it can be applied to (probably) any verbatim-style environment. Moreover, I have learned a bit about TeX scanning from his well-documented answer. It came "right in time" for me to safe me a reasonable amount of work.
- Martin's solution showed up relatively late. It is much cleaner as it integrates directly into the
listings
package and is provided as an own package. I am surprised by how little code he needed for this, which for me is an indicator that his solution integrates well and has a good chance to survive further evolution of thelistings
package. I certainly hope hislstautogobble
package will make it to CTAN or eventually be directly integrated intolistings
.
I have tested the latter two with my lecture slides, which contain ~100 small listings in very different settings and environments (inside tables, minipages, in combination with beamer overlays, ...), so I can say that both approaches do actually work.
To sum up: Bruno's answer became the accepted answer, as it helped me most when I actually needed it. Martin's answer received the bounty, as it is the cleaner and more stable solution which I am going to use in any future project.
listings
package. Another point is that there may be occasions where the first line does not actually define the indenting, for example, if continuing the listing of some longer function. (Well, the latter could count as a pathological case where it would be perfectly acceptable to specifygobble
manually.)\lstinputlisting
.\lstinputlisting
, but figured that it is organizational overkill and reduces the comprehensibility of both sources (LatTeX and listing) quite a bit, especially as I tend to "pollute" my listings with beamer overlay stuff. To sum up: Embedding and indenting them in the LaTeX code really is what I am up to.lstautogobble
package on CTAN as part of thelstaddons
bundle.