% \iffalse meta-comment % !TeX spellcheck = en-US % % File: latexdemo.sty % Version: 2023/03/26 v0.2 % Author: Matthias Pospiech % Email: % % 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} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{latexdemo} %<*package> [2023/03/26 v0.2 typeset code and resulting output] % % %<*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} % % \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 % % \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 % % \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 % % \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 % % \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 % % \fi % % \Finale \endinput