% LaTeX Package `lstautogobble`
% Counts the leading spaces of the first line and sets `gobble` to this number
% Copyright (c) 2011 by Martin Scharrer <martin@scharrer-online.de>
% for http://tex.stackexchange.com/questions/19953/how-to-automatically-skip-leading-white-spaces-in-listings
% This is free software under the LPPL v1.3c or later and was also posted under the CC BY-SA 3.0 license.
\ProvidesPackage{lstautogobble}[2012/02/04 v1.1 Implements 'autogobble' option for 'listings']

% This is an add-on to the `listings` package
\RequirePackage{listings}

% Counter for leading spaces
\newcount\lstag@spacecount

% Some macros for comparison:
\def\lstag@activespace{\lst@ProcessSpace}%  Definition of an active space
\def\lstag@tabulator{\lst@ProcessTabulator}%  Definition of an tabulator

\begingroup
\catcode`\^^M=\active%
\gdef\lstag@activenl{^^M}%  Active CR (ASCII 13) character which is used as line break
\endgroup


% Define `autogobble` option as boolean (by default off)
\lst@Key{autogobble}{false}[t]{\lstKV@SetIf{#1}\lst@ifautogobble}

% `ungobble` option
\lst@Key{ungobble}{0}{\def\lst@ungobble{#1}}

% Insert required code at environment init
\lst@AddToHook{Init}{\lst@autogobble}

% Autogobble init macro.
% If the option is active and `gobble` is not set, init vars and overwrite the process macro with own definition.
\def\lst@autogobble{%
    \lst@ifautogobble
        \ifnum\lst@gobble>0\else
            \def\lst@gobble{\lstag@gobble}%
            \def\lstag@gobble{0}%
            \lstag@spacecount\z@
            \def\lstag@spaceaccu{}%
            \let\lstag@restofline\empty
            \let\lstag@origlstenv@Process\lstenv@Process
            \let\lstenv@Process\lstag@countleadingspaces
        \fi
    \fi
}

% Checks if the next following character (read as argument) is a line break (as it is supposed to be)
% Otherwise there is some text direct after the `\begin{<env>}[<options>]` which is dropped by `listings`.
\def\lstag@countleadingspaces#1{%
    \expandafter\ifx\lstag@activenl#1\relax
        \expandafter\lstag@countleadingspaces@
    \else
        \def\lstag@restofline{Dummy replacement of text after begin of listing to trigger original warning message}%
        \expandafter\lstag@countleadingspaces
    \fi
}

% After the new line is found this macro counts the spaces and tabulators
\def\lstag@countleadingspaces@#1{%
    \ifx\lstag@activespace#1\relax
        \advance\lstag@spacecount by \@ne
        % Accumulate spaces (i.e. their definitions) for later re-insertion:
        \expandafter\def\expandafter\lstag@spaceaccu\expandafter{\lstag@spaceaccu\lst@ProcessSpace}%
        \let\next\lstag@countleadingspaces@
    \else% Character wasn't a space
    \ifx\lstag@tabulator#1\relax
        \advance\lstag@spacecount by \lst@tabsize\relax
        % Accumulate spaces (i.e. their definitions) for later re-insertion:
        \@tempcnta=\lst@tabsize\relax
        \loop
        \ifnum\@tempcnta>\z@
            \expandafter\def\expandafter\lstag@spaceaccu\expandafter{\lstag@spaceaccu\lst@ProcessSpace}%
            \advance\@tempcnta\m@ne
        \repeat
        \let\next\lstag@countleadingspaces@
    \else% Character wasn't a tabulator either
        % Set gobble option (indirect):
        \xdef\lstag@gobble{\the\numexpr\lstag@spacecount-\lst@ungobble\relax}%
        % Restore original definition of process macro:
        \global\let\lstenv@Process\lstag@origlstenv@Process
        % Re-insert all collected material or appropriate replacement material:
        \edef\next{\noexpand\lstenv@Process\lstag@restofline\expandafter\noexpand\lstag@activenl\expandafter\unexpanded\expandafter{\lstag@spaceaccu}\noexpand#1}%
    \fi\fi
    \next
}

\endinput