14

In the manual for listings it says that gobble has no effect for lstinputlistings. Since the manual is about four years old now and after reading How to automatically skip leading white spaces in listings my question is if there is a way to activate gobble or even better autogobble for lstinputlistings?

Edit: I have tried \lstinputlistings[gobble=3]{hello.c} and it does not work and I have set tabsize=3.

MWE:

\documentclass{article}

\usepackage{listings}
\lstset{tabsize=3,frame=single,numbers=left}

\usepackage{filecontents}
\begin{filecontents*}{hello.c}
if (a<b){
    if (b<a){
        //do something
    }
}
\end{filecontents*}

\begin{document}
\noindent
Using \verb|\begin{lstlisting}... gobble=3| works:
\begin{lstlisting}[gobble=3,firstnumber=2,linerange={2-4}]
if (a<b){
    if (b<a){
        //do something
    }
}
\end{lstlisting}

\bigskip\noindent
Using \verb|\lstinputlisting gobble| does not work:
\lstinputlisting[gobble=3,firstnumber=2,linerange={2-4}]{hello.c}
\end{document}

enter image description here

Update: after playing around with S. Murugan's code I came up with this which also sets firstnumber according to firstline -- something I've also wanted.

\documentclass{article}
\usepackage{listings,xifthen,filecontents}

\lstset{tabsize=3,numbers=left,frame=single,basicstyle=\Huge\ttfamily,columns=flexible}
\newlength{\gobble}
\newlength{\gobblea}
% The width of a single space. basicstyle from lstset should be used
\sbox0{\Huge\ttfamily \ }
\newcommand{\mylist}[5]{
%#1 is number of tabs, could be calculated like in listings-autogobble with autogobble=true or be an extra option
%#2 is tabsize, which is set in lstset
%#3 is firstline from lstset
%#4 is lastline from lstset
%#5 is the filename, the only thing which should be an argument and not an option.

% Remove a single space
\setlength{\gobble}{-\the\wd0}
% Reindent a bit by dividing by 1.1, then multiply by tabsize and number of indentation levels
\setlength{\gobble}{0.90909090909090909090909090909091\gobble*#1*#2}
\setlength{\gobblea}{\gobble}
\addtolength{\gobblea}{10pt}
% Check if firstline is defined
\ifthenelse{\isempty{#3} \OR \equal{#3}{0}}{%
% Check if lastline is defined
\ifthenelse{\isempty{#4}}{%
\lstinputlisting[firstnumber=1,firstline=1,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}{
\lstinputlisting[firstnumber=1,firstline=1,lastline=#4,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}
}{
\ifthenelse{\isempty{#4}}{%
\lstinputlisting[firstnumber=#3,firstline=#3,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}{
\lstinputlisting[firstnumber=#3,firstline=#3,lastline=#4,framexleftmargin=\gobble,xleftmargin=\gobble,numbersep=\gobblea]{#5}
}
}
}

\begin{filecontents*}{hello.c}
if (b<a){
   //do something
}
\end{filecontents*}
\begin{filecontents*}{hello1.c}
if (a<b){
   if (b<a){
      //do something
   }
}
\end{filecontents*}

\begin{document}
\lstinputlisting[firstnumber=2,linerange={1-3}]{hello.c}
%mylist{#tabs}{#tabsize}{firstline}{lastline}{filename}
\mylist{1}{3}{2}{4}{hello1.c}
\mylist{2}{3}{3}{3}{hello1.c}
\end{document}

Update Now it should work for any font size (tested from 8 to 60pt) and for any basicstyle (tested from \tiny to \Huge). Now it would be really nice, if I could just write \lstinputlisting[tabs=1,firstline=2,lastline=4]{hello.c} and it would fetch tabsize=3 and basicstyle=\Huge\ttfamily from lstset{}.

Update 7/06/2013 In How to extend the \lstinputlisting command there is a nicer way to achieve the desired result.

6
  • 1
    Have you tried something like \lstinputlisting[gobble=4](hello.c} and it did not work? Please add a minimal working example (MWE) that illustrates your problem.
    – Daniel
    Feb 7 '12 at 12:06
  • You can use four space indent to show a code block instead of using <code> and <br> tags, this produce a more nice look of the code, and make it easier to read.
    – adn
    Feb 7 '12 at 12:43
  • If you indent lines by 4 spaces or enclose words in backticks `, they'll be marked as code, as can be seen in my edit. You can also highlight the code and click the "code" button (with "{}" on it). It's also possible to add syntax highlights for other languages. :) Feb 7 '12 at 12:50
  • 1
    Hope you don't mind, but I changed the MWE to show that gobble works with the lstlisting environment but not within lstinputlisting. Feb 7 '12 at 16:48
  • 1
    sed to the rescue! Feb 7 '12 at 16:50
4

Now check this:

\documentclass{article}

\usepackage{listings}
\lstset{tabsize=3,frame=single,numbers=left}

\usepackage{filecontents}
\begin{filecontents*}{hello.c}
if (a<b){
    if (b<a){
        //do something
    }
}
\end{filecontents*}

\begin{document}
\noindent Using \verb|\begin{lstlisting}... gobble=3| works:
\begin{lstlisting}[gobble=3,firstnumber=2,linerange={2-4}]
if (a<b){
    if (b<a){
        //do something
    }
}
\end{lstlisting}

\bigskip\noindent
Using \verb|\lstinputlisting gobble| does not work:

\lstinputlisting[tabsize=2,showspaces=false,gobble=3,firstnumber=2,linerange={2-4},framexleftmargin=-16pt,numbersep=-8pt,xleftmargin=-18pt]{hello.c}

\end{document}
2
  • 7
    I can't see that this answers the question. Mar 19 '12 at 17:47
  • 2
    In third last line framexleftmargin=-16pt,numbersep=-8pt,xleftmargin=-18pt is used to revert the indentation. Mar 20 '12 at 1:02
3

Since this question comes first when searching about automatically add gobble to listing, here is a solution to simply remove indentation based on first line, thanks to \usepackage{lstautogobble}:

\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage{lstautogobble} % <== this line is important

\lstset{ %
  language=C,
  numbers=left,
  autogobble=true, % <== this line is important
}

\begin{document}

\begin{lstlisting}
  int main(){
    printf("hello");
    return 0;
  }
\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.