% --------------------------------------------------------------------------
% the CNLTX bundle
%
%   LaTeX source code and output
%
% --------------------------------------------------------------------------
% Clemens Niederberger
% Web:    https://github.com/cgnieder/cnltx/
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
% Copyright 2013--2019 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Clemens Niederberger.
% --------------------------------------------------------------------------
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
\RequirePackage{cnltx-base}
\ProvidesPackage{cnltx-example}[\cnltx@@date\space \cnltx@@version\space \cnltx@@info]
\cnltx@load@modules{listings,translations}

\cnltx@create@bundle@message{example}{Error}
\cnltx@create@bundle@message{example}{Warning}
\cnltx@create@bundle@message{example}{WarningNoLine}
\cnltx@create@bundle@message{example}{Info}

% --------------------------------------------------------------------------
\PassOptionsToPackage{framemethod=tikz}{mdframed}
\RequirePackage{mdframed}
\RequirePackage{idxcmds}
\RequirePackage{textcomp}
\RequirePackage{adjustbox}
\RequirePackage{ifxetex}

% --------------------------------------------------------------------------
% \code
\newrobustcmd*\code[1]{\begingroup\codefont#1\endgroup}
\newcommand*\verbcode{\lstinline[style=cnltx-inline]}
\newcommand*\codefont{\ttfamily}
\pgfkeys{
  cnltx/.cd,
    code-font/.code = \def\codefont{#1} ,
}

% --------------------------------------------------------------------------
% command descriptions:
% \cs
\newidxcmd\cs{\code{\textbackslash\textcolor{cs}{#1}}}

% \env
\newidxcmd\env{\code{\textcolor{env}{#1}}}[\ (\GetTranslation{cnltx-environment})]

% \begin, \end
\newidxcmd\beginend{\code{\textbackslash\textcolor{beginend}{#1}}}
\def\beginenv{\@ifstar{\beginend*{begin}}{\beginend{begin}}}
\def\endenv{\@ifstar{\beginend*{end}}{\beginend{end}}}

% --------------------------------------------------------------------------
% option descriptions:
\def\cnltx@isvalue{%
  \nobreak\hskip.3333em plus .1667em =\hskip.3333em plus .1667em }

% \option
\newidxcmd\option{\code{\textcolor{option}{#1}}}
\newidxcmd\module{\code{\textcolor{module}{#1}}}

\newrobustcmd*\key{\@ifstar{\cnltx@key@star}{\cnltx@key@nostar}}

\newrobustcmd*\cnltx@key@star{%
  \cnltx@ifdash
    {\cnltx@key@aux*\meta}
    {\cnltx@key@aux*\marg}%
}
\newrobustcmd*\cnltx@key@nostar{%
  \cnltx@ifdash
    {\cnltx@key@aux{}\meta}
    {\cnltx@key@aux{}\marg}%
}
\newcommand*\cnltx@key@aux[4]{%
  \code{\option#1{#3}\cnltx@isvalue#2{#4}}%
}

\newrobustcmd*\keyis{%
  \@ifstar
    {\cnltx@keyis*}
    {\cnltx@keyis{}}%
}
\newrobustcmd*\cnltx@keyis[1]{%
  \cnltx@ifdash
    {\cnltx@key@aux{#1}\@firstofone}
    {\cnltx@key@aux{#1}\Marg}%
}

\newlength\cnltx@choice@sep@stretch
\setlength\cnltx@choice@sep@stretch{\z@\@plus.5em}
% \DeclareListParser*\cnltx@choices{|}
\newrobustcmd*\choices[1]{%
  \def\cnltx@choice@sep{%
    \def\cnltx@choice@sep{%
      \hskip\cnltx@choice@sep@stretch|\hskip\cnltx@choice@sep@stretch
    }%
  }%
  \forcsvlist{\cnltx@choice@sep\code}{#1}%
}

\RequirePackage[normalem]{ulem}
\newrobustcmd*\default[1]{\uline{#1}}

\pgfkeys{
  cnltx/.cd,
    default-value/.code = \def\default##1{#1{##1}}
}

\newrobustcmd*\choicekey{%
  \@ifstar
    {\cnltx@choicekey@star}
    {\cnltx@choicekey@nostar}%
}
\def\cnltx@choicekey@star#1#2{%
  \code{\option*{#1}\cnltx@isvalue\choices{#2}}}
\def\cnltx@choicekey@nostar#1#2{%
  \code{\option{#1}\cnltx@isvalue\choices{#2}}}

\newcommand*\boolkey{%
  \@ifstar
    {\cnltx@boolkey@star}
    {\cnltx@boolkey@nostar}%
}

\def\cnltx@boolkey@star#1{\choicekey*{#1}{\default{true},false}}
\def\cnltx@boolkey@nostar#1{\choicekey{#1}{\default{true},false}}

% --------------------------------------------------------------------------
% argument descriptions:
% \meta
\newcommand*\meta[1]{%
  $\langle$%
    \textcolor{meta}{{\argumentformat#1}}%
  $\rangle$%
}

% arguments:
\newcommand*\argumentformat{\normalfont\itshape}

\pgfkeys{
  cnltx/.cd,
    arg-format/.code = \renewcommand*\argumentformat{#1} ,
}

\newcommand*\newarg[4][\meta]{%
  \newcommand*#2[1]{%
    \code{\textcolor{argument}{%
      #3\textnormal{\ifblank{##1}{}{#1{##1}}}#4}}%
  }%
}

\newarg\marg{\{}{\}}
\newarg[\code]\Marg{\{}{\}}
\newarg\oarg{[}{]}
\newarg[\code]\Oarg{[}{]}
\newarg\darg{(}{)}
\newarg[\code]\Darg{(}{)}
\newcommand*\sarg{\textcolor{argument}{\code{*}}}
\newcommand*\parg{\textcolor{argument}{\code{+}}}

% --------------------------------------------------------------------------
% source code examples:
% format of the source code:
\newcommand*\sourceformat{\codefont\small}
% format of the iput example:
\newcommand*\exampleformat{}

\pgfkeys{
  cnltx/.cd,
    source-format/.code = \renewcommand*\sourceformat{#1} ,
    expl-format/.code = \renewcommand*\exampleformat{#1} ,
}

% see http://tex.stackexchange.com/a/114580/5049 for reference on the `nolig'
% trick, thanks to @egreg!

\newrobustcmd\cnltx@treat@lst@index[2]{%
  \newrobustcmd#1[1]{%
    \begingroup
      \let\lst@nolig\@empty
      \def\cnltx@tmp@index{##1}%
      \expandafter\cnltx@replace@all
        \expandafter\cnltx@tmp@index
        \expandafter{\cnltxotherat}{\cnltxat}%
      \cnltx@replace@all\cnltx@tmp@index{@}{\cnltxat}%
      \expandafter#2\expandafter{\cnltx@tmp@index}%
    \endgroup
  }%
}

\cnltx@treat@lst@index{\indexcs}{\csidx}
\cnltx@treat@lst@index{\indexenv}{\envidx}

% this command is undocumented and not used; it requires `cnltx-tools':
\newcommand\cnltx@copyablespace{%
  \cnltx@accsupp{00A0}{method=hex,unicode}{\ }%
}

\lst@RequireAspects{writefile}
\providecommand*\MakePercentComment{\cnltx@set@catcode{\%}{14}}

\def\cnltx@gobble{2}

% listings style for source code:
\def\cnltx@listings@style{
  language         = [AlLaTeX]TeX,
  alsolanguage     = [plain]TeX,
  basicstyle       = {\sourceformat},
  numbers          = left,
  numberstyle      = \tiny,
  xleftmargin      = 1em,
  numbersep        = .75em,
  gobble           = \cnltx@gobble ,
  columns          = fullflexible,
  literate         =
    {ä}{{\"a}}{1}
    {ö}{{\"o}}{1}
    {ü}{{\"u}}{1}
    {Ä}{{\"A}}{1}
    {Ö}{{\"O}}{1}
    {Ü}{{\"U}}{1}
    {ß}{{\ss}}{1} ,
  upquote          = true,
  breaklines       = true,
  keepspaces       = true,
  breakindent      = 1em,
  commentstyle     = \color{comment},
  keywordstyle     = \color{cs},
  deletetexcs      =
    {
      a,o,u,A,O,U,
      begin,
      center,
      description,document,
      end,enumerate,
      equation,eqnarray,
      figure,flushleft,flushright,
      itemize,list,
      otherlanguage,
      table,tabu,tabular
    },
  deletekeywords   =
    {
      a,o,u,A,O,U,
      begin,
      center,
      description,document,
      end,enumerate,
      equation,eqnarray,
      figure,flushleft,flushright,
      itemize,list,
      math,
      otherlanguage,
      table,tabu,tabular
    },
  texcs = , keywords = ,
  % \begin, \end:
  texcsstyle       = [2]\color{beginend},
  index            = [2][texcs2],
  indexstyle       = [2]\@gobble,
  moretexcs        = [2]{begin,end},
  % control sequences that'll be indexed:
  texcsstyle       = [3]\color{cs},
  index            = [3][texcs3],
  indexstyle       = [3]\indexcs,
  % control sequences that won't be indexed:
  texcsstyle       = [4]\color{cs},
  index            = [4][texcs4],
  indexstyle       = [4]\@gobble,
  % added environments that'll be indexed:
  keywordstyle     = [5]\color{env},
  index            = [5][keyword5],
  indexstyle       = [5]\indexenv,
  % environments that won't be indexed:
  keywordstyle     = [6]\color{env},
  index            = [6][keyword6],
  indexstyle       = [6]\@gobble,
  moredelim        = *[s][\color{math}]{$}{$}
}

\def\cnltx@bibtex@listings@style{
  language         = BiBTeX,
  basicstyle       = {\sourceformat},
  numbers          = left,
  numberstyle      = \tiny,
  xleftmargin      = 1em,
  numbersep        = .75em,
  gobble           = \cnltx@gobble ,
  columns          = fullflexible,
  literate         =
    {ä}{{\"a}}1
    {ö}{{\"o}}1
    {ü}{{\"u}}1
    {Ä}{{\"A}}1
    {Ö}{{\"O}}1
    {Ü}{{\"U}}1
    {ß}{{\ss}}1 ,
  upquote          = true,
  breaklines       = true,
  keepspaces       = true,
  breakindent      = 1em,
  commentstyle     = \color{comment},
  keywordstyle     = \color{bibentry} ,
  keywordstyle     = [2]\color{bibentryfield}\itshape ,
  showstringspaces = false ,
  deleteindex      = [3][texcs3] ,
  deleteindex      = [5][keyword5] ,
  deleteindex      = [6][keyword6]
}

\def\cnltx@makeindex@listings@style{
  language         = makeindex,
  basicstyle       = {\sourceformat},
  numbers          = left,
  numberstyle      = \tiny,
  xleftmargin      = 1em,
  numbersep        = .75em,
  gobble           = \cnltx@gobble ,
  columns          = fullflexible,
  literate         =
    {ä}{{\"a}}1
    {ö}{{\"o}}1
    {ü}{{\"u}}1
    {Ä}{{\"A}}1
    {Ö}{{\"O}}1
    {Ü}{{\"U}}1
    {ß}{{\ss}}1 ,
  breaklines       = true,
  keepspaces       = true,
  breakindent      = 1em,
  commentstyle     = \color{comment},
  keywordstyle     = \color{makeidxkey}\bfseries ,
  stringstyle      = \color{makeidxstring} ,
  showstringspaces = false ,
  deleteindex      = [3][texcs3] ,
  deleteindex      = [5][keyword5] ,
  deleteindex      = [6][keyword6]
}

\def\cnltx@bash@listings@style{
  language         = bash,
  basicstyle       = {\sourceformat\color{black}},
  % numbers          = left,
  % numberstyle      = \tiny,
  xleftmargin      = 1em,
  numbersep        = .75em,
  gobble           = \cnltx@gobble ,
  columns          = fullflexible,
  literate         =
    {ä}{{\"a}}1
    {ö}{{\"o}}1
    {ü}{{\"u}}1
    {Ä}{{\"A}}1
    {Ö}{{\"O}}1
    {Ü}{{\"U}}1
    {ß}{{\ss}}1 ,
  upquote          = true,
  breaklines       = true,
  keepspaces       = true,
  breakindent      = 1em,
  commentstyle     = \color{comment},
  keywordstyle     = \color{black}\bfseries ,
  stringstyle      = \color{black} ,
  showstringspaces = false ,
  morekeywords     = texdoc ,
  deleteindex      = [3][texcs3] ,
  deleteindex      = [5][keyword5] ,
  deleteindex      = [6][keyword6]
}

\newcommand*\cnltx@prompt{}
\patchcmd\lst@NewLine
  {\hbox{}}
  {\hbox{}\cnltx@prompt}
  {}
  {}

\cnltx@expandargs(nx)\lstdefinestyle
  {cnltx}
  {\expandonce\cnltx@listings@style}

\cnltx@expandargs(nx)\lstdefinestyle
  {cnltx-bibtex}
  {\expandonce\cnltx@bibtex@listings@style}

\cnltx@expandargs(nx)\lstdefinestyle
  {cnltx-makeindex}
  {\expandonce\cnltx@makeindex@listings@style}

\cnltx@expandargs(nx)\lstdefinestyle
  {bash}
  {\expandonce\cnltx@bash@listings@style}

\lstdefinestyle
  {cnltx-inline}
  {
    style=cnltx,
    basicstyle = \codefont
  }

\def\cnltx@addcmds#1{%
  \cnltx@expandargs(nx)\lstdefinestyle
    {cnltx}
    {\expandonce\cnltx@listings@style,\unexpanded{moretexcs={[3]#1}}}%
  \edef\cnltx@listings@style{%
    \expandonce\cnltx@listings@style,\unexpanded{moretexcs={[3]#1}}%
  }%
}

\def\cnltx@addsilentcmds#1{%
  \cnltx@expandargs(nx)\lstdefinestyle
    {cnltx}
    {\expandonce\cnltx@listings@style,\unexpanded{moretexcs={[4]#1}}}%
  \edef\cnltx@listings@style{%
    \expandonce\cnltx@listings@style,\unexpanded{moretexcs={[4]#1}}%
  }%
}

\cnltx@expandargs(o)\cnltx@addsilentcmds{\cnltx@predefined@control@sequences}

\def\cnltx@addenvs#1{%
  \cnltx@expandargs(nx)\lstdefinestyle
    {cnltx}
    {\expandonce\cnltx@listings@style,\unexpanded{morekeywords={[5]#1}}}%
  \edef\cnltx@listings@style{%
    \expandonce\cnltx@listings@style,\unexpanded{morekeywords={[5]#1}}%
  }%
}

\def\cnltx@addsilentenvs#1{%
  \cnltx@expandargs(nx)\lstdefinestyle
    {cnltx}
    {\expandonce\cnltx@listings@style,\unexpanded{morekeywords={[6]#1}}}%
  \edef\cnltx@listings@style{%
    \expandonce\cnltx@listings@style,\unexpanded{morekeywords={[6]#1}}%
  }%
}

\cnltx@expandargs(o)\cnltx@addsilentenvs{\cnltx@predefined@environments}

\def\cnltx@addlistingsoptions#1{%
  \cnltx@expandargs(nx)\lstdefinestyle
    {cnltx}
    {\expandonce\cnltx@listings@style,\unexpanded{#1}}%
  \edef\cnltx@listings@style{%
    \expandonce\cnltx@listings@style,\unexpanded{#1}%
  }%
}

\def\cnltx@local@listings@options{}
\newbool{cnltx@local@sourcecode@overwrite}

\pgfkeys{
  cnltx/.cd,
    gobble/.code                 = \def\cnltx@gobble{#1} ,
    add-cmds/.code               = \cnltx@addcmds{#1} ,
    add-silent-cmds/.code        = \cnltx@addsilentcmds{#1} ,
    add-listings-options/.code   = \cnltx@addlistingsoptions{#1} ,
    listings-options/.code       = \lstdefinestyle{cnltx}{#1} ,
    add-envs/.code               = \cnltx@addenvs{#1} ,
    add-silent-envs/.code        = \cnltx@addsilentenvs{#1} ,
    add-sourcecode-options/.code =
      \edef\cnltx@local@listings@options{\trim@spaces@noexp{#1}} ,
    sourcecode-options/.code     =
      \booltrue{cnltx@local@sourcecode@overwrite}
      \edef\cnltx@local@listings@options{\trim@spaces@noexp{#1}}
}

\def\cnltx@mdframed@options
  {
    backgroundcolor = cnltxbg ,
    linecolor       = cnltx ,
    roundcorner     = 5pt ,
    skipabove       = .5\baselineskip ,
    skipbelow       = .5\baselineskip
  }
\cnltx@expandargs(nx)\mdfdefinestyle
  {cnltx}
  {\expandonce\cnltx@mdframed@options}

\def\cnltx@addmdframedoptions#1{%
  \cnltx@expandargs(nx)\mdfdefinestyle
    {cnltx}
    {\expandonce\cnltx@mdframed@options,\unexpanded{#1}}%
}

\def\cnltx@local@frame@options{}
\newbool{cnltx@local@frame@overwrite}

\newbool {cnltx@sidebyside}
\newbool {cnltx@codeleft}
\booltrue{cnltx@codeleft}
\newbool {cnltx@codeonly}
\newbool {cnltx@compile}
\newbool {cnltx@float}
\newbool {cnltx@pagelist}
\newbool {cnltx@outside}% use this to allow floating material in the examples

\newsavebox\cnltx@example@box

\newlength\cnltx@sidebysidewidth
\newlength\cnltx@before@skip
\newlength\cnltx@after@skip

\newcommand*\cnltx@examplesep{\hrulefill}
\newcommand*\cnltx@pre@source@hook{}
\newcommand*\cnltx@after@source@hook{}
\newcommand*\cnltx@pre@example@hook{}
\newcommand*\cnltx@after@example@hook{}
\newcommand*\cnltx@image@max@height{.5\textheight}
\newcommand*\cnltx@image@options{}
\newcommand*\cnltx@example@fileext{pdf}
\newcommand*\cnltx@float@type{figure}
\newcommand*\cnltx@float@pos{}
  \edef\cnltx@float@pos{[\csuse{fps@\cnltx@float@type}]}
\newcommand*\cnltx@float@caption{}
\newcommand*\cnltx@float@start{}
\newcommand*\cnltx@init@float{%
  \edef\cnltx@float@start{%
    \noexpand\begin{\expandonce\cnltx@float@type}\expandonce\cnltx@float@pos}%
}
\cnltx@init@float

\newcounter{cnltx@filenumber}
\newcounter{cnltx@runs}
\setcounter{cnltx@runs}{2}
\newcounter{cnltx@pdfpages}
\newcounter{cnltx@maxpages}
\setcounter{cnltx@maxpages}{4}

\pgfkeys{
  cnltx/.cd,
    side-by-side/.is if        = cnltx@sidebyside ,
    code-only/.is if           = cnltx@codeonly ,
    code-left/.is if           = cnltx@codeleft ,
    compile/.is if             = cnltx@compile ,
    code-sep/.code             = \def\cnltx@examplesep{#1} ,
    pre-code/.code             = \def\cnltx@pre@source@hook{#1} ,
    after-code/.code           = \def\cnltx@after@source@hook{#1} ,
    pre-output/.code           = \def\cnltx@pre@example@hook{#1} ,
    after-output/.code         = \def\cnltx@after@example@hook{#1} ,
    add-frame-options/.code    = \cnltx@addmdframedoptions{#1} ,
    frame-options/.code        = \mdfdefinestyle{cnltx}{#1} ,
    add-local-frame/.code      = \def\cnltx@local@frame@options{#1} ,
    local-frame/.code          =
      \booltrue{cnltx@local@frame@overwrite}
      \def\cnltx@local@frame@options{#1} ,
    gobble/.code               = \def\cnltx@gobble{#1} ,
    max-pages/.code            = \setcounter{cnltx@maxpages}{#1} ,
    max-height/.code           = \def\cnltx@image@max@height{#1} ,
    pages/.code                =
      \cnltx@get@page@list{#1}
      \booltrue{cnltx@pagelist} ,
    runs/.code                 = \setcounter{cnltx@runs}{#1} ,
    program/.code              = \def\cnltx@compilation@methods{#1} ,
    file-ext/.code             = \def\cnltx@example@fileext{#1} ,
    exe-with/.code             = \def\cnltx@compilation@options{#1} ,
    graphics/.code             = \def\cnltx@image@options{#1} ,
    float/.code                =
      \ifstrequal{#1}{true}
        {%
          \booltrue{cnltx@float}%
          \edef\cnltx@float@pos{[\csuse{fps@\cnltx@float@type}]}%
        }{%
          \ifstrequal{#1}{false}
            {\boolfalse{cnltx@float}}
            {%
              \booltrue{cnltx@float}%
              \def\cnltx@float@pos{[#1]}%
            }%
        }
      \cnltx@init@float ,
    float/.default             = true ,
    float-env/.code            = \def\cnltx@float@type{#1} ,
    caption/.code              =
      \booltrue{cnltx@float}%
      \renewcommand\cnltx@float@caption{#1} ,
    float-pos/.code            = \def\cnltx@float@pos{[#1]}\cnltx@init@float ,
    outside/.is if             = cnltx@outside ,
    add-frame/.is choice ,
    add-frame/true/.code       = \def\cnltx@adjustbox@frame{frame} ,
    add-frame/false/.code      = \def\cnltx@adjustbox@frame{} ,
    add-frame/.default         = true ,
    before-skip/.code          = \setlength\cnltx@before@skip{#1} ,
    after-skip/.code           = \setlength\cnltx@after@skip{#1}         
}

\setlength\cnltx@before@skip{\baselineskip}
\setlength\cnltx@after@skip{\baselineskip}

\newcommand*\cnltx@get@page@list[1]{%
  \forcsvlist{\cnltx@read@page@list@item}{#1}%
}
\newcommand*\cnltx@read@page@list@item[1]{%
  \cnltx@if@in{#1}{-}
    {\cnltx@addrangeto@page@list#1\q@stop}
    {\cnltx@addto@page@list{#1}}%
}
\newcommand*\cnltx@pagelist{}
\newcommand*\cnltx@addto@page@list[1]{\listadd\cnltx@pagelist{#1}}
\newcommand*\cnltx@addrangeto@page@list{}
\def\cnltx@addrangeto@page@list#1-#2\q@stop{%
  \setcounter{cnltx@tmpa}{#1}%
  \setcounter{cnltx@tmpb}{#2}%
  \whileboolexpr
    { test {\ifnumgreater{\value{cnltx@tmpb}+1}{\value{cnltx@tmpa}}} }
    {%
      \listeadd\cnltx@pagelist{\arabic{cnltx@tmpa}}%
      \stepcounter{cnltx@tmpa}%
    }%
}

\newcommand*\cnltx@example@input[1]{%
  \begingroup
    \trivlist\item\relax
      % what about those:
      % \leftskip\@totalleftmargin
      % \rightskip\z@skip
      % \@topsep\z@
      % \parskip\z@
      % \partopsep\z@
      % don't know why this is necessary but it is:
      \catcode`\^^M=5\relax
      \makeatother
      \MakePercentComment
      % want special formatting for the input example:
      \exampleformat
      % we're in a list so the first paragraph is not indented;
      % let's make the input example be the second paragraph:
      \if@minipage\else
        \par\mbox{}\par\vskip-\baselineskip\relax
      \fi
      \input{#1}%
    \endtrivlist
  \endgroup
}

\newcommand*\cnltx@exe{\immediate\write18}
\newrobustcmd*\cnltx@add@program[1]{%
  \expandafter\newcommand
  \expandafter*\csname cnltx@program@#1\endcsname{#1}%
}
\cnltx@add@program{pdflatex}
\cnltx@add@program{lualatex}
\cnltx@add@program{xelatex}
\cnltx@add@program{arara}
\cnltx@add@program{biber}
\cnltx@add@program{bibtex}

\newcommand*\cnltx@compile[3]{%
  \ifcsdef{cnltx@program@#1}
    {%
      \setcounter{cnltx@tmpa}{\value{cnltx@runs}}%
      \whileboolexpr
        { test {\ifnumgreater{\value{cnltx@tmpa}}{0}} }
        {
          \cnltx@exe{\csuse{cnltx@program@#1}\ifblank{#2}{}{ #2} #3}%
          \addtocounter{cnltx@tmpa}{-1}%
        }%
    }
    {\cnltx@example@error{Unknown compilation method `#1'}}%
}
\newcommand*\cnltx@compilation@methods{pdflatex}
\newcommand*\cnltx@compilation@options{}

\newrobustcmd*\cnltx@compilation@process[2]{
  \cnltx@expandargs(oo)\cnltx@compile
    {#2}
    {\cnltx@compilation@options}
    {#1}%
}

\newrobustcmd*\cnltx@get@pdfpages[1]{%
  \begingroup
    \ifxetex
      \edef\cnltx@tmpa{\the\XeTeXpdfpagecount #1 }%
      \setcounter{cnltx@pdfpages}{\cnltx@tmpa}%
    \else
      \sbox0{%
        \includegraphics{#1}%
        \setcounter{cnltx@pdfpages}{\pdflastximagepages}%
      }%
    \fi
  \endgroup
}

\newrobustcmd*\cnltx@source@input@start[1]{%
  \ifboolexpr{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
    {%
      \adjustbox{
        % discard,
        trim= 0pt 0pt \linewidth{} 0pt,
        valign=c,
        gstore=\cnltx@example@box,
        discard
      }\bgroup
    }
    {\cnltx@pre@source@hook}%
  \lst@BeginAlsoWriteFile{#1}%
}

\newrobustcmd*\cnltx@source@input@end{%
  \lst@EndWriteFile
  \ifboolexpr{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
    {\egroup}{\cnltx@after@source@hook}%
}

\newrobustcmd*\cnltx@example@start[1]{%
  \pgfqkeys{/cnltx}{#1}%
  \ifbool{cnltx@local@sourcecode@overwrite}
    {%
      \cnltx@expandargs(x)\lstset{
        \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
        {linewidth=\cnltx@sidebysidewidth,}{}%
        \expandonce\cnltx@local@listings@options
      }%
    }
    {%
      \cnltx@expandargs(x)\lstset{
        style=cnltx,
        \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
          {linewidth=\cnltx@sidebysidewidth,}{}%
        \expandonce\cnltx@local@listings@options
      }%
    }%
  \ifbool{cnltx@local@frame@overwrite}
    {%
      \cnltx@expandargs(nxx)%
      \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
        {%
          \noexpand\mdframed[
            \expandonce\cnltx@local@frame@options,
            nobreak=true]
        }
        {%
          \noexpand\mdframed[
            \expandonce\cnltx@local@frame@options,
            nobreak=false]
        }%
    }
    {%
      \cnltx@expandargs(nxx)%
      \ifboolexpe{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
        {%
          \noexpand\mdframed[
            style=cnltx,
            \expandonce\cnltx@local@frame@options,
            nobreak=true]
        }
        {%
          \noexpand\mdframed[
            style=cnltx,
            \expandonce\cnltx@local@frame@options,
            nobreak=false]
        }%
    }%
}

\newcommand*\cnltx@adjustbox@frame{frame}

% #1: filename
% #2: number of pages
% #3: current page
\newrobustcmd*\cnltx@print@documentpage[3]{%
  \cnltx@expandargs(x)\setlength\cnltx@tmpa@length{%
    \strip@pt\dimexpr1pt/%
    \ifnumgreater{#2}{\value{cnltx@maxpages}}
      {\value{cnltx@maxpages}}
      {#2}%
    \relax \noexpand\linewidth
  }%
  \ifblank{#3}{}{%
    \adjustbox{
      \cnltx@adjustbox@frame,
      max width = \cnltx@tmpa@length ,
      max height = \cnltx@image@max@height
    }{%
      \ifnumgreater{#3}{\value{cnltx@pdfpages}}
        {%
          \cnltx@example@warning
            {
              The file `#1.\cnltx@example@fileext' has less than #3 pages,
              namely \arabic{cnltx@pdfpages}%
            }%
          \parbox[b]{\cnltx@tmpa@length}{%
            \raggedright
            Page number #3 does not exist.  \code{#1} only has
            \arabic{cnltx@pdfpages} pages.%
          }%
        }
        {%
          \expandafter\includegraphics
          \expandafter[\cnltx@image@options,page=#3]
            {\jobname-cnltx-\arabic{cnltx@filenumber}.\cnltx@example@fileext}%
        }%
    }%
    \ifboolexpr
      {
        test
         {\ifnumgreater{#2}{\value{cnltx@maxpages}}}
        and test
         {
           \ifnumequal
              {\cnltx@modulo{#3}{\value{cnltx@maxpages}}}
              {0}
          }
      }
      {\newline}{}%
  }%
}

\newrobustcmd*\cnltx@stepcounter@ifnotempty[2]{%
  \ifblank{#2}{}{\stepcounter{#1}}%
}

\newrobustcmd*\cnltx@example@end[1]{%
  \ifblank{#1}{\booltrue{cnltx@codeonly}}{}
  \ifboolexpr
    {
      bool {cnltx@codeonly} or
      bool {cnltx@compile} or
      bool {cnltx@outside}
    }
    {}
    {% direct input of code example
      % \showthe\wd\cnltx@example@box
      % \showthe\linewidth
      \ifbool{cnltx@sidebyside}
        {% side-by-side
          \ifbool{cnltx@codeleft}
            {% code on the left
              \noindent
              \minipage[c]{\cnltx@sidebysidewidth}%
                \cnltx@pre@source@hook
                \unhbox\cnltx@example@box
                \cnltx@after@source@hook
              \endminipage\hfill
              \minipage[c]{\cnltx@sidebysidewidth}%
                \cnltx@pre@example@hook
                \cnltx@example@input{#1.code}%
                \cnltx@after@example@hook
              \endminipage
            }
            {% code on the right
              \noindent
              \minipage[c]{\cnltx@sidebysidewidth}%
                \cnltx@pre@example@hook
                \cnltx@example@input{#1.code}%
                \cnltx@after@example@hook
              \endminipage\hfill
              \minipage[c]{\cnltx@sidebysidewidth}%
                \cnltx@pre@source@hook
                \unhbox\cnltx@example@box
                \cnltx@after@source@hook
              \endminipage
            }%
        }
        {% example below
          \par\noindent\cnltx@examplesep
          \cnltx@pre@example@hook
          \cnltx@example@input{#1.code}%
          \cnltx@after@example@hook
        }%
    }%
  \ifbool{cnltx@compile}
    {% compile file and include document
      \cnltx@ifshellescape
        {%
          \cnltx@example@info
            {%
              Compiling example `#1.tex' \arabic{cnltx@runs}
              time\ifnum\value{cnltx@runs}>1s\fi\space with
              \cnltx@compilation@methods
            }%
          \cnltx@expandargs(no)\forcsvlist
            {\cnltx@compilation@process{#1}}
            {\cnltx@compilation@methods}%
        }
        {%
          \cnltx@example@warning
            {`shell-escape' or `write18' not enabled -- I'm  not compiling}%
        }%
      \IfFileExists{#1.\cnltx@example@fileext}
        {%
          \cnltx@get@pdfpages{#1.\cnltx@example@fileext}%
          \setcounter{cnltx@tmpa}{1}%
          \setcounter{cnltx@tmpb}{\value{cnltx@pdfpages}}%
          \ifbool{cnltx@float}
            {%
              \endmdframed
              \cnltx@float@start
            }
            {\par\noindent\cnltx@examplesep\par}%
          \cnltx@pre@example@hook
          \ifbool{cnltx@pagelist}
            {%
              \setcounter{cnltx@tmpa}{0}%
              \forlistloop
                {\cnltx@stepcounter@ifnotempty{cnltx@tmpa}}
                \cnltx@pagelist
              \ifnumgreater{\value{cnltx@tmpa}}{1}
                {\noindent}
                {\centering}%
              \forlistloop
                {\cnltx@print@documentpage{#1.\cnltx@example@fileext}{\value{cnltx@tmpa}}}
                \cnltx@pagelist
            }
            {%
              \ifnumequal{\value{cnltx@pdfpages}}{1}
                {\centering}
                {\noindent}%
              \whileboolexpr
                { test {\ifnumgreater{\value{cnltx@tmpb}}{0}} }
                {%
                  \cnltx@print@documentpage
                    {#1.\cnltx@example@fileext}
                    {\value{cnltx@pdfpages}}
                    {\value{cnltx@tmpa}}%
                  \stepcounter{cnltx@tmpa}%
                  \setcounter{cnltx@tmpb}{\numexpr\value{cnltx@tmpb}-1\relax}%
                }
            }%
          \ifbool{cnltx@float}
            {%
              \cnltx@after@example@hook
              \ifdefvoid\cnltx@float@caption{}{\caption{\cnltx@float@caption}}%
              \expandafter\end\expandafter{\cnltx@float@type}%
            }
            {%
              \cnltx@after@example@hook
              \endmdframed
              \par
            }%
        }
        {\endmdframed\par}%
    }% 
    {%
      \endmdframed\par
      \ifbool{cnltx@outside}
        {%
          \cnltx@pre@example@hook
          \cnltx@example@input{#1.code}%
          \cnltx@after@example@hook
        }
        {}%
    }%
  \ignorespacesafterend
}

\def\cnltx@new@sourcecode@env#1#2{%
  \lstnewenvironment{#2}[1][]
    {%
      \vskip\cnltx@before@skip
      \setlength\cnltx@sidebysidewidth
        {\dimexpr .45\columnwidth -\lst@xleftmargin -\lst@xrightmargin\relax}%
      \ifboolexpr{ bool {cnltx@sidebyside} and not bool {cnltx@codeonly} }
        {\cnltx@addlistingsoptions{linewidth=\cnltx@sidebysidewidth}}
        {}%
      \cnltx@example@start{##1,#1}%
      \ifbool{cnltx@compile}{%
        \stepcounter{cnltx@filenumber}%
        \cnltx@source@input@start{\jobname-cnltx-\arabic{cnltx@filenumber}.tex}%
      }{\cnltx@source@input@start{\jobname-cnltx.code}}%
    }
    {%
      \cnltx@source@input@end
      \ifbool{cnltx@compile}
        {\cnltx@example@end{\jobname-cnltx-\arabic{cnltx@filenumber}}}
        {\cnltx@example@end{\jobname-cnltx}}%
      % see http://tex.stackexchange.com/a/136264/5049
      % for the reasoning behind this:
      \if@nobreak
        \@nobreakfalse
      \fi
      \csname par\endcsname
      \vskip\cnltx@after@skip
    }%
}
  
\newrobustcmd\newsourcecodeenv[2][]{%
  \cnltx@new@sourcecode@env{#1}{#2}%
}

\def\cnltx@input@sourcecode@file#1#2{%
  \begingroup
    \cnltx@example@start{#1}%
    \lstinputlisting{#2}%
    \cnltx@example@end{#2}%
  \endgroup
}

\def\cnltx@new@input@source@file#1#2{%
  \newcommand#2[2][]{\cnltx@input@sourcecode@file{#1,##1}{##2}}%
}

\newrobustcmd*\newinputsourcefilecmd[2][]{%
  \cnltx@new@input@source@file{#1}{#2}%
}

\newsourcecodeenv{example}
\newsourcecodeenv[side-by-side]{sidebyside}
\newsourcecodeenv[code-only]{sourcecode}

\newsourcecodeenv[
  code-only,
  sourcecode-options={style=bash},
  pre-code=\def\cnltx@prompt{\textasciitilde\space\$\space}
]{bash}

\newinputsourcefilecmd\inputexample
\newinputsourcefilecmd[side-by-side]\inputsidebyside
\newinputsourcefilecmd[code-only]\inputsourcecode

\newrobustcmd*\implementation[2][]{%
  \lstinputlisting[style=cnltx,#1]{#2}%
}

% --------------------------------------------------------------------------
% packages and classes:
\newcommand*\packageformat{\sffamily}
\newcommand*\classformat{\sffamily}
\newcommand*\bundleformat{\sffamily}

\newidxcmd\pkg{{\packageformat#1}}[\ (\GetTranslation{cnltx-package})]
\newidxcmd\cls{{\classformat#1}}[\ (\GetTranslation{cnltx-class})]
\newidxcmd\bnd{{\bundleformat#1}}[\ (\GetTranslation{cnltx-bundle})]

\pgfkeys{
  cnltx/.cd,
    pkg-format/.code = \renewcommand*\packageformat{#1} ,
    cls-format/.code = \renewcommand*\classformat{#1}
}

% disable indexing commands in PDF strings:
\AtBeginDocument{%
  \providecommand\pdfstringdefDisableCommands[1]{}%
  \pdfstringdefDisableCommands{%
    \def\code#1{#1}%
    \def\cs*#1{\textbackslash#1}%
    \def\env*{}%
    \def\option*{}%
    \def\pkg*{}%
    \def\cls*{}%
    \def\bnd*{}%
    \def\key*#1#2{#1 = #2}%
  }%
}

\endinput

% --------------------------------------------------------------------------
HISTORY:

2013/09/08 v0.1   - first working version
2013/09/10 v0.2   - added \keyis
                  - lot's of improvements on the source code example
                    environments
                  - disable indexing commands in PDF strings
                  - added hooks to the source example environments
                  - added possibility for internationalization
                  - new macro \verbcode
                  - added optional argument to \newarg
                  - new macros \Marg, \Oarg, \Darg
                  - option for formatting the \default command
2013/09/12 v0.3   - added \module
                  - added \newsourcecodeenv and \newinputsourcefilecmd
                  - added \inputexample, \inputsidebyside and \inputsourcecode
                  - renamed `example*' into `sidebyside'
2013/09/15 v0.4   - new listings style `cnltx-bibtex'
2013/09/20 v0.5   - new command \implementation
                  - fixed wrong indexing behaviour: keywords in the silent
                    lists are now correctly indexed if added with `add-cmds'
                    or `add-envs'
2013/09/30 v0.7   - added listings style `cnltx-makeindex'
2013/10/04 v0.7a  - new command \cnltx@treat@lst@index
                  - changed \envidx in listings into \indexenv
                  - added \bnd for package bundles
2013/11/22 v0.9   - new option `compile' that allows to compile source code
                    examples (which need to be complete, of course) with
                    pdflatex and include the documents afterwards
                  - new options `max-pages' that determines the maximum number
                    of pages before a line break if documents are included
                    with `compile'
                  - new option `graphics'
                  - new option `runs' that specifies the number of compilation
                    runs of the included example
                  - new options `program' and `exe-with'
                  - new option `float', `float-pos' and `caption'
2014/01/05 v0.10  - sometimes there is a spurious `undefined control sequence
                    \lst@gtexcs3' error: added hack to fix this => find out
                    where this comes from!
                  - new option `add-frame' for `compile'd examples
                  - new command \parg for an optional + argument
                  - new option `outside' for non-`compiled' examples
                  - new option `float-env'
2014/03/11 v0.11  - \cnltx@load@modules
2014/04/09 v0.12  - improvements on the sidebyside examples
2015/08/29 v0.13a - enable \choices list to stretch
2016/03/16 v0.13b - `program' may now be a csv list of programs to be
                    executed
2017/02/04 v0.14  - exchange literate={`}{\`{}}{1}{'}{\textquotesingle}{1} for
                    listings' upquote option
                  - new sourcecode environment `bash'
2019/11/01 v0.15  - fix `undefined control sequence \lst@gtexcs3' error
                  - fix `undefined control sequence \lst@gkeyword3' error
                  - fix `undefined control sequence \lst@gkeyword3' error
TODO: