% \iffalse meta-comment
% !TeX spellcheck = en-US
%   
% File:      latexdemo.sty
% Version:   2023/03/26 v0.2
% Author:    Matthias Pospiech
% Email:     <matthias@pospiech.eu>
%
% Copyright (C) 2023 by Matthias Pospiech (matthias@pospiech.eu)
% ---------------------------------------------------------------------------
% 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 Matthias Pospiech.
%
% This work consists of the files latexdemo.dtx and latexdemo.ins
% and the derived filebase latexdemo.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{latexdemo.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{latexdemo}
%<*package>
   [2023/03/26 v0.2 typeset code and resulting output]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{hypdoc}
\RequirePackage{latexdemo}
\usepackage{lmodern}
%%%% Additional packages
\usepackage{soulutf8}
%
%%% Configures doc.sty and its (outdated) index generation, which does
%   not work together with any modern package and has no hyperref support
%   and thus no links. Furthermore it is conflicts with the index macros
%   of doctools.
%
\EnableCrossrefs  % (default) Every new macro name used within a macrocode or
                  % macrocode∗ environment will produce an index entry.
% \DisableCrossrefs % turn off this feature
%
% If an index is created is determined by the use of the following
% declarations in the driver file preamble; if neither is used, no index is 
% produced.
\PageIndex     % all index entries refer to their page number
% \CodelineIndex % index entries produced by \DescribeMacro and \DescribeEnv
               %  refer to page number but those produced by the macro
               %  environment refer to the code lines, 
               % which will be numbered automatically.
% \CodelineNumbered % no index is created, but the code lines are numbered

\RecordChanges

\listfiles

\begin{document}
  \DocInput{latexdemo.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v0.1}{2012/12/01}{initial version (converted to dtx file)}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
% \providecommand*{\url}{\texttt}
% \GetFileInfo{latexdemo.dtx}
% \title{The \textsf{latexdemo} package}
% \author{Matthias Pospiech \\ \url{matthias@pospiech.eu}}
% \date{\fileversion~from \filedate}
%
% \maketitle
% \section{Introduction}
% In order to demonstrate \latex{} code it is very useful to have the code and
% the resulting output together in the same document.
% \package{latexdemo} 
% is a package that provides configurable tools to print out \latex{} code and the
% resulting output in the same document.
%
% The difference to other similar packages is the support of
% verbatim material inside a conditional sequence and the consequence that each 
% code must be written to an external file.
%
% The commands provided by this package are based on the packages 
% \package{listings}, \package{mdframed} and the enviroment \environment{filecontents}. 
%
% \section{Basic example}
% \label{sec:example:basic}
% Below is a principle example,
% which demonstrates the usage of the package by showing some commands of a
% package (\package{soul}) with the resulting code side by side:
%
% \iffalse
%<*example>
% \fi
\begin{DefineCode}
\so{letterspacing}, \\
\ul{underlining},   \\
\st{overstriking}   \\
and \hl{highlighting}. 
\end{DefineCode}
% \iffalse
%</example>
% \fi
%
% \PrintDemo{style=parallel}
%
% which is created with the code of this package using \cs{ifcsdef} from etoolbox
% to test if the code will run through or fail because of unkown commands.
%
% \iffalse
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
\begin{DefineCode}
\so{letterspacing}, \\
\ul{underlining},   \\
\st{overstriking}   \\
and \hl{highlighting}. 
\end{DefineCode}

\ifcsdef{so}{%
%
\PrintDemo{style=parallel}
%
}{% 
  \DemoError{Command \cs{so} of package% 
  \package{soul} not available.
  Probably the package was not loaded.
  }
}%
\end{lstlisting}
% \iffalse
%</example>
% \fi
%
% \section{Usage}
%
% \subsection{Define code}
% This package requires the example code to be written to an external file. The
% filename is saved in the command sequence \cs{democodefile}. The output is done
% with the \environment{DefineCode} environment:
%
% \iffalse
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
\begin{DefineCode}
... code ...
\end{DefineCode}
\end{lstlisting}
% \iffalse
%</example>
% \fi
%
% The requirement for an external file originates from the problem that verbatim
% content cannot be saved in normal tex macros since the line breaks and white
% spaces get lost. Furthermore, any solution which would solve this problem would
% fails finally because saving such contend cannot be included in conditional
% code statements\footnote{See discussion on:
%  \url{http://tex.stackexchange.com/questions/29256/}}.
%
% The content in the file defined by \cs{democodefile} is further read for the
% printing of the code and the corresponding output.
%
% \subsection{Print code and result}
%
% \DescribeMacro{\PrintDemo}\arg{style=\meta{option}} \AfterLastParam%
% This is the macro for the output of code and result. 
% The layout of both is defined with the style option. 
% The following options are possible
% \begin{Optionlist}
%  \option{parallel} &  code and result side by side.  \\
%  \option{stacked}  &  (default) code and result with 100\,\% text width
%                       stacked.\\
%  \option{lines}    &  like \texttt{stacked}, but with lines on 
%                       top and bottom of the result instead of a 
%                       surrounding box. \\
%  \option{none}     &  like \texttt{stacked}, but with nothing around the
%                       result. \\
%  \option{page}     &  result on a single page.\\
% \end{Optionlist}
%
% You should use \option{parallel} for small examples and \option{stacked}
% otherwise. The options \option{lines} and \option{none} is primarily 
% for those cases where a surrounding box is disturbing or impossible. 
% The latter occurs for example in cases where content is written across 
% the text width boundaries. The option \option{page} is obviously for 
% those cases where the output is very large or written to another page anyway.
%
% \subsubsection{Examples}
% The following code is used in the examples
% \iffalse
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
\begin{DefineCode}
This code shows some basic math: $a^2 + b^2 = c^2$.
\end{DefineCode}
\end{lstlisting}
%
\begin{DefineCode}
This code shows some basic math: $a^2 + b^2 = c^2$.
\end{DefineCode}
% \iffalse
%</example>
% \fi
%
% \begin{itemize}
% \item \cs{PrintDemo}\{style=parallel\}
% \PrintDemo{style=parallel}
%
% \item \cs{PrintDemo}\{style=stacked\}
% \PrintDemo{style=stacked}
%
% \item \cs{PrintDemo}\{style=lines\}
% \PrintDemo{style=lines}
%
% \item \cs{PrintDemo}\{style=none\}
% \PrintDemo{style=none}
% \end{itemize}
%
% The prefix text for code and result and the filename can be changed. The
% commands are introduced in section~\ref{sec:setup}. Commands for the output of
% content such as the name of of a package, a command, an environment or a
% generalized error message are introduced in section~\ref{sec:commands:output}.
%
% \subsection{Setup}
% \label{sec:setup}
%
% The following commands define the name for the temporary file or the strings
% used for the printing of code or results. Use \cs{renewcommand} to change the
% definitions.
%
% \DescribeMacro{\democodefile}%
% Filename for the temporary file required for code and results printing. 
% \Default{democode}
%
% \DescribeMacro{\democodeprefix}%
% Prefix text for output of code.
% \Default{Code: }
%
% \DescribeMacro{\demoresultprefix}%
% Prefix text for output of the result. 
% \Default{Result: }
%
% \subsection{Output commands}
% \label{sec:commands:output}
%
% The following commands are provided for the user to print out and format
% commands, environments, packages and errors. Some are provided by the
%  \package{doctools} package.
%
% \DescribeMacro{\command} \marg{cmd} \AfterLastParam
% Prints out the argument \cs{command}\arg{foo} as \cs{foo}.
%
% \DescribeMacro{\cs} \marg{cmd} \AfterLastParam
% Shortcut for \cs{command}. 
%
% \DescribeMacro{\arg} \marg{cmd} \AfterLastParam
% Prints out an argument in curled brackets without the use of 
% angle brackets as in \cs{marg} or \cs{oarg}. 
% Thus prints \cs{arg}\arg{foo} as \arg{foo}.
%
% \DescribeMacro{\environment}  \marg{environment} \AfterLastParam
% Prints out an environment name as \environment{environment}.
%
% \DescribeMacro{\env} \marg{environment} \AfterLastParam
% Shortcut for \cs{environment}
%
% \DescribeMacro{\package} \marg{package} \AfterLastParam
% Prints out a package name as \package{package}.
%
% \DescribeMacro{\DemoError}%
% prints out the given error message
% \Example{\DemoError{foo}}
%
%
% \StopEventually{}
%
% \clearpage
% \section{Implementation}
%
% \iffalse
%<*latexdemo.sty>
% \fi
%
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{latexdemo}[2012/12/01 v0.1 typeset code and resulting output]
\@ifpackageloaded{hypdoc}
  {\RequirePackage[loadHyperref=true,%
                   createIndexEntries=false,%
                   applyLayout=false]{doctools}}
  {\@ifpackageloaded{doc}
    {\RequirePackage[loadHyperref=false,%
                    createIndexEntries=false,%
                    applyLayout=false]{doctools}}
    {}}
%%% listings (must be loaded before \AtBeginDocument)
\RequirePackage{listings}
\PassOptionsToPackage{table}{xcolor}
% This code needs to be executed at the beginning
% of the document because some packages (eg. xcolor)
% could lead to option clashes otherwise
%
%% Programming
\RequirePackage{xspace}
\RequirePackage{etoolbox}
%% Packages for frames
\RequirePackage{mdframed}
\RequirePackage{framed}
%
\AtBeginDocument{%
%    \end{macrocode}
% \subsection{Preamble}
% \subsubsection{Packages}
% 
%    \begin{macrocode}
%% Package for colors
\RequirePackage{xcolor}
%
%% load doctools without hyperref if not loaded and no documentation
%% package was loaded.
\@ifpackageloaded{doctools}{}
  {\RequirePackage[loadHyperref=false,%
                   createIndexEntries=true,%
                   applyLayout=false]{doctools}}
%    \end{macrocode}
%
% \subsubsection{Colors}
%
%    \begin{macrocode}
%% Colors
\colorlet{demo@stringcolor}{green!40!black!100}
\colorlet{demo@commentcolor}{green!50!black!100}
\colorlet{demo@numbercolor}{white!50!black!100}
\colorlet{demo@codebackcolor}{white!95!black!100}
\colorlet{demo@resultbackcolor}{white}
\definecolor{demo@keywordcolor}{rgb}{0,0.47,0.80}
\definecolor{demo@rulecolor}{rgb}{0,0.4,0.5}
\definecolor{demo@code@rulecolor}{rgb}{0.5,0.5,0.5}
%    \end{macrocode}
%
% \subsection{Commands}
%
%    \begin{macrocode}
%% === Simple Commands ===============================
%    \end{macrocode}
%
% \begin{macro}{\democodefile}
% Saves the filename for temporary file output.
%    \begin{macrocode}
\newcommand{\democodefile}{democode}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\democodeprefix}
% Prefix text for code output.
%    \begin{macrocode}
\newcommand{\democodeprefix}{Code: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\demoresultprefix}
% Prefix text for result output.
%    \begin{macrocode}
\newcommand{\demoresultprefix}{\noindent Result:}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\DemoError}
% Output and formatting of error messages.
%    \begin{macrocode}
%% Print Error
\newcommand{\DemoError}[1]{
  \ifcsdef{textcolor}
    {\textcolor{red}{Error:~}}
    {Error:~}
  #1 \par\noindent
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Define keys}
%
%    \begin{macrocode}
%% === Define Keys ===================================
\RequirePackage{kvoptions-patch}
\RequirePackage{kvoptions}  % options
\RequirePackage{pdftexcmds} % string comparison
\SetupKeyvalOptions{family=demo,prefix=demo@}
%    \end{macrocode}
% Define default option for style key: \emph{stacked}
%    \begin{macrocode}
\DeclareStringOption[stacked]{style}
\ProcessKeyvalOptions{demo}
%    \end{macrocode}
%
% \begin{macro}{\PrintDemoUsingKeys}
% Evaluate key and execute corresponding commands
%    \begin{macrocode}
\newcommand{\PrintDemoUsingKeys}{%
  \ifnum\pdf@strcmp{\demo@style}{parallel}=0%
    \PrintCodeAndResultsParallel%
  \else\ifnum\pdf@strcmp{\demo@style}{stacked}=0%
    \PrintCodeAndResultsStacked%
  \else\ifnum\pdf@strcmp{\demo@style}{lines}=0%
    \PrintCodeAndResultsStackedLines%
  \else\ifnum\pdf@strcmp{\demo@style}{page}=0%
    \PrintCodeAndResultsPage%
  \else\ifnum\pdf@strcmp{\demo@style}{none}=0%
    \PrintCodeAndResultsNone%
  \else%
     \PackageError{latexdemo}{%
       \MessageBreak%
       value >\tplbugs@style< unkown \MessageBreak%
     }{}%
  \fi\fi\fi\fi\fi%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{DefineCode}
% Define code for demonstration using the enviroment \environment{DefineCode} which is based on the enviroment \environment{filecontents*}.
%    \begin{macrocode}
	\newenvironment{DefineCode}{%
	\csname filecontents*\endcsname[overwrite]{\democodefile}%
}{%
	\csname endfilecontents*\endcsname%
}
%    \end{macrocode}
% \end{environment}
%
% \begin{macro}{\PrintDemo}
% Print code and result using the key-value syntax
%    \begin{macrocode}
\newcommand{\PrintDemo}[1]{%
\begingroup
  \setkeys{demo}{#1}%
  \PrintDemoUsingKeys
\endgroup
}    
%    \end{macrocode}
% \end{macro}
%
% \subsection{listings package style}
%    \begin{macrocode}
%% === Listings style ================================
%% reuses style from doctools
\lstdefinestyle{demostyle}{
  ,style=lstDemoStyleLaTeXCode%
  ,numbers=none%
}
\lstloadlanguages{[LaTeX]TeX}
%    \end{macrocode}
%
% \subsection{mdframed package style}
%
%    \begin{macrocode}
%% === Mdframed style ================================
\mdfdefinestyle{DemoStyleFrames}{
  linecolor=demo@rulecolor,%
  linewidth=0.8pt,
  skipabove=0.5\baselineskip,
  skipbelow=0.5\baselineskip,
  leftmargin =-3.5pt,
  rightmargin=-3.5pt,
  innerleftmargin=3pt,
  innerrightmargin=3pt,
  needspace=3\baselineskip,
}% 
%    \end{macrocode}
%
% \subsection{Commands for the formatting}
%
% \begin{macro}{\preResultSkip}
% Default skip at the beginning of a result
%    \begin{macrocode}
%% === Formating commands ============================
\newcommand{\preResultSkip}{}%\vspace*{-0.5\baselineskip}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{environment}{latexresult}
% Environment to print the result in a box
%    \begin{macrocode}
\newenvironment{latexresult}{%
\demoresultprefix
\nopagebreak[4]
\preResultSkip
\mdframed[%
  style=DemoStyleFrames,
  backgroundcolor=demo@resultbackcolor,%
  usetwoside=false,
]%
}{
\endmdframed
\noindent
}
%    \end{macrocode}
% \end{environment}
%
%
% \begin{macro}{\resultline}
%% Single Line for results
%    \begin{macrocode}
\newcommand{\resultline}{%
\nopagebreak[4]
%% Insert single line
\mdframed[%
  style=DemoStyleFrames,
  skipabove=3pt,
  skipbelow=3pt,
  topline=true,bottomline=false,leftline=false,rightline=false,
  backgroundcolor=white,%
]\mbox{}\endmdframed
\nopagebreak[4]
}
%    \end{macrocode}
% \end{macro}
%
% % \subsection{Low level commands for printing of code and result}
%
% \begin{macro}{\printlatexcode}
% Prints the code using \cs{lstinputlisting}
%    \begin{macrocode}
%% === Output commands ===============================
%% Print Code with prefix
\newcommand{\printlatexcode}[1][\democodefile]{%
\def\demoInputFile{#1}%
\IfFileExists{\demoInputFile.tex}{%
\democodeprefix%
\lstinputlisting[style=demostyle,nolol=true]{\demoInputFile}}{}%
}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\printlatexresult}
% Prints the result enclosed in the \environment{latexresult} environment.
% The evaluation of the code is simply achieved by loading the file with 
% \cs{input}.
%    \begin{macrocode}
%% Print Result with standard box
\newcommand{\printlatexresult}[1][\democodefile]{%
\def\demoInputFile{#1}%
\begin{latexresult}%
\IfFileExists{\demoInputFile.tex}{\input{\demoInputFile.tex}}{}%
\end{latexresult}%
}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\printlatexresultlines}
% Like \cs{printlatexresult} but with lines above and below instead of a
% surrounding box.
%    \begin{macrocode}
%% Print result with lines 
\newcommand{\printlatexresultlines}{%
\demoresultprefix
\nopagebreak[4] \resultline \nopagebreak[4]
\IfFileExists{\democodefile}{\input{\democodefile}}{}%
\nopagebreak[4] \resultline \nopagebreak[4]
}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Output of code and result}
%
% \begin{macro}{\PrintCodeAndResultsParallel}
%    \begin{macrocode}
%% === Output commands for code and result ===========
\newcommand{\PrintCodeAndResultsParallel}{%
\nopagebreak[4]
\vspace*{0.5em}\par\noindent
\begin{minipage}[t]{0.48\linewidth}
\printlatexcode
\end{minipage} \hfill
\begin{minipage}[t]{0.48\linewidth}
\printlatexresult
\end{minipage}
\par\noindent
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\PrintCodeAndResultsStacked}
%    \begin{macrocode}
\newcommand{\PrintCodeAndResultsStacked}{%
\nopagebreak[4]
\vspace*{0.5em}\par\noindent
\printlatexcode%
\printlatexresult%
\par\noindent
}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\PrintCodeAndResultsStackedLines}
%    \begin{macrocode}
\newcommand{\PrintCodeAndResultsStackedLines}{%
\nopagebreak[4]
\vspace*{0.5em}\par\noindent
\printlatexcode%
\printlatexresultlines%
\vspace*{0.5em}\par\noindent
}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\PrintCodeAndResultsNone}
%    \begin{macrocode}
\newcommand{\PrintCodeAndResultsNone}{%
\nopagebreak[4]
\vspace*{0.5em}\par\noindent
\printlatexcode%
%    \end{macrocode}
%
%    \begin{macrocode}
\demoresultprefix
\nopagebreak[4]
\par\noindent
\IfFileExists{\democodefile}{\input{\democodefile}}{}%
%    \end{macrocode}
%
%    \begin{macrocode}
\vspace*{0.5em}\par\noindent
}%
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\PrintCodeAndResultsPage}
%    \begin{macrocode}
\newcommand{\PrintCodeAndResultsPage}{%
\nopagebreak[4]
\vspace*{0.5em}\par\noindent
\printlatexcode%
\demoresultprefix: Shown on the following page.
\newpage
\IfFileExists{\democodefile}{\input{\democodefile}}{}%
\newpage
}%
%    \end{macrocode}
%
%    \begin{macrocode}
} % end of \AtBeginDocument
%    \end{macrocode}
% \end{macro}
%
%
% \iffalse
%</latexdemo.sty>
% \fi
%
% \Finale
\endinput

