summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/easyfloats/doc/preamble
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/easyfloats/doc/preamble')
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/bibliography.tex35
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/description-links.tex224
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/examplecode.tex778
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/keydoc.tex754
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/link.tex53
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/macros.tex218
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/markdown.tex153
-rw-r--r--macros/latex/contrib/easyfloats/doc/preamble/pdfstring.tex35
8 files changed, 2250 insertions, 0 deletions
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/bibliography.tex b/macros/latex/contrib/easyfloats/doc/preamble/bibliography.tex
new file mode 100644
index 0000000000..ad24a2b445
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/bibliography.tex
@@ -0,0 +1,35 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+\usepackage[%
+ sorting=none, % none=citation order
+]{biblatex}
+
+\setcounter{biburllcpenalty}{8000}
+\setcounter{biburlucpenalty}{8000}
+\setcounter{biburlnumpenalty}{8000}
+
+\addbibresource{\jobname.bib}
+
+\SetCiteCommand\autocite
+
+\newcommand{\mycite}[2][]{%
+ \citetitle{#2}~\autocite[#1]{#2}%
+}
+
+%https://tex.stackexchange.com/a/108349
+\DeclareCiteCommand{\citetitle}
+ {\boolfalse{citetracker}%
+ \boolfalse{pagetracker}%
+ \usebibmacro{prenote}}
+ {\ifciteindex
+ {\indexfield{indextitle}}
+ {}%
+ \printtext[bibhyperref]{\printfield[citetitle]{labeltitle}}}
+ {\multicitedelim}
+ {\usebibmacro{postnote}}
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/description-links.tex b/macros/latex/contrib/easyfloats/doc/preamble/description-links.tex
new file mode 100644
index 0000000000..6eac79bc1c
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/description-links.tex
@@ -0,0 +1,224 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Links all \cmd, \env and \handler to the corresponding \Describe*.
+% Links all \pkg to a reference defined with \newurllink (see link.tex)
+% Defines \pkgoptndoc to document package otions and links all \pkgoptn to it.
+%
+% \pkgoptndoc{<packageoption>}
+% \pkgoptndoc*{<packageoption>}
+% The starred version is for default package options.
+% The non-starred version is for options disabled by default.
+% Empty lines before a \pkgoptndoc are relevant:
+% Without an empty line they are considered to belong together.
+% With an empty line they do not and \pkgoptndoc@afterpar is inserted as separator.
+% A list of \pkgoptndoc must be closed with \endpkgoptndoc.
+%
+% Defines
+% \NoDescribeMacro{<cs>}
+% \NoDescribeEnv{<environment>}
+% to declare undescribed control sequences or environments
+% which shall not produce a warning when being referenced.
+%
+% Warning: \cmd and \DescribeMacro are not intended for use with control characters.
+%
+% depends on
+% \NewKeyword[\unexpanded]{<keywordtype>}{<keyword>}{<formatmacro-bg>}{<formatmacro-fg>}{<text>}
+% \NoKeyword{<keywordtype>}{<keyword>}{<formatmacro-bg>}{<formatmacro-fg>}
+% \LinkKeyword{<keywordtype>}{<keyword>}<formatmacro-bg><formatmacro-fg>{<text>}
+% from preamble/keydoc.tex
+
+\makeatletter
+
+% --------- \cmd & \(No)DescribeMacro ----------
+
+\newcommand{\DlCmdLabelName}[1]{\detokenize{#1}}
+\newcommand{\Cmd}[1]{\expandafter{\detokenize{#1}\unskip}}
+\newcommand{\CmdBg}{\formatcode}
+\let\DlOriginalDescribeMacro=\DescribeMacro
+\renewcommand{\DescribeMacro}[1]{%
+ \begingroup
+ \def\cmd##1{\formatcodeinmarginpar{\Cmd{##1}}}%
+ \DlOriginalDescribeMacro{#1}%
+ \endgroup
+ \NewKeyword[\unexpanded]{cs}{\DlCmdLabelName{#1}}{\CmdBg}{\Cmd}{}%
+ \AbbrevKeyword[\unexpanded]{}{\DlCmdLabelName{#1}} {cs}{\DlCmdLabelName{#1}}%
+ \ignorespaces
+}
+\newcommand{\NoDescribeMacro}[1]{%
+ \NoKeyword[\unexpanded]{cs}{\DlCmdLabelName{#1}}{\CmdBg}{\Cmd}%
+ \AbbrevKeyword[\unexpanded]{}{\DlCmdLabelName{#1}} {cs}{\DlCmdLabelName{#1}}%
+ \ignorespaces
+}
+\renewrobustcmd{\cmd}[1]{%
+ \LinkKeyword{cs}{\detokenize{#1}}\CmdBg\Cmd{#1}%
+}
+
+
+% --------- \env & \(No)DescribeEnv ----------
+
+\let\DlOriginalDescribeEnv=\DescribeEnv
+\renewcommand{\DescribeEnv}[1]{%
+ \DlOriginalDescribeEnv{#1}%
+ \NewKeyword{env}{#1}{\DlEnvBg}{\DlOriginalEnv}{}%
+ \AbbrevKeyword{}{#1} {env}{#1}%
+ \ignorespaces
+}
+\newcommand{\NoDescribeEnv}[1]{%
+ \NoKeyword{env}{#1}{\DlEnvBg}{\DlOriginalEnv}%
+ \AbbrevKeyword{}{#1} {env}{#1}%
+ \ignorespaces
+}
+\let\DlOriginalEnv=\env
+\renewcommand{\env}[1]{\LinkKeyword{env}{#1}\DlEnvBg\DlOriginalEnv{#1}}
+\newcommand{\DlEnvBg}{\formatcode}
+
+
+% --------- \handler & \DescribeHandler ----------
+
+\let\DlOriginalDescribeHandler=\DescribeHandler
+\renewcommand{\DescribeHandler}[1]{%
+ \DlOriginalDescribeHandler{#1}%
+ \NewKeyword{handler}{#1}{\DlHandlerBg}{\DlOriginalHandler}{}%
+ \AbbrevKeyword{}{#1} {handler}{#1}%
+ \ignorespaces
+}
+\let\DlOriginalHandler=\handler
+\renewcommand{\handler}[1]{\LinkKeyword{handler}{#1}\DlHandlerBg\DlOriginalHandler{#1}}
+\newcommand{\DlHandlerBg}{\formatcode}
+
+\newcommand{\NoDescribeHandler}[1]{%
+ \NoKeyword{handler}{#1}{\DlHandlerBg}{\DlOriginalHandler}%
+ \AbbrevKeyword{}{#1} {handler}{#1}%
+ \ignorespaces
+}
+
+
+% --------- \NoDescribeKey, \NoDescribeVal ----------
+
+\newcommand{\NoDescribeKey}[1]{%
+ \NoKeyword{key}{#1}{\keydoc@key@bg}{\keydoc@original@key}%
+ \AbbrevKeyword{}{#1} {key}{#1}%
+ \ignorespaces
+}
+\newcommand{\NoDescribeVal}[1]{%
+ \NoKeyword{}{#1}{\formatcode}{\val}%
+ \ignorespaces
+}
+
+
+% --------- \DescribeMeta ----------
+
+\newcommand{\DescribeMeta}[1]{%
+ \NewKeyword{meta}{#1}{\formatcode}{\val}{}%
+ \ignorespaces
+}
+
+\let\meta@nolink=\meta
+\renewcommand{\meta}[1]{%
+ \IfKeywordUndefined{meta}{#1}%
+ {\@firstofone}%
+ {\LinkUnformattedKeyword{meta}{#1}}%
+ {\meta@nolink{#1}}%
+}
+
+
+% --------- \pkgoptn & \pkgoptndoc ----------
+
+\let\DlOriginalPkgoptn=\pkgoptn
+\renewcommand{\pkgoptn}[1]{\LinkKeyword{pkgoptn}{#1}\DlPkgoptnBg\DlOriginalPkgoptn{#1}}
+\newcommand{\DlPkgoptnBg}{\formatcode}
+
+\newcommand{\begin@pkgoptndoc}{\begin{itemize}}
+\def \endpkgoptndoc {\end{itemize}}
+\newcommand{\pkgoptndoc@beforepkg@normal}{\item[\radiooff]}
+\newcommand{\pkgoptndoc@beforepkg@default}{\item[\radioon]}
+% inserted before \pkgoptndoc if it was preceded by an empty line
+\newcommand{\pkgoptndoc@afterpar}{\bigpar}
+
+\newif\if@inpkgoptndoc
+
+\newcommand{\pkgoptndoc}{%
+ \unless\if@inpkgoptndoc
+ \begin@pkgoptndoc
+ \@inpkgoptndoctrue
+ \else
+ \ifvmode
+ \pkgoptndoc@afterpar
+ \fi
+ \fi
+ \@ifstar
+ {\pkgoptndoc@beforepkg@default\@pkgoptndoc@do}%
+ {\pkgoptndoc@beforepkg@normal\@pkgoptndoc@do}%
+}
+\newcommand{\@pkgoptndoc@do}[1]{%
+ \NewKeyword{pkgoptn}{#1}{\DlPkgoptnBg}{\DlOriginalPkgoptn}{#1}%
+ \AbbrevKeyword{}{#1} {pkgoptn}{#1}%
+}
+
+\newcommand{\NoDescribePkgoptn}[1]{%
+ \NoKeyword{pkgoptn}{#1}{\DlPkgoptnBg}{\DlOriginalPkgoptn}%
+ \AbbrevKeyword{}{#1} {pkgoptn}{#1}%
+ \ignorespaces
+}
+
+
+% --------- \pkg & \pkgdoc, \NoDescribePkg ----------
+
+\let\DlOriginalPkg=\pkg
+\newcommand{\DlPkgBg}[1]{#1}
+\renewcommand{\pkg}[1]{\LinkKeyword{pkg}{#1}\DlPkgBg\DlOriginalPkg{#1}}
+\newcommand{\pkgdoc}[1]{%
+ \unless\if@inpkgdoc
+ \begin@pkgdoc
+ \@inpkgdoctrue
+ \fi
+ \pkgdoc@beforepkg
+ \NewKeyword{pkg}{#1}{\DlPkgBg}{\DlOriginalPkg}{\link[#1]{#1}}%
+ %\AbbrevKeyword{}{#1} {pkg}{#1}%
+ \let\pkgdoc@beforepkg=\pkgdoc@beforepkg@bak
+ \pkgdoc@lookahead
+}
+\newcommand{\pkgdoc@lookahead}{%
+ \futurelet \pkgdoc@nexttoken \pkgdoc@lookahead@check
+}
+\newcommand{\pkgdoc@lookahead@check}{%
+ \ifcat \noexpand\pkgdoc@nexttoken \space
+ \let\pkgdoc@lookahead@do=\pkgdoc@lookahead
+ \let\pkgdoc@lookahead@gobble=\@firstofone
+ \else\ifx \pkgdoc@nexttoken /%
+ \pkgdoc@pkgsep
+ \let\pkgdoc@beforepkg=\relax
+ \let\pkgdoc@lookahead@do=\pkgdoc@lookahead
+ \let\pkgdoc@lookahead@gobble=\@gobble
+ \else\ifx \pkgdoc@nexttoken \pkgdoc
+ \let\pkgdoc@lookahead@do=\relax
+ \let\pkgdoc@lookahead@gobble=\@empty
+ \else
+ \pkgdoc@descriptionsep
+ \let\pkgdoc@lookahead@do=\relax
+ \let\pkgdoc@lookahead@gobble=\@empty
+ \fi \fi \fi
+ \expandafter \pkgdoc@lookahead@do \pkgdoc@lookahead@gobble
+}
+
+\newcommand{\begin@pkgdoc}{\begin{itemize}}
+\def \endpkgdoc {\end{itemize}}
+\newif\if@inpkgdoc
+\newcommand{\pkgdoc@beforepkg}{\item}
+\newcommand{\pkgdoc@pkgsep}{/}
+\newcommand{\pkgdoc@descriptionsep}{ }
+\let\pkgdoc@beforepkg@bak=\pkgdoc@beforepkg
+
+\newcommand{\NoDescribePkg}[1]{%
+ \NoKeyword{pkg}{#1}{\DlPkgBg}{\DlOriginalPkg}%
+ %\AbbrevKeyword{}{#1} {pkg}{#1}%
+ \ignorespaces
+}
+
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/examplecode.tex b/macros/latex/contrib/easyfloats/doc/preamble/examplecode.tex
new file mode 100644
index 0000000000..79d3c7f424
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/examplecode.tex
@@ -0,0 +1,778 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Defines an environment to typeset LaTeX code:
+% \begin{examplecode}
+% \let\do=\@makeother
+% \dospecials
+% \end{examplecode}
+% @ is treated as letter.
+%
+% A starred version takes one argument, TeX code to be executed inside of the group.
+% It can be used to change catcodes or to define escape characters.
+% \begin{examplecode*}{\ExamplecodeEscapeinside $ $}
+% a long$\\$long line
+% \end{examplecode*}
+%
+% \ExamplecodeEscapeinside takes two arguments
+% characters between which the code is executed normally.
+%
+% \ExamplecodeNoBox
+% disables the tcolorbox
+%
+% \ExamplecodeLinenumbers
+% enables line numbers
+%
+% \\ is redefined to cause a linebreak marked with \ExamplecodePostBreakText.
+
+
+
+\makeatletter
+% ---------- settings ---------
+
+\usepackage{xcolor}
+\usepackage{tcolorbox}
+\tcbuselibrary{breakable,skins}
+\usepackage{latexsym}
+\usepackage{textcomp}
+
+
+% taken from /usr/lib/python3/dist-packages/pygments/styles/default.py
+\definecolor{math}{RGB}{"BA,"21,"21}
+\definecolor{aligntab}{RGB}{"00,"80,"00}
+\definecolor{parameter}{RGB}{"19,"17,"7C}
+\colorlet{superscript}{black}
+\colorlet{subscript}{superscript}
+\colorlet{brace}{aligntab}
+\colorlet{controlsequence}{aligntab}
+\definecolor{comment}{RGB}{"40,"80,"80}
+\definecolor{codebackground}{rgb}{0.9,0.9,1}
+\colorlet{codeborder}{codebackground!50!black}
+\colorlet{codelinkcolor}{white}
+
+\newtcolorbox{examplecodebox}{breakable, skin=enhanced,
+ colback = codebackground,
+ colframe = codeborder,
+ size = fbox, % normal|title|small|fbox|tight|minimal
+ %left = 0pt, right = 0pt,
+ %top = 0pt, bottom = 0pt,
+ %boxrule = 1pt,
+ %arc = 3pt,
+}
+\newcommand{\ExamplecodeNoBox}{%
+ \let\examplecodebox=\par
+ \let\endexamplecodebox=\par
+}
+
+\newcommand{\NewExamplecodeFormatMandatoryArgument}[2]{% #1: control sequence, #2: replacement text where ##1 is the unprocessed argument
+ \expandafter\newcommand\csname @examplecode@formatarg\detokenize{#1}\endcsname[1]{\ExamplecodeProcessBeginGroup{\{}#2\ExamplecodeProcessEndGroup{\}}\ExamplecodeAllowLinebreakBeforeNext\@examplecode@loop}%
+}
+\newcommand{\NewExamplecodeFormatOptionalArgument}[4]{% #1: control sequence, #2: bracket open, #3: bracket close, #4: replacement text where ##1 is the unprocessed argument
+ \expandafter\def\csname @examplecode@formatoptarg\detokenize{#1}#2\endcsname##1#3{\ExamplecodeProcessBracket{#2}#4\ExamplecodeProcessBracket{#3}\ExamplecodeAllowLinebreakBeforeNext\@examplecode@loop}%
+}
+\NewExamplecodeFormatMandatoryArgument\begin{\ExamplecodeProcessEnv{#1}\ExamplecodeSetCmd{#1}}
+\NewExamplecodeFormatMandatoryArgument\end{\ExamplecodeProcessEnv{#1}\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument\usepackage{\ExamplecodeProcessPkg{#1}\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument{object}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument{tableobject}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument{figureobject}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument{subobject}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument\objectset{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatOptionalArgument\includegraphicobject[]{\ExamplecodeParseKeys{}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatOptionalArgument\includegraphicsubobject[]{\ExamplecodeParseKeys{}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument\NewObjectStyle{\ExamplecodeParse\relax\relax\ExamplecodeEndParseKeys#1\ExamplecodeEndParseKeys\ExamplecodeSetCmd{\NewObjectStyle2}}
+\NewExamplecodeFormatMandatoryArgument{\NewObjectStyle2}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+
+% custom styles defined in example
+\NewExamplecodeFormatMandatoryArgument{tikzobject}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+\NewExamplecodeFormatMandatoryArgument{tikz3dobject}{\ExamplecodeParseKeys{/object}#1\ExamplecodeEndParseKeys\ExamplecodeNoCmd}
+
+\newcommand{\ExamplecodeFormatMeta}[1]{{\normalfont\meta{#1}}}
+
+\newcommand{\ExamplecodePrint}[1]{#1}
+
+\newcommand{\ExamplecodePostBreakSymbol}{\footnotesize$\hookrightarrow$\quad}
+\newcommand{\ExamplecodeIndentation}{}% don't change this, it is overwritten later to always contain the indentation of the current line
+\newcommand{\ExamplecodePostBreakText}{\hbox{\ExamplecodeIndentation\ExamplecodePostBreakSymbol}}
+\newcommand{\ExamplecodeAllowLinebreak}{\discretionary{}{\ExamplecodePostBreakText}{}}
+\newcommand{\ExamplecodeAllowLinebreakBeforeNext}{\@examplecode@allowlinebreakbeforenexttrue}
+\newcommand{\ExamplecodeLinebreak}{\newline\ExamplecodePostBreakText}
+
+\newcommand{\ExamplecodeFormatCmd}[1]{{\leavevmode\color{controlsequence}\LinkUnformattedKeyword{cs}{\detokenize{#1}}{\string#1}}\ExamplecodeAllowLinebreakBeforeNext} % catcode 0/16
+\newcommand{\ExamplecodeFormatEnv}[1]{\LinkUnformattedKeyword{env}{#1}{#1}}
+\newcommand{\ExamplecodeFormatPkg}[1]{\LinkUnformattedKeyword{pkg}{#1}{#1}}
+
+\newcommand{\ExamplecodeFormatBeginGroup}[1]{\textcolor{brace}{#1}} % catcode 1
+\newcommand{\ExamplecodeFormatEndGroup}[1]{\textcolor{brace}{#1}\ExamplecodeAllowLinebreakBeforeNext} % catcode 2
+\newcommand{\ExamplecodeFormatMathShift}[1]{\textup{#1}} % catcode 3, see \ExamplecodeFormatMath
+\newcommand{\ExamplecodeFormatAlignmentTab}[1]{\textcolor{aligntab}{#1}} % catcode 4
+% catcode 5: \ExamplecodeEndOfLine
+\newcommand{\ExamplecodeFormatParameter}[1]{\textcolor{parameter}{#1}} % catcode 6
+\newcommand{\ExamplecodeFormatSuperscript}[1]{\textcolor{superscript}{#1}} % catcode 7
+\newcommand{\ExamplecodeFormatSubscript}[1]{\textcolor{subscript}{#1}} % catcode 8
+% catcode 9: ignored
+% catcode 10: \ExamplecodeSpace, \ExamplecodeTab
+\newcommand{\ExamplecodeFormatText}[1]{%
+ \ifx`#1%
+ \textasciigrave
+ \else\ifx'#1%
+ \textquotesingle
+ \else
+ #1%
+ \fi\fi
+} % catcode 11, 12
+\newcommand{\ExamplecodeFormatBracket}[1]{#1} % catcode 11
+% catcode 13: active (uses \ExamplecodeFormatCmd, too)
+
+% in contrast to the other format macros this does
+% *not* take an argument. Instead it applies the
+% format for the rest of the group.
+\newcommand{\ExamplecodeFormatComment}{%
+ \leavevmode
+ \color{comment}%
+ \itshape
+ \let\color=\@gobble
+} % catcode 14
+\newcommand{\ExamplecodeFormatMath}{%
+ \leavevmode
+ \color{math}%
+ \itshape
+ \let\color=\@gobble
+ \ExamplecodeForbidLinebreaks
+}
+\newcommand{\ExamplecodeForbidLinebreaks}{%
+ \let\discretionary=\@thirdofthree
+} % catcode 3
+
+% catcode 15: invalid
+
+\newcommand{\ExamplecodeSpaceSymbol}{\space}
+\newcommand{\ExamplecodeTabSymbol}{\qquad}
+\newcommand{\ExamplecodeIndentationSpace}{\EnsureHMode\nobreak\space}
+\newcommand{\ExamplecodeIndentationTab}{\EnsureHMode\nobreak\qquad}
+\newcommand{\ExamplecodeNormalSpace}{\discretionary{}{\ExamplecodePostBreakText}{\hbox{\ExamplecodeSpaceSymbol}}}
+\newcommand{\ExamplecodeNormalTab}{\discretionary{}{\ExamplecodePostBreakText}{\hbox{\ExamplecodeTabSymbol}}}
+\newcommand{\ExamplecodeEndOfLine}{\EnsureHMode\par}
+
+
+\newcommand{\ExamplecodeTabsize}{4}
+
+
+\newcommand{\ExamplecodeAllowLinebreakAfter}[1]{\expandafter\def\csname @examplecode@breakafter@#1\endcsname{\ExamplecodeAllowLinebreakBeforeNext}}
+\ExamplecodeAllowLinebreakAfter]
+
+
+% ---------- process ---------
+
+\newif\ifExamplecodeInAlign
+
+\newcommand{\ExamplecodeProcessCmd}[1]{\ExamplecodePrint{\ExamplecodeFormatCmd{#1}}} % catcode 0/16
+\newcommand{\ExamplecodeProcessEnv}[1]{\ExamplecodePrint{\ExamplecodeFormatEnv{#1}}}
+\newcommand{\ExamplecodeProcessPkg}[1]{\ExamplecodePrint{\ExamplecodeFormatPkg{#1}}}
+\newcommand{\ExamplecodeProcessBeginGroup}[1]{\ExamplecodePrint{\ExamplecodeFormatBeginGroup{#1}}} % catcode 1
+\newcommand{\ExamplecodeProcessEndGroup}[1]{\ExamplecodePrint{\ExamplecodeFormatEndGroup{#1}}} % catcode 2
+\newcommand{\ExamplecodeProcessMathShift}[1]{\ExamplecodePrint{\ExamplecodeFormatMathShift{#1}}} % catcode 3
+\newcommand{\ExamplecodeProcessBeginMath}{\ExamplecodePrint{\begingroup\ExamplecodeFormatMath}} % catcode 3
+\newcommand{\ExamplecodeProcessEndMath}{\ExamplecodePrint{\endgroup}}
+\newcommand{\ExamplecodeProcessAlignmentTab}[1]{\ExamplecodePrint{%
+ \ifExamplecodeInAlign
+ \endgroup
+ \fi
+ \ExamplecodeAllowLinebreak
+ \begingroup
+ \ExamplecodeInAligntrue
+ \ExamplecodeForbidLinebreaks
+ \ExamplecodeFormatAlignmentTab{#1}%
+}} % catcode 4
+\newcommand{\ExamplecodeProcessEndOfLine}{\ExamplecodePrint{%
+ \ifExamplecodeInAlign
+ \endgroup
+ \fi
+ \ExamplecodeEndOfLine
+}} % catcode 5
+\newcommand{\ExamplecodeProcessParameter}[1]{\ExamplecodePrint{\ExamplecodeFormatParameter{#1}}} % catcode 6
+\newcommand{\ExamplecodeProcessSuperscript}[1]{\ExamplecodePrint{\ExamplecodeFormatSuperscript{#1}}} % catcode 7
+\newcommand{\ExamplecodeProcessSubscript}[1]{\ExamplecodePrint{\ExamplecodeFormatSubscript{#1}}} % catcode 8
+% catcode 9: ignored
+\newcommand{\ExamplecodeProcessSpace}{\ExamplecodePrint{\ExamplecodeSpace}\ExamplecodeAppendIndentation{\ExamplecodeSpace}} % catcode 10
+\newcommand{\ExamplecodeProcessTab}{\ExamplecodePrint{\ExamplecodeTab}\ExamplecodeAppendIndentation{\ExamplecodeTab}} % catcode 10
+\newcommand{\ExamplecodeProcessText}[1]{\ExamplecodePrint{\ExamplecodeFormatText{#1}}} % catcode 11, 12
+\newcommand{\ExamplecodeProcessBracket}[1]{\ExamplecodePrint{\ExamplecodeFormatBracket{#1}}} % catcode 11
+% catcode 13: active (uses \ExamplecodeProcessCmd, too)
+\newcommand{\ExamplecodeProcessBeginComment}{\ExamplecodePrint{\begingroup\ExamplecodeFormatComment}} % catcode 14
+\newcommand{\ExamplecodeProcessEndComment}{\ExamplecodePrint{\endgroup}}
+% catcode 15: invalid
+
+\newcommand{\ExamplecodeProcessCleanup}{\ExamplecodePrint{%
+ \ifExamplecodeInAlign
+ \endgroup
+ \fi
+}}
+
+\newcommand{\ExamplecodeProcessMeta}[1]{\ExamplecodePrint{\ExamplecodeFormatMeta{#1}}}
+
+
+% ---------- key=value options ---------
+
+\newcommand{\ExamplecodeParseKeys}[1]{% #1: key path
+ \ExamplecodeParse
+ {\@examplecode@prepare@parsekeys{#1}}%
+ {\@examplecode@cleanup@parsekeys}%
+ \ExamplecodeEndParseKeys
+}
+\newcommand{\@examplecode@prepare@parsekeys}[1]{% #1: key path
+ \let\@examplecode@print@original=\ExamplecodePrint
+ \ExamplecodeNoCmd
+ \def\@examplecode@key@cmd{\key@withopt@unformatted}%
+ \def\@examplecode@keypath{#1}%
+ \let\@examplecode@pathsep=\@empty
+ \def\ExamplecodeProcessText##1{% ##1: current token
+ \ifx,##1%
+ \ifExamplecodeInAlign
+ \endgroup
+ \fi
+ \@examplecode@endkey
+ \let\@examplecode@beginkey=\@examplecode@beginkey@bak
+ \@examplecode@print@original{\ExamplecodeFormatText{##1}}%
+ \else\ifx=##1%
+ \@examplecode@endkey
+ \let\@examplecode@beginkey=\relax
+ \@examplecode@print@original{\ExamplecodeFormatText{##1}}%
+ \else\ifx/##1%
+ \@examplecode@beginkey
+ \@examplecode@appendpathsep{##1}%
+ \else\ifx.##1%
+ \unless \ifx \@examplecode@pathsep \@empty
+ \@examplecode@endkey
+ \expandafter\@examplecode@print@original\expandafter{\expandafter\ExamplecodeFormatText\expandafter{\@examplecode@pathsep}}%
+ \fi
+ \@examplecode@beginkey
+ \ifx \@examplecode@key \@empty
+ \def\@examplecode@key@cmd[####1]####2{\LinkUnformattedKeyword{handler}{####2}{####2}}%
+ \fi
+ \@examplecode@appendkey{##1}%
+ \else
+ \@examplecode@beginkey
+ \@examplecode@appendkey{##1}%
+ \fi \fi \fi \fi
+ }%
+ \def\@examplecode@appendkey##1{%
+ \ExamplecodePrint{\ExamplecodeFormatText{##1}}%
+ }%
+ \def\@examplecode@appendpathsep##1{%
+ \ExamplecodePrint{\ExamplecodeFormatText{##1}}%
+ }%
+ \def\ExamplecodeProcessBeginComment{%
+ \@examplecode@endkey
+ \begingroup
+ \let\@examplecode@beginkey=\relax
+ \let\@examplecode@beginkey@bak=\relax
+ \@examplecode@print@original{\begingroup\ExamplecodeFormatComment}%
+ \let\ExamplecodePrint=\@examplecode@print@original
+ }%
+ \def\ExamplecodeProcessEndComment{%
+ \@examplecode@print@original{\endgroup}%
+ \endgroup
+ }%
+ \def\ExamplecodeProcessBeginGroup##1{%
+ \begingroup
+ \let\@examplecode@beginkey=\relax
+ \let\@examplecode@beginkey@bak=\relax
+ \ExamplecodePrint{\ExamplecodeFormatBeginGroup{##1}}%
+ }%
+ \def\ExamplecodeProcessEndGroup##1{%
+ \ExamplecodePrint{\ExamplecodeFormatEndGroup{##1}}%
+ \endgroup
+ }%
+}
+\newcommand{\@examplecode@cleanup@parsekeys}{%
+ \@examplecode@endkey
+ \ExamplecodeProcessCleanup
+}
+\newcommand{\@examplecode@beginkey}{%
+ \begingroup
+ \def\@examplecode@key{}%
+ \let\@examplecode@keyspace=\@empty
+ \def\@examplecode@appendkey##1{%
+ \unless \ifx \@examplecode@keyspace \@empty
+ \appto\@examplecode@key{ }%
+ \let\@examplecode@keyspace=\@empty
+ \fi
+ \@examplecode@applypathsep
+ \appto\@examplecode@key{##1}%
+ }%
+ \def\@examplecode@appendpathsep##1{%
+ \unless \ifx \@examplecode@keyspace \@empty
+ \appto\@examplecode@key{ }%
+ \let\@examplecode@keyspace=\@empty
+ \fi
+ \appto\@examplecode@pathsep{##1}%
+ }%
+ \def\@examplecode@applypathsep{%
+ \unless \ifx \@examplecode@pathsep \@empty
+ \eappto\@examplecode@key{\@examplecode@pathsep}%
+ \let\@examplecode@pathsep=\@empty
+ \fi
+ }%
+ \def\ExamplecodePrint##1{%
+ \@examplecode@endkey
+ \@examplecode@print@original{##1}%
+ }%
+ \def\ExamplecodeProcessSpace{%
+ \@examplecode@applypathsep
+ \appto\@examplecode@keyspace{\ExamplecodeSpace}%
+ }%
+ \let\@examplecode@beginkey=\relax
+ \def\@examplecode@endkey{%
+ \edef\@examplecode@do{\noexpand\@examplecode@print@original{%
+ \expandafter\noexpand\@examplecode@key@cmd[\@examplecode@keypath]{\@examplecode@key}%
+ \expandonce{\@examplecode@pathsep}%
+ \expandonce{\@examplecode@keyspace}%
+ }}%
+ \@examplecode@do
+ \endgroup
+ }%
+}
+\let\@examplecode@beginkey@bak=\@examplecode@beginkey
+\newcommand{\@examplecode@endkey}{}
+
+\newcommand{\ExamplecodeEndParseKeys}{\PackageError{examplecode}{This should never be expanded}{}}
+
+
+% ---------- parsing command ---------
+
+\newcommand{\ExamplecodeParse}[3]{% #1: prepare, #2: cleanup, #3: end token
+ \begingroup
+ #1%
+ \let\@examplecode@endtoken=#3%
+ \def\@examplecode@checkend##1{#2\@examplecode@beforeline\endgroup}%
+ \@examplecode@loop
+}
+
+% WARNING: reads end token before changing catcodes
+% compares end token with \ifx in case it is a control sequence
+% => does not find end token if it's catcode is changed
+% => \xc`...` does not work directly but inside of macro
+\newcommand{\@xc@prepare}{%
+ \def\ExamplecodeNormalSpace{\ExamplecodeSpaceSymbol}%
+ \def\ExamplecodeNormalTab{\ExamplecodeTabSymbol}%
+ \@examplecode@setcatcodes
+ \@examplecode@state@normal
+ \let\ExamplecodeAllowLinebreak=\relax
+ \gdef\@xc@code{}%
+ \def\ExamplecodePrint{\gappto\@xc@code}%
+}%
+\newcommand{\@xc@afterend}{%
+ \formatcode{\@xc@code}%
+}
+\newcommand{\xc}{%
+ \ExamplecodeParse{%
+ \@xc@prepare
+ }{%
+ \ExamplecodeProcessCleanup
+ \@xc@afterend
+ }%
+}
+\newcommand{\xckey}{%
+ \ExamplecodeParse{%
+ \@xc@prepare
+ \@examplecode@prepare@parsekeys{}%
+ }{%
+ \@examplecode@cleanup@parsekeys
+ \@xc@afterend
+ }%
+}
+
+
+% ---------- escape inside ---------
+
+\newcommand{\ExamplecodeEscapeinside}[2]{% #1: begin token, #2: end token
+ \def\@examplecode@escapeinside#1##1#2{##1\@examplecode@loop}%
+ \let\@examplecode@escapeinside@startchar=#1%
+}
+
+
+% ---------- line numbers ---------
+
+\newcounter{ExamplecodeLinecounter}
+\newcommand{\ExamplecodeLinenumbers}{%
+ \setcounter{ExamplecodeLinecounter}{1}%
+ \let\@examplecode@beforeline@hook=\@examplecode@insertlinenumber
+}
+\newcommand\@examplecode@insertlinenumber{%
+ \makebox[0pt][r]{{\ExamplecodeFormatLinenumber{\theExamplecodeLinecounter}}\quad}%
+ \stepcounter{ExamplecodeLinecounter}%
+}
+\newcommand\ExamplecodeFormatLinenumber[1]{%
+ \normalfont
+ \footnotesize
+ #1%
+}
+
+
+% ---------- parsing environment ---------
+
+\newenvironment{examplecode}{%
+ \csname examplecode*\endcsname{}%
+}{%
+ \csname endexamplecode*\endcsname{}%
+}
+\newenvironment{examplecode*}[1]{%
+ \let\@examplecode@envname=\@currenvir
+ \@examplecode@setcatcodes
+ \let\@examplecode@endtoken=\end
+ #1%
+ \begin{examplecodebox}%
+ \colorlet{linkcolor}{codelinkcolor}%
+ \raggedright
+ \ttfamily
+ \leavevmode
+ \parskip=0pt
+ \parindent=0pt\relax
+ \let\\=\ExamplecodeLinebreak
+ \@examplecode@state@firstindent
+ \@examplecode@gobblefirsteol
+}{%
+ \end{examplecodebox}%
+}
+
+\newenvironment{examplecodekey}{%
+ \csname examplecodekey*\endcsname{}%
+}{%
+ \csname endexamplecodekey*\endcsname{}%
+}
+\newenvironment{examplecodekey*}[1]{%
+ \csname examplecode*\endcsname{%
+ \@examplecode@prepare@parsekeys{}%
+ #1%
+ }%
+}{%
+ \@examplecode@cleanup@parsekeys
+ \csname endexamplecode*\endcsname
+}
+
+
+\newcommand{\@examplecode@setcatcodes}{%
+ \@makeother\^^M% end of line
+ \@makeother\^^I% tab
+ \@makeother\ % space
+ \@makeother\%%
+ \makeatletter
+ % changed
+ \@makeother*%
+ \@makeother`%
+}
+\begingroup
+\@makeother\^^M %
+\@makeother\^^I %
+\@firstofone{%
+\endgroup%
+\let\EolOther=^^M%
+\let\TabOther=^^I%
+}
+\begingroup\@makeother\%\@firstofone{\endgroup\let\PercentOther=%}
+
+\newcommand{\@examplecode@error@catcodes@indentation}{\PackageError{examplecode}{failed to change catcodes, indentation will be screwed up}{}}
+\newcommand{\@examplecode@error@mixedtabsandspaces}{\PackageWarning{examplecode}{mixed use of tabs and spaces}}
+
+\newcount\@examplecode@count@outerindent
+\newcount\@examplecode@count@gobbledindent
+\newif\if@examplecode@allowlinebreakbeforenext
+
+\newcommand{\EnsureHMode}{\leavevmode\@examplecode@beforeline\let\EnsureHMode\relax}%
+\let\@EnsureHMode@bak=\EnsureHMode
+
+
+\newcommand{\@examplecode@beforeline}{%
+ \@examplecode@beforeline@hook
+ \let\@examplecode@beforeline=\relax
+}
+\let\@examplecode@beforeline@bak=\@examplecode@beforeline
+\let\@examplecode@beforeline@hook=\relax
+
+\newcommand{\@examplecode@state@firstindent}{%
+ \@examplecode@beforeline
+ \let\@examplecode@check@spaces=\@examplecode@check@firstindent
+}
+\newcommand{\@examplecode@state@gobbleindent}{%
+ \let\@examplecode@beforeline=\@examplecode@beforeline@bak
+ \let\@examplecode@state@normal=\@examplecode@state@normal@bak
+ \ifnum \@examplecode@count@outerindent > 0
+ \@examplecode@count@gobbledindent=0
+ \let\@examplecode@check@spaces=\@examplecode@check@gobbleindent
+ \else
+ \@examplecode@state@indent
+ \fi
+ \let\EnsureHMode=\@EnsureHMode@bak
+}
+\newcommand{\@examplecode@state@indent}{%
+ \let\@examplecode@check@spaces=\@examplecode@check@normalspaces
+ \let\ExamplecodeSpace=\ExamplecodeIndentationSpace
+ \let\ExamplecodeTab=\ExamplecodeIndentationTab
+ \def\ExamplecodeAppendIndentation##1{\eappto\ExamplecodeIndentation{\expandonce{##1}}}%
+ \let\ExamplecodeIndentation=\@empty
+}
+\newcommand{\@examplecode@state@normal}{%
+ \@examplecode@beforeline
+ \let\@examplecode@check@spaces=\@examplecode@check@normalspaces
+ \let\ExamplecodeSpace=\ExamplecodeNormalSpace
+ \let\ExamplecodeTab=\ExamplecodeNormalTab
+ \let\@examplecode@state@normal=\relax
+ \let\ExamplecodeAppendIndentation=\@gobble
+}
+\let\@examplecode@state@normal@bak=\@examplecode@state@normal
+
+
+\newcommand{\@examplecode@gobblefirsteol}[1]{%
+ \ifx \EolOther #1\relax
+ \else
+ \PackageError{examplecode}{unexpected code on same line after \string\begin{examplecode}}{}%
+ \detokenize{#1}%
+ \fi
+ \@examplecode@loop
+}
+
+\newcommand{\@examplecode@loop}{%
+ \futurelet \@examplecode@nexttoken \@examplecode@check
+}
+\newcommand{\@examplecode@check}{%
+ \ifx \@examplecode@nexttoken \@examplecode@endtoken
+ \expandafter \@examplecode@checkend
+ \else
+ \if@examplecode@allowlinebreakbeforenext
+ \ExamplecodeAllowLinebreak
+ \@examplecode@allowlinebreakbeforenextfalse
+ \fi
+ \expandafter \@examplecode@check@ii
+ \fi
+}
+
+\newcommand{\@examplecode@check@ii}{%
+ \ifcat \noexpand\@examplecode@nexttoken \relax
+ \def\@examplecode@do{\@examplecode@handle@cs}%
+ \else
+ \def\@examplecode@do{\@examplecode@check@spaces}%
+ \fi
+ \@examplecode@do
+}
+\newcommand{\@examplecode@handle@cs}[1]{%
+ \ExamplecodeSetCmd{#1}%
+ \@examplecode@state@normal
+ \ExamplecodeProcessCmd{#1}%
+ \@examplecode@loop
+}
+\newcommand{\ExamplecodeSetCmd}[1]{\edef\@examplecode@cs{\detokenize{#1}}}
+\newcommand{\ExamplecodeNoCmd}{\def\@examplecode@cs{}}
+\ExamplecodeNoCmd
+
+\newcommand{\@examplecode@check@normalspaces}{%
+ \ifcat \noexpand\@examplecode@nexttoken \space
+ \def\@examplecode@do##1{\ExamplecodeProcessSpace\@examplecode@loop##1}%
+ \else\if \noexpand\@examplecode@nexttoken \space
+ \def\@examplecode@do##1{\ExamplecodeProcessSpace\@examplecode@loop}%
+ \else\ifx \@examplecode@nexttoken \TabOther
+ \def\@examplecode@do##1{\ExamplecodeProcessTab\@examplecode@loop}%
+ \else
+ \def\@examplecode@do{\@examplecode@check@iv}%
+ \fi \fi \fi
+ \@examplecode@do
+}
+% count the indentation of the first line
+\newcommand{\@examplecode@check@firstindent}{%
+ \ifcat \noexpand\@examplecode@nexttoken \space
+ \@examplecode@error@catcodes@indentation
+ \advance\@examplecode@count@outerindent by 1
+ \def\@examplecode@do##1{\@examplecode@loop##1}%
+ \else\if \noexpand\@examplecode@nexttoken \space
+ \advance\@examplecode@count@outerindent by 1
+ \def\@examplecode@do##1{\@examplecode@loop}%
+ \else\ifx \@examplecode@nexttoken \TabOther
+ \advance\@examplecode@count@outerindent by \ExamplecodeTabsize
+ \def\@examplecode@do##1{\@examplecode@loop}%
+ \else
+ \def\@examplecode@do{\@examplecode@check@iv}%
+ \fi \fi \fi
+ \@examplecode@do
+}
+% gobble indentation as far as the first line was indented
+\newcommand{\@examplecode@check@gobbleindent}{%
+ \ifcat \noexpand\@examplecode@nexttoken \space
+ \@examplecode@error@catcodes@indentation
+ \@examplecode@gobbleindent{1}%
+ \def\@examplecode@do##1{\@examplecode@loop##1}%
+ \else\if \noexpand\@examplecode@nexttoken \space
+ \@examplecode@gobbleindent{1}%
+ \def\@examplecode@do##1{\@examplecode@loop}%
+ \else\ifx \@examplecode@nexttoken \TabOther
+ \@examplecode@gobbleindent{\ExamplecodeTabsize}%
+ \def\@examplecode@do##1{\@examplecode@loop}%
+ \else
+ \def\@examplecode@do{\@examplecode@check@iv}%
+ \fi \fi \fi
+ \@examplecode@do
+}
+\newcommand{\@examplecode@gobbleindent}[1]{%
+ \advance\@examplecode@count@gobbledindent by #1
+ \ifnum \@examplecode@count@gobbledindent = \@examplecode@count@outerindent
+ \@examplecode@state@indent
+ \else\ifnum \@examplecode@count@gobbledindent > \@examplecode@count@outerindent
+ \@examplecode@error@mixedtabsandspaces
+ \@examplecode@state@indent
+ \fi \fi
+}
+\newcommand{\@examplecode@check@iv}{%
+ \def\@examplecode@do{\@examplecode@check@v}%
+ \unless\ifx \@examplecode@escapeinside@startchar \relax
+ \if \noexpand\@examplecode@nexttoken \noexpand\@examplecode@escapeinside@startchar
+ \def\@examplecode@do{\@examplecode@escapeinside}%
+ \fi
+ \fi
+ \@examplecode@do
+}
+\newcommand{\@examplecode@check@v}{%
+ \ifcat \noexpand\@examplecode@nexttoken \bgroup% catcode 1
+ \def\@examplecode@do{\@examplecode@handlebgroup}%
+ \else\ifcat \noexpand\@examplecode@nexttoken \egroup% catcode 2
+ \def\@examplecode@do{\expandafter\@examplecode@handlespecialtoken\expandafter\ExamplecodeProcessEndGroup\string}%
+ \else\ifcat \noexpand\@examplecode@nexttoken $% catcode 3
+ \def\@examplecode@do{\@examplecode@handlemathshift}%
+ \else\ifcat \noexpand\@examplecode@nexttoken &% catcode 4
+ \def\@examplecode@do{\@examplecode@handlespecialtoken\ExamplecodeProcessAlignmentTab}%
+ \else\ifx \@examplecode@nexttoken \EolOther% catcode 5
+ \@examplecode@endcomment
+ \def\@examplecode@do##1{%
+ \ExamplecodeProcessEndOfLine
+ \@examplecode@state@gobbleindent
+ \@examplecode@loop
+ }%
+ \else\ifcat \noexpand\@examplecode@nexttoken ##% catcode 6
+ \def\@examplecode@do{\@examplecode@handleparameter}%
+ \else\ifcat \noexpand\@examplecode@nexttoken ^% catcode 7
+ \def\@examplecode@do{\@examplecode@handlespecialtoken\ExamplecodeProcessSuperscript}%
+ \else\ifcat \noexpand\@examplecode@nexttoken _% catcode 8
+ \def\@examplecode@do{\@examplecode@handlespecialtoken\ExamplecodeProcessSubscript}%
+ % catcode 9: ignored characters
+ % catcode 10: space, handled in \@examplecode@check@spaces
+ % catcode 11: letter, handled in \else
+ % catcode 12: other, handled in \else
+ \else\ifx \@examplecode@nexttoken <%
+ \def\@examplecode@do{\@examplecode@handlepossiblemeta}%
+ % catcode 13: active, handled in \@examplecode@check@ii (after \futurelet it's indistinguishable from a control sequence)
+ \else\ifx \@examplecode@nexttoken \PercentOther% catcode 14
+ \@examplecode@state@normal
+ \ExamplecodeProcessBeginComment
+ \def\@examplecode@endcomment{\ExamplecodeProcessEndComment}%
+ \def\@examplecode@do{\@examplecode@handlenormaltoken}%
+ % catcode 15: invalid characters
+ \else% catcode 11, 12
+ \def\@examplecode@do{\@examplecode@handlenormaltoken}%
+ \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi
+ \@examplecode@do
+}
+\newcommand{\@examplecode@endcomment}{}
+\newcommand{\@examplecode@handlebgroup}{%
+ \ifcsundef{@examplecode@formatarg\@examplecode@cs}{%
+ \expandafter\@examplecode@handlespecialtoken\expandafter\ExamplecodeProcessBeginGroup\string
+ }{%
+ \csname @examplecode@formatarg\@examplecode@cs\endcsname
+ }%
+}
+\newcommand{\@examplecode@handlenormaltoken}[1]{%
+ \@examplecode@state@normal
+ \ifcsundef{@examplecode@formatoptarg\@examplecode@cs#1}{%
+ \csname @examplecode@breakafter@#1\endcsname
+ \ExamplecodeProcessText{#1}%
+ \@examplecode@loop
+ }{%
+ \csname @examplecode@formatoptarg\@examplecode@cs#1\endcsname
+ }%
+}
+\newcommand{\@examplecode@handlespecialtoken}[2]{%
+ \@examplecode@state@normal
+ #1{\string#2}%
+ \@examplecode@loop
+}
+
+\newcommand{\@examplecode@handlemathshift}[1]{%
+ \@examplecode@math@begin
+ \ExamplecodeProcessMathShift{\string#1}%
+ \@examplecode@math@end
+ \@examplecode@loop
+}
+\newcommand{\@examplecode@math@begin}{%
+ \@examplecode@state@normal
+ \begingroup
+ \let\@examplecode@handlemeta=\@examplecode@handlenormaltoken
+ \ExamplecodeProcessBeginMath
+ \let\@examplecode@math@begin=\relax
+ \def\@examplecode@math@end{\def\@examplecode@math@end{\ExamplecodeProcessEndMath\endgroup}}%
+}
+
+\newcommand{\@examplecode@handleparameter}[1]{%
+ \edef\@examplecode@parameter{\string#1}%
+ \@examplecode@parameterloop
+}
+\newcommand{\@examplecode@parameterloop}{%
+ \futurelet \@examplecode@nexttoken \@examplecode@parametercheck
+}
+\newcommand{\@examplecode@parametercheck}{%
+ \ifcat \noexpand\@examplecode@nexttoken ##%
+ \def\@examplecode@do##1{%
+ \edef\@examplecode@parameter{\@examplecode@parameter\string##1}%
+ \@examplecode@parameterloop
+ }%
+ \else\ifcat \noexpand\@examplecode@nexttoken 1%
+ \def\@examplecode@do##1{%
+ \edef\@examplecode@parameter{\@examplecode@parameter##1}%
+ \expandafter\ExamplecodeProcessParameter\expandafter{\@examplecode@parameter}%
+ \@examplecode@loop
+ }%
+ \else
+ \def\@examplecode@do{%
+ \expandafter\ExamplecodeProcessParameter\expandafter{\@examplecode@parameter}%
+ \@examplecode@check
+ }%
+ \fi \fi
+ \@examplecode@do
+}
+
+\newcommand{\@examplecode@handlepossiblemeta}[1]{%
+ \def\@examplecode@tmp{#1}%
+ \futurelet \@examplecode@nexttoken \@examplecode@checkmeta
+}
+\newcommand{\@examplecode@checkmeta}{%
+ \ifcat \@examplecode@nexttoken a%
+ \def\@examplecode@do{\@examplecode@handlemeta}%
+ \else
+ \def\@examplecode@do{\@examplecode@handlenormaltoken}%
+ \fi
+ \expandafter\@examplecode@do\@examplecode@tmp
+}
+\def\@examplecode@handlemeta<#1>{%
+ \ExamplecodeProcessMeta{#1}%
+ \@examplecode@loop
+}
+
+\newcommand{\@examplecode@checkend}[2]{%
+ \def\@examplecode@arg{#2}%
+ \ifx \@examplecode@arg \@examplecode@envname
+ \expandafter \@firstoftwo
+ \else
+ \expandafter \@secondoftwo
+ \fi{%
+ \end{#2}%
+ }{%
+ \@examplecode@state@normal
+ \ExamplecodeProcessCmd{#1}%
+ \ExamplecodeProcessBeginGroup{\{}%
+ \ExamplecodeProcessEnv{#2}%
+ \ExamplecodeProcessEndGroup{\}}%
+ \@examplecode@loop
+ }%
+}%
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/keydoc.tex b/macros/latex/contrib/easyfloats/doc/preamble/keydoc.tex
new file mode 100644
index 0000000000..3116266bef
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/keydoc.tex
@@ -0,0 +1,754 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+\usepackage{etoolbox}
+\usepackage{pgfkeys}
+
+% Defines a macro to document a macro or environment key:
+% \keydoc{<keyname> = <allowedvalues>}{<keytype>}
+% \keydoc[<options>]{<keyname> = <allowedvalues>}{<keytype>}
+% Following text is assumed to be a description of the key.
+% If it is instead followed by another \keydoc it is assumed
+% that this key has no description.
+% If a description applies to two keys separate the \keydocs
+% by a slash.
+% Do *not* put an empty line between a \keydoc and it's description.
+% Spaces after (the second argument of) \keydoc are ignored.
+% <options> is a comma separated list of the following possible key=value pairs:
+% - target = the full key to another key.
+% The name of this key is made into a link to target.
+% This is used by \forwardingkeydoc.
+% - initial value
+% - default value
+% Values are separated by pipes.
+% Wildcards are put in angular brackets.
+%
+% The description of a \keydoc is assumed to reach up to the
+% next \keydoc, \section, \subsection or \subsubsection.
+% If that is not the case you must explicitly end it with
+% \endkeydoc
+% If the description of a \keydoc is ended by a \*section macro
+% there must be a \par (aka an empty line) before that \*section.
+% Otherwise \keydoc@descriptionsep will be inserted.
+%
+% There is a special macro for forwarding keys:
+% \forwardingkeydoc[<options>]{<keyname>}
+% In contrast to \keydoc, the target option can be a path, name or full key.
+% If target is not given it is tried to generate it by expanding
+% \TargetKey{<keypath>}{<keyname>}
+% This macro is given the path (without trailing slash) and name
+% of the key to be described and is expected to expand to a full key.
+% You must define it yourself if you want to leave out the optional argument.
+%
+% \forwardingkeydoc uses internally a more generalized macro:
+% \correspondingkeydoc[<options>]{<keyname>}{<keytype>}
+% target is as flexible as for \forwardingkeydoc
+% but it also takes a <keytype> like \keydoc.
+%
+% Examples for a key pattern can be specified with
+% \keylinktarget{<keyexample>}
+% It must be specified directly following the \keydoc it refers to.
+%
+% \key is redefined to link to \keydoc.
+% However, different environments can have different keys
+% with the same name. In that case a path must be set to
+% distinguish these keys:
+% \keydocpath{<path>}
+% Sets the path for all following \keydoc in the same group.
+% Unambiguous keys can be referenced without a path:
+% \key{sub}
+% For ambiguous keys the path must given as an optional argument:
+% \key[/object]{label}
+% Paths may *not* include a trailing slash.
+%
+% Internals:
+% \begin@keydoc is put before the first \keydoc.
+% \endkeydoc is put after the last description of a \keydoc.
+% \keydoc@beforekey is put before each \keydoc but only once
+% for \keydocs which belong together.
+% \keydoc@keysep is put between \keydocs which belong together.
+% \keydoc@descriptionsep is put between a \keydoc and it's description.
+% If a \keydoc is followed by a \par neither \keydoc@keysep
+% nor \keydoc@descriptionsep is inserted.
+
+
+\makeatletter
+
+% ---------- \keydoc settings ---------
+
+\newcommand{\begin@keydoc}{\begin{itemize}}
+\def \endkeydoc {\end{itemize}}
+
+\newcommand{\keydoc@beforekey}{\item}
+\newcommand{\keydoc@keysep}{~/ }
+\newcommand{\keydoc@descriptionsep}{\nopagebreak\par}
+
+\newcommand{\keydoc@mandatoryvalueformat}[1]{#1}
+\newcommand{\keydoc@optionalvalueformat}{\textcolor{gray}}
+
+\newcommand{\keydoc@keytype}[1]{\,\ensuremath{^{\pgfmanualcslinkpreskip=.33em\pgfmanualcslinkpostskip=\pgfmanualcslinkpreskip\LinkUnformattedKeyword{keytype}{#1}{\keytypesymbol{#1}}}}}
+\newcommand{\keytypedoc@keytype}[1]{\raisebox{.2ex}{\bfseries\keytypesymbol{#1}}}
+
+% ---------- key type symbols ---------
+
+\newcommand{\keytypesymbolformat}[1]{\hbox{\scriptsize(#1)}}
+\newcommand{\newkeytypesymbol}[2]{% #1: key type, #2: symbol
+ \expandafter\newcommand\csname keytypesymbol@#1\endcsname{#2}%
+}
+\newcommand{\keytypesymbol}[1]{% #1: key type
+ \@ifundefined{keytypesymbol@#1}%
+ {\PackageError{keydoc}{undefined keytype `#1'}{}}%
+ {\keytypesymbolformat{\csname keytypesymbol@#1\endcsname}}%
+}
+
+\newkeytypesymbol{storing key}{sto}
+\newkeytypesymbol{executed key}{exe}
+\newkeytypesymbol{boolean key}{bool}
+\newkeytypesymbol{forwarding key}{fwd}
+\newkeytypesymbol{handler}{hdl}
+\newkeytypesymbol{unknown key handler}{unk}
+
+
+% ---------- optional dependencies ---------
+
+\providecommand{\key}[2][]{% #1: key path/group, #2: key name
+ \texttt{#2}%
+}
+
+
+% ---------- auxiliary macros ---------
+
+% \ifendsonspace{<text>}{<then>}{<else>}
+% Checks if the last token of <text> is a space.
+% If it is it expands to <then>{<text-without-last-space>}.
+% If it is not it expands to <else>{<text>}.
+% <text> may not contain \relax.
+\newcommand\ifendsonspace{\ifendson{ }}
+\newcommand\ifendson[2]{%
+ \def\endson@check##1#1\relax.##2\relax\relax##3##4{%
+ \if \relax\detokenize{##2}\relax
+ \def\endson@do{##4}%
+ \endson@stripandappto##1%
+ \else
+ \def\endson@do{##3{##1}}%
+ \fi
+ \endson@do
+ }%
+ \def\endson@stripandappto##1\relax.{\appto\endson@do{{##1}}}%
+ \endson@check#2\relax.#1\relax.\relax\relax
+}
+
+% \newstripoptend{<cs>}{<suffix>}
+% Defines a new control sequence <cs> which checks if it's argument ends on <suffix>.
+% If the argument of <cs> ends on <suffix> it is stripped.
+% If the argument of <cs> does not end on <suffix> <cs> expands to the argument.
+% <cs> is expandable.
+% The number of required expansion steps depends on whether the argument ends on <suffix> or not.
+\newcommand\newstripoptend[2]{% #1: cs, #2: end
+ \expandafter\def\csname\string#1@do\endcsname##1#2\relax.##2\relax\relax{%
+ \if \relax\detokenize{##2}\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\csname\string#1@strip\endcsname##1}%
+ {##1}%
+ }%
+ \expandafter\def\csname\string#1@strip\endcsname##1\relax.{##1}%
+ \newcommand#1[1]{\csname\string#1@do\endcsname##1\relax.#2\relax.\relax\relax}%
+}
+\newstripoptend\stripoptplus{ (+)}
+
+
+% ---------- \FormatKey ---------
+
+\newcommand{\FormatKey}[1]{%
+ \def\FormatKeyText{}%
+ \FormatKey@lookahead#1\pgfeov
+ \let\FormatKey@original=\FormatKey
+ \let\FormatKey=\@firstofone
+ \KeyFormat@original@key{\FormatKeyText}%
+ \let\FormatKey=\FormatKey@original
+}
+\newcommand{\FormatKey@lookahead}{%
+ \futurelet \FormatKey@nexttoken \FormatKey@check
+}
+\newcommand{\FormatKey@check}{%
+ \ifx \FormatKey@nexttoken (%
+ \def\FormatKey@do{\FormatKey@optional}%
+ \else\ifx \FormatKey@nexttoken <%
+ \def\FormatKey@do{\FormatKey@var}%
+ \else\ifcat \noexpand\FormatKey@nexttoken \space
+ \def\FormatKey@do{\FormatKey@space}%
+ \else\ifx \FormatKey@nexttoken \pgfeov
+ \def\FormatKey@do{\FormatKey@endofloop}%
+ \else\ifx \FormatKey@nexttoken \bgroup
+ \def\FormatKey@do{\FormatKey@arg}%
+ \else
+ \def\FormatKey@do{\FormatKey@normaltoken}%
+ \fi \fi \fi \fi \fi
+ \FormatKey@do
+}
+\def\FormatKey@normaltoken#1{%
+ \appto\FormatKeyText{#1}%
+ \FormatKey@lookahead
+}
+\def\FormatKey@arg#1{%
+ \let\FormatKey@text@backup=\FormatKeyText
+ \def\FormatKeyText{}%
+ \FormatKey@lookahead#1\pgfeov
+ \eappto\FormatKey@text@backup{{\expandonce{\FormatKeyText}}}%
+ \let\FormatKeyText=\FormatKey@text@backup
+ \FormatKey@lookahead
+}
+\def\FormatKey@optional(#1){%
+ \appto\FormatKeyText{{\normalfont\color{gray}(}}%
+ \FormatKey@lookahead#1\pgfeov
+ \appto\FormatKeyText{{\normalfont\color{gray})}}%
+ \FormatKey@lookahead
+}
+\providecommand{\meta@nolink}{\meta}
+\def\FormatKey@var<#1>{%
+ \appto\FormatKeyText{{\normalfont\meta@nolink{#1}}}%
+ \FormatKey@lookahead
+}
+\@firstofone{\def\FormatKey@space} {%
+ \appto\FormatKeyText{ }%
+ \FormatKey@lookahead
+}
+\def\FormatKey@endofloop\pgfeov{%
+}
+
+\providecommand{\pgfeov}{\textcolor{red}{\textbf{eov, this should never be expanded}}}
+
+\let\KeyFormat@original@key=\key
+\renewcommand{\key}{\FormatKey}
+
+
+% ---------- format allowed values ---------
+
+\def\FormatVal@var#1{{\normalfont\meta{#1}}}
+\def\FormatVal@or{\unskip\,\ensuremath{|}\,\ignorespaces}
+
+\newcommand{\FormatValue}[1]{%
+ \def\FormatValue@val{}%
+ \expandafter\FormatValue@loop#1\pgfeov
+ \FormatValue@val
+}
+\newcommand{\FormatValue@loop}{%
+ \futurelet \FormatValue@nexttoken \FormatValue@check
+}
+\newcommand{\FormatValue@check}{%
+ \ifx \FormatValue@nexttoken \pgfeov
+ \def\FormatValue@do##1{}%
+ \else\ifcat \noexpand\FormatValue@nexttoken \space
+ \appto\FormatValue@val{ }%
+ \def\FormatValue@do##1{\FormatValue@loop##1}%
+ \else
+ \def\FormatValue@do{\FormatValue@check@ii}%
+ \fi \fi
+ \FormatValue@do
+}
+\newcommand{\FormatValue@check@ii}[1]{%
+ \if|\noexpand#1%
+ \appto\FormatValue@val{\FormatVal@or}%
+ \def\FormatValue@do{\FormatValue@loop}%
+ \else\if<\noexpand#1%
+ \def\FormatValue@do##1>{\appto\FormatValue@val{\FormatVal@var{##1}}\FormatValue@loop}%
+ \else
+ \appto\FormatValue@val{#1}%
+ \def\FormatValue@do{\FormatValue@loop}%
+ \fi \fi
+ \FormatValue@do
+}
+
+
+% ---------- keyword ---------
+% This is a generalized api to link certain keywords.
+% Use the following macro in a description:
+% \NewKeyword[\unexpanded]{<keywordtype>}{<keyword>}{<formatmacro-bg>}{<formatmacro-fg>}{<text>}
+% Use the following macro in references:
+% \LinkKeyword{<keywordtype>}{<keyword>}<formatmacro-bg><formatmacro-fg>{<text>}
+% <keywordtype> and <keyword> are used to generate/
+% link to a hyper link target. They are not visible
+% in the resulting document.
+% <formatmacro-bg/fg>: TeX code which takes one mandatory argument
+% and formats it as desired. Usually those passed to \NewKeyword are used
+% for both the description and the link.
+% Those passed to \LinkKeyword are used only if the link is undefined.
+% <formatmacro-bg> is applied before \FormatLink.
+% <formatmacro-fg> is applied inside of \FormatLink.
+% Setting a background color must happen in <formatmacro-bg>
+% otherwise it will cover the underline produced by \FormatLink.
+% Using \detokenize must happen in <formatmacro-fg>
+% otherwise \FormatLink will not be executed but printed to the pdf.
+% Changing the font can happen in either one.
+% <text>: TeX code to produce the displayed text.
+% The optional argument of \NewKeyword is a macro which
+% takes the <keyword> as argument and can protect it
+% from expansion when writing it to an auxiliary file.
+% If you try to link an undefined keyword you will
+% get a warning.
+%
+% You can define abbreviations so you do not always
+% need to type out the full name:
+% \AbbrevKeyword[\unexpanded]{<abbrevtype>}{<abbrevname>}{<fulltype>}{<fullname>}
+% If two abbreviations are ambiguous they will not
+% cause an error where they are defined but where
+% they are referenced so you can create abbreviations
+% automatically without trouble.
+%
+% In order to avoid warnings for undescribed keywords
+% \NoKeyword[\unexpanded]{<keywordtype>}{<keyword>}{<formatmacro-bg>}{<formatmacro-fg>}
+% can be used. It is used similar to \NewKeyword but
+% does not display any text and \LinkKeyword to this keyword
+% will not result in a link and will not give a warning.
+% The separation in <formatmacro-bg> and <formatmacro-fg>
+% is only for compatability with \NewKeyword.
+%
+% Links are defined in a temporary file which is loaded in the
+% preamble so that \LinkKeyword can be used before \NewKeyword.
+% I am not using the aux file for that because
+% (a) the aux file is loaded twice (once in \begin{document}
+% and once in \end{document}) and
+% (b) the aux file is loaded in a group so all definitions need
+% to be global but \newcommand can't do that and \gdef does not
+% check if a macro is already defined.
+
+
+% https://github.com/pgf-tikz/pgf/blob/master/tex/latex/pgf/doc/pgfmanual-en-macros.tex
+\colorlet{linkcolor}{black!8}
+\newdimen\pgfmanualcslinkpreskip
+\newdimen\pgfmanualcslinkpostskip
+\ifunderlinelinks
+\newcommand{\FormatLink}[1]{%
+ \begingroup
+ \setbox0=\hbox{#1}%
+ \rlap{{%
+ \keyword@original@color{linkcolor}%
+ \dimen0\wd0
+ \advance\dimen0by-\pgfmanualcslinkpreskip
+ \advance\dimen0by-\pgfmanualcslinkpostskip
+ \hskip\pgfmanualcslinkpreskip
+ \vrule width\dimen0 height-1pt depth1.6pt
+ }}%
+ \box0%
+ \endgroup
+}
+\else
+\newcommand{\FormatLink}[1]{#1}
+\fi
+
+
+% is used in the first run when the keyword is not yet defined
+% or if an abbreviation is ambiguous
+\newcommand{\keyword@placeholder}[1]{%
+ {\keyword@original@color{yellow}%
+ #1%
+ }%
+}
+\let\keyword@original@color=\color
+
+\newcommand{\keyword@targetname}[2]{% #1: keyword type, #2: name
+ keyword:#1:#2%
+}
+\newcommand{\keyword@csname}[2]{% #1: keyword type, #2: name
+ keyword@#1@#2%
+}
+\newcommand{\keyword@link}[3]{% #1: keyword type, #2: name, #3: text
+ \hyperlink{\keyword@targetname{#1}{#2}}{#3}%
+}
+\newcommand{\DisableLinks}{%
+ \let\keyword@link=\@thirdofthree
+ \let\FormatLink=\@firstofone
+}
+\let\keyword@formatenable=\@firstofone
+\newrobustcmd{\keyword@new}[4]{% #1: keyword type, #2: name, #3: format macro bg, #4: format macro fg
+ \expandafter\newcommand\csname\keyword@csname{#1}{#2}\endcsname[1]{\keyword@link{#1}{#2}{\keyword@formatenable{#3}{\FormatLink{\keyword@formatenable{#4}{##1}}}}}%
+}
+\newrobustcmd{\keyword@no}[4]{% #1: keyword type, #2: name, #3: format macro bg, #4: format macro fg
+ \expandafter\newcommand\csname\keyword@csname{#1}{#2}\endcsname[1]{\keyword@formatenable{#3}{\keyword@formatenable{#4}{##1}}}%
+}
+\newrobustcmd{\keyword@abbrev}[4]{% #1: abbrev keyword type, #2: abbrev name, #3: full keyword type, #4: full name
+ \IfKeywordUndefined{#3}{#4}{%
+ \PackageError{keyword}{#3 `#4' (for which you wanted to add the abbreviation `#1@#2') is undefined}{}%
+ }{\IfKeywordUndefined{#1}{#2}{%
+ \expandafter\let \csname\keyword@csname{#1}{#2}\expandafter\endcsname \csname\keyword@csname{#3}{#4}\endcsname
+ }{%
+ \expandafter\def \csname\keyword@csname{#1}{#2}\endcsname ##1{\PackageWarning{keyword}{The abbreviation #1 `#2' is ambiguous. Please specify the full name for ##1}{}\keyword@placeholder{##1}}%
+ }}%
+}
+\newcommand{\IfKeywordIsAbbrev}[4]{% key to be tested, reference key
+ \expandafter\ifx \csname\keyword@csname{#1}{#2}\expandafter\endcsname \csname\keyword@csname{#3}{#4}\endcsname
+ \expandafter \@firstoftwo
+ \else
+ \expandafter \@secondoftwo
+ \fi
+}
+
+\newcommand{\LinkKeyword}[5]{% #1: keyword type, #2: name, #3: formatmacro bg, #4: formatmacro fg, #5: displayed text
+ \IfKeywordUndefined{#1}{#2}{%
+ \edef\do{\noexpand\PackageWarning{keydoc}{Either #1 `#2' is undefined or you need to rerun LaTeX}}%
+ \do
+ \keyword@placeholder{#3{#4{#5}}}%
+ }{%
+ \csname \keyword@csname{#1}{#2}\endcsname{#5}%
+ }%
+}
+\newcommand{\LinkUnformattedKeyword}[3]{% #1: keyword type, #2: name, #3 displayed text
+ \begingroup
+ \let\keyword@formatenable=\@gobble
+ \LinkKeyword{#1}{#2}\@firstofone\@firstofone{#3}%
+ \endgroup
+}
+\newcommand{\IfKeywordUndefined}[2]{% #1: keyword type, #2: name, #3: then, #4: else
+ \expandafter \ifx \csname\keyword@csname{#1}{#2}\endcsname \relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+
+
+\newcommand\keyword@filename{\jobname.kw}
+
+\AtBeginDocument{%
+ \IfFileExists{\keyword@filename}{%
+ \makeatletter
+ \input{\keyword@filename}%
+ \makeatother
+ }{}
+ \newwrite\keyword@file
+ \immediate\openout\keyword@file=\keyword@filename\relax
+}
+
+\newcommand{\NewKeyword}[6][\@firstofone]{% [#1: name protection], #2: type, #3: name, #4: format macro bg, #5: format macro fg, #6: text
+ %https://tex.stackexchange.com/a/17138
+ \Hy@raisedlink{\hypertarget{\keyword@targetname{#2}{#3}}{}}%
+ \if\relax\detokenize{#6}\relax
+ \else
+ #4{#5{#6}}%
+ \fi
+ \immediate\write\keyword@file{\keyword@new{#2}{#1{#3}}{\unexpanded{#4}}{\unexpanded{#5}}}%
+}
+\newcommand{\AbbrevKeyword}[5][\@firstofone]{% abbrev = full
+ \immediate\write\keyword@file{\keyword@abbrev{#2}{#1{#3}} {#1{#4}}{#1{#5}}}%
+}
+\newrobustcmd{\NoKeyword}[5][\@firstofone]{% #2: keyword type, #3: name, #4: format macro bg, #5: format macro fg
+ \immediate\write\keyword@file{\keyword@no{#2}{#1{#3}}{\unexpanded{#4}}{\unexpanded{#5}}}%
+}
+
+
+% ---------- \keydoc ---------
+
+\newif\if@inkeydoc
+\newif\ifkeydoc@isrelated
+
+\newcommand\keydoc@keypath{}
+\newcommand{\keydocpath}[1]{\def\keydoc@keypath{#1}}
+
+\pgfqkeys{/keydoc}{%
+ target/.initial,
+ target/.value required,
+ %
+ initial value/.initial,
+ initial value/.value required,
+ %
+ default value/.initial,
+ default value/.value required,
+}
+
+\newcommand{\keydoc@printvalues}{%
+ \pgfkeysgetvalue{/keydoc/initial value}{\keydoc@initialvalue}%
+ \pgfkeysgetvalue{/keydoc/default value}{\keydoc@defaultvalue}%
+ \let\keydoc@initdefault=\@empty
+ %
+ \unless\ifx \keydoc@defaultvalue \pgfkeysnovalue@text
+ \appto\keydoc@initdefault{\hyperref[initial-vs-default-values]{Default value}: \keydoc@defaultvalue.}%
+ \fi
+ \unless\ifx \keydoc@initialvalue \pgfkeysnovalue@text
+ \unless\ifx \keydoc@initdefault \@empty
+ \appto\keydoc@initdefault{ }%
+ \fi
+ \appto\keydoc@initdefault{\hyperref[initial-vs-default-values]{Initial value}: \keydoc@initialvalue.}%
+ \fi
+ \unless\ifx \keydoc@initdefault \@empty
+ \\%
+ {\MaxFontSize\footnotesize\keydoc@initdefault}%
+ \fi
+ \pgfkeyssetvalue{/keydoc/initial value}{\pgfkeysnovalue}%
+ \pgfkeyssetvalue{/keydoc/default value}{\pgfkeysnovalue}%
+}
+\newcommand{\MaxFontSize}[1]{%
+ #1%
+ \def\MaxFontSize@do##1#1##2\relax{%
+ \@tfor\MaxFontSize@fontsize:=##1\do{%
+ \expandafter\let\MaxFontSize@fontsize=\relax
+ }%
+ }%
+ \MaxFontSize@do\Huge\huge\LARGE\Large\large\normalsize\small\footnotesize\scriptsize\tiny\relax
+}
+
+\newcommand{\keydoc}[3][]{% [#1: options], #2: key name, #3: key type
+ \unless \if@inkeydoc
+ \begin@keydoc
+ \keydoc@registerend
+ \@inkeydoctrue
+ \fi
+ \pgfkeyssetvalue{/keydoc/target}{\pgfkeysnovalue}%
+ \pgfqkeys{/keydoc}{#1}%
+ \keydoc@parsekey#2=\relax%
+ \def\keydoc@abbrev{%
+ \AbbrevKeyword{key}{\keydoc@keypattern} {key}{\keydoc@keypath/\keydoc@keypattern}%
+ \AbbrevKeyword{}{\keydoc@keypattern} {key}{\keydoc@keypath/\keydoc@keypattern}%
+ }%
+ \pgfkeysgetvalue{/keydoc/target}{\keydoc@targetkey}%
+ \ifx \keydoc@targetkey \pgfkeysnovalue@text
+ \let\keydoc@link=\@firstofone
+ \else
+ \def\keydoc@link{\LinkKeyword{key}{\keydoc@targetkey}\keydoc@key@bg\keydoc@original@key}%
+ \IfKeywordUndefined{}{\keydoc@keypattern}{%
+ % keep \keydoc@abbrev
+ }{\IfKeywordIsAbbrev{}{\keydoc@keypattern} {key}{\keydoc@keypath/\keydoc@keypattern}{%
+ % keep \keydoc@abbrev
+ }{%
+ \let\keydoc@abbrev=\relax
+ }}%
+ \fi
+ \ifkeydoc@isrelated
+ \keydoc@keysep
+ \else
+ \keydoc@beforekey
+ \fi
+ \edef\keydoc@do{%
+ \noexpand\NewKeyword{key}{\keydoc@keypath/\keydoc@keypattern}{\noexpand\keydoc@key@bg}{\noexpand\keydoc@original@key}{\noexpand\keydoc@link{\keydoc@keypattern}%
+ \noexpand\keydoc@valueformat{\keydoc@keyvalsep\noexpand\FormatValue\noexpand\keydoc@keyval}}%
+ }%
+ \keydoc@do
+ \keydoc@abbrev
+ \keydoc@keytype{#3}%
+ \keydoc@isrelatedfalse
+ \keydoc@lookahead
+}
+\def\keydoc@parsekey#1=#2\relax{%
+ \if \relax\detokenize{#2}\relax
+ \def\keydoc@keypattern{#1}%
+ \def\keydoc@keyval{}%
+ \def\keydoc@keyvalsep{}%
+ \let\keydoc@valueformat=\@firstofone
+ \else
+ \expandafter\def\expandafter\keydoc@keyval\expandafter{\keydoc@stripeq#2\relax}%
+ \expandafter\keydoc@checkifvalueisoptional\keydoc@keyval\relax
+ \ifendsonspace{#1}{%
+ \def\keydoc@keyvalsep{\ =}%
+ \def\keydoc@keypattern%{#1 without space}
+ }{%
+ \def\keydoc@keyvalsep{=}%
+ \def\keydoc@keypattern%{#1}
+ }%
+ \fi
+}
+\def\keydoc@stripeq#1=\relax{#1}
+\def\keydoc@checkifvalueisoptional#1#2\relax{%
+ \pgfkeysgetvalue{/keydoc/default value}{\keydoc@defaultvalue}%
+ \ifx?#1%
+ \ifx \keydoc@defaultvalue \pgfkeysnovalue@text
+ \ifx \keydoc@link \@firstofone
+ \PackageWarning{keydoc}{keydoc with optional value but default value is not given}{}%
+ \fi
+ \fi
+ \def\keydoc@keyval{#2}%
+ \let\keydoc@valueformat=\keydoc@optionalvalueformat
+ \else
+ \unless\ifx \keydoc@defaultvalue \pgfkeysnovalue@text
+ \PackageWarning{keydoc}{keydoc with default value but value is not optional}{}%
+ \fi
+ \let\keydoc@valueformat=\keydoc@mandatoryvalueformat
+ \fi
+}
+
+
+
+\newcommand{\keydoc@lookahead}{%
+ \futurelet \keydoc@nexttoken \keydoc@lookahead@check
+}
+\newcommand{\keydoc@lookahead@check}{%
+ \ifcat \noexpand\keydoc@nexttoken \space
+ \let\keydoc@lookahead@do=\keydoc@lookahead
+ \let\keydoc@lookahead@gobble=\@firstofone
+ \else\ifx \keydoc@nexttoken \par
+ \let\keydoc@lookahead@do=\keydoc@afterlookahead
+ \let\keydoc@lookahead@gobble=\@empty
+ \else\ifx \keydoc@nexttoken /%
+ \keydoc@isrelatedtrue
+ \let\keydoc@lookahead@do=\keydoc@lookahead
+ \let\keydoc@lookahead@gobble=\@gobble
+ \else\ifx \keydoc@nexttoken \keydoc
+ \let\keydoc@lookahead@do=\keydoc@afterlookahead
+ \let\keydoc@lookahead@gobble=\@empty
+ \else\ifx \keydoc@nexttoken \forwardingkeydoc
+ \let\keydoc@lookahead@do=\keydoc@afterlookahead
+ \let\keydoc@lookahead@gobble=\@empty
+ \else\ifx \keydoc@nexttoken \correspondingkeydoc
+ \let\keydoc@lookahead@do=\keydoc@afterlookahead
+ \let\keydoc@lookahead@gobble=\@empty
+ \else\ifx \keydoc@nexttoken \endkeydoc
+ \let\keydoc@lookahead@do=\keydoc@afterlookahead
+ \let\keydoc@lookahead@gobble=\@empty
+ \else
+ \ifkeydoc@isrelated
+ \PackageError{keydoc}{expexcted another keydoc command after /}{}%
+ \fi
+ \keydoc@printvalues
+ \keydoc@descriptionsep
+ \let\keydoc@lookahead@do=\relax
+ \let\keydoc@lookahead@gobble=\@empty
+ \fi \fi \fi \fi \fi \fi \fi
+ \expandafter \keydoc@lookahead@do \keydoc@lookahead@gobble
+}
+\newcommand{\keydoc@afterlookahead}{%
+ \unless\ifkeydoc@isrelated
+ \keydoc@printvalues
+ \fi
+}
+\newcommand{\RegisterEnd}[1]{%
+ \@tfor \@sec@cmd :=\section\subsection\subsubsection \do{%
+ \expandafter\appto\csname My\expandafter\string\@sec@cmd Hook\endcsname{#1}%
+ }%
+}
+\newcommand{\keydoc@registerend}{\RegisterEnd\endkeydoc}
+
+\newcommand{\keylinktarget}[1]{%
+ \AbbrevKeyword{key}{\keydoc@keypath/#1} {key}{\keydoc@keypath/\keydoc@keypattern}%
+ \AbbrevKeyword{key}{#1} {key}{\keydoc@keypath/\keydoc@keypattern}%
+ \AbbrevKeyword{}{#1} {key}{\keydoc@keypath/\keydoc@keypattern}%
+ \ignorespaces
+}
+
+\let\keydoc@original@key=\key
+\newcommand{\keydoc@key@bg}{\formatcode}
+% I cannot say \renewcommand{\key}[1][] because that would break \keydoc@original@key
+\renewcommand{\key}{%
+ \@ifnextchar [
+ \key@withopt
+ \key@withoutopt
+}
+\newcommand{\key@withopt}{}
+\def\key@withopt[#1]#2{%
+ \ifx\relax#1\relax
+ \LinkKeyword{key}{#2}\keydoc@key@bg\keydoc@original@key{#2}%
+ \else
+ \LinkKeyword{key}{#1/#2}\keydoc@key@bg\keydoc@original@key{#2}%
+ \fi
+}
+\newcommand{\key@withoutopt}[1]{%
+ \LinkKeyword{key}{#1}\keydoc@key@bg\keydoc@original@key{#1}%
+}
+
+\def\key@withopt@unformatted[#1]#2{%
+ \ifx\relax#1\relax
+ \LinkUnformattedKeyword{key}{#2}{#2}%
+ \else
+ \LinkUnformattedKeyword{key}{#1/#2}{#2}%
+ \fi
+}
+
+
+% ---------- \forwardingkeydoc ---------
+
+\newcommand{\forwardingkeydoc}[2][]{% [#1: name, path or full key of target], #2: name
+ \correspondingkeydoc[#1]{#2}{forwarding key}%
+}
+\newcommand{\correspondingkeydoc}[3][]{% [#1: options], #2: name, #3: key type
+ \keydoc[#1, /utils/exec=\forwardingkeydoc@parsetarget{#2}]{#2}{#3}%
+}
+\newcommand{\forwardingkeydoc@parsetarget}[1]{% #1: this key name
+ % parse target which may be a name, path or full key of corresponding key
+ \pgfkeysgetvalue{/keydoc/target}{\forwardingkeydoc@targetkey}%
+ \ifx\forwardingkeydoc@targetkey\pgfkeysnovalue@text
+ \ifundef\TargetKey{%
+ \PackageError{keydoc}
+ {\string\TargetKey{<keypath>}{<keyname>} must be defined if the the optional argument of \forwardingkeydoc\space is not passed}
+ {\string\TargetKey\space shall expand to path/name of the linked key given the path (without trailing slash) and name of the forwarding key.}%
+ }{%
+ \def\forwardingkeydoc@targetkey{\TargetKey{\keydoc@keypath}}%
+ \edef\forwardingkeydoc@targetkey{\expandafter\forwardingkeydoc@targetkey\expandafter{\forwardingkeydoc@stripval#1=\relax}}%
+ \expandafter\ifendsonspace\expandafter{\forwardingkeydoc@targetkey}%
+ {\def\forwardingkeydoc@targetkey}%
+ {\def\forwardingkeydoc@targetkey}%
+ \pgfkeyslet{/keydoc/target}{\forwardingkeydoc@targetkey}%
+ }%
+ \else
+ \forwardingkeydoc@parse{\forwardingkeydoc@targetkey}{\keydoc@keypath}{#1}%
+ \pgfkeyslet{/keydoc/target}{\forwardingkeydoc@targetkey}%
+ \fi
+}
+\newcommand\forwardingkeydoc@parse[3]{% #1: key name, key path or full key of target, #2: path of source, #3: name of source
+ \IfStartsWithSlash{#1}{%
+ \edef\forwardingkeydoc@targetkey@original{#1}%
+ \edef\forwardingkeydoc@targetkey{#1/\forwardingkeydoc@stripval#3=\relax}%
+ \expandafter\ifendsonspace\expandafter{\forwardingkeydoc@targetkey}%
+ {\def\forwardingkeydoc@targetkey}%
+ {\def\forwardingkeydoc@targetkey}%
+ \IfKeywordUndefined{key}{\forwardingkeydoc@targetkey}{%
+ \let\forwardingkeydoc@targetkey=\forwardingkeydoc@targetkey@original
+ }{}%
+ }{%
+ \def\forwardingkeydoc@targetkey{#2/#1}%
+ }%
+}
+\def\forwardingkeydoc@stripval#1=#2\relax{#1}
+
+\newcommand{\IfStartsWithSlash}[1]{%
+ \expandafter\IfStartsWithSlash@do#1\relax
+}
+\def\IfStartsWithSlash@do#1#2\relax{%
+ \ifx/#1%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+
+
+% ---------- \keytypedoc ---------
+
+\newcommand{\begin@keytypedoc}{\begin{itemize}}
+\def \endkeytypedoc {\end{itemize}}
+
+\newcommand{\keytypedoc@beforekeytype}{\item}
+\newcommand{\keytypedoc@format}[1]{\emph{#1}}
+\newcommand{\keytypedoc@descriptionsep}{:}
+
+\newif\if@inkeytypedoc
+
+\newcommand{\keytypeRAW}[1]{#1}
+\newcommand{\keytype@bg}[1]{#1}
+\newcommand{\keytype}{% [#1: type name], #2: displayed text (usually the type name, but can be another grammatic form)
+ \@ifnextchar [
+ {\@keytype@do}
+ {\@dblarg\@keytype@do}%
+}
+\def\@keytype@do[#1]#2{%
+ \LinkKeyword{keytype}{#1}\keytype@bg\keytypeRAW{#2}%
+}
+
+\newcommand{\keytypedoc}[1]{% #1 key type name
+ \unless \if@inkeytypedoc
+ \begin@keytypedoc
+ \keytypedoc@registerend
+ \@inkeytypedoctrue
+ \fi
+ \keytypedoc@beforekeytype[\keytypedoc@keytype{#1}]
+ \NewKeyword{keytype}{#1}{\keytype@bg}{\keytypeRAW}{\keytypedoc@format{#1}}%
+ \keytypedoc@descriptionsep
+}
+
+\newcommand{\keytypedoc@registerend}{\RegisterEnd\endkeytypedoc}
+
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/link.tex b/macros/latex/contrib/easyfloats/doc/preamble/link.tex
new file mode 100644
index 0000000000..bd6daf7d42
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/link.tex
@@ -0,0 +1,53 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Adds an abstraction layer above hyperref's \href and \hyperref commands.
+% Links are defined with:
+% \newurllink{<name>}{<url>}
+% \newlabellink{<name>}{<label>}
+% A text is turned into a link with
+% \link[<name>]{<text>}
+% Like in markdown the name of the link is optional.
+% If it is omitted <text> is used instead.
+% This has the advantage that all links can be declared in one place
+% and URLs don't need to be repeated.
+% Changing an external link to an internal link is easy.
+
+\makeatletter
+\newcommand{\link@csname}[1]{link@cs@#1}
+
+\newcommand\newurllink{%
+ \begingroup
+ \let\do=\@makeother
+ \dospecials
+ \catcode`{=1
+ \catcode`}=2
+ \newurllink@do
+}
+\newcommand\newurllink@do[2]{% #1: name, #2: url
+ \endgroup
+ \expandafter \newcommand \csname\link@csname{#1}\endcsname{\href{#2}}%
+}
+
+\newcommand\newlabellink[2]{% #1: name, #2: label
+ \expandafter \newcommand \csname\link@csname{#1}\endcsname{\hyperref[#2]}%
+}
+
+\newcommand\link{% [#1: name], #2: displayed text
+ \@ifnextchar [
+ {\link@do}
+ {\@dblarg\link@do}%
+}
+\def\link@do[#1]#2{%
+ \ifcsname\link@csname{#1}\endcsname
+ \csname\link@csname{#1}\endcsname{#2}%
+ \else
+ \PackageError{link}{link name `#1' undefined}{}%
+ \fi
+}
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/macros.tex b/macros/latex/contrib/easyfloats/doc/preamble/macros.tex
new file mode 100644
index 0000000000..2be2bc74cb
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/macros.tex
@@ -0,0 +1,218 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Defines additional macros which are not provided
+% by the document class or other packages.
+%
+% \TikZ
+% Typesets the name of the TikZ package.
+% dtxdescribe defines the \tikz macro for that
+% but it's wrong, the Z is not capitalized.
+%
+% \eTeX
+% Typesets the name of eTeX.
+% In standard LaTeX there are \TeX, \LaTeX and \LaTeXe.
+% metalogo and dtxdescribe define more logos.
+% But I have failed to find a package which provides
+% the eTeX logo.
+% In contrast to the other logo macros \eTeX includes a
+% link to the eTeX manual on CTAN.
+%
+% \radioon
+% draws an activated radio button
+% \radiooff
+% draws a deactivated radio button
+%
+% \DescribeHandler[<class>]{<name>}
+% Typesets the handler name as a \marginpar.
+% The same like all other \Describe* macros defined by dtxdescribe
+% just for handlers.
+%
+% \handler{<name>}
+% To reference a handler described with \DescribeHandler.
+%
+% \filename{<filename>}
+% Typesets a file name in the pdf.
+%
+% \pkgoptn{<option>}
+% Typesets a package option in the pdf.
+% \key{<option>}
+% Typesets a macro/environment option in the pdf.
+% Usually \optn is used for both macro options and package options.
+% However, I am using pgfkeys for macro options and standard LaTeX
+% for package options making the two types of options quite different.
+% Unlike some other packages the easyfloats package does not allow to
+% pass macro options as package options.
+% Therefore I like to have a better distinction between them even
+% if they are formatted in the same way.
+% Also, dtxdescribe defines two different macros for the description:
+% \DescribeOption for package/class options and
+% \DescribeKey for macro/environment options.
+% So it is only consistent to have two different macros for typesetting
+% macro/environment and package/class options.
+% I have redefined \optn to print an error in order to avoid ambiguity.
+% \val{<value>}
+% typesets the value of a key. Package options don't have values.
+%
+% \errormessage{<message>}
+% Typesets an error message in the pdf. Changes category codes so that
+% control sequences and active characters do *not* need to be prefixed
+% by \string.
+%
+% \sectionname{<title>}
+% Format the name of a section of a different document which I am referring to.
+% For sections of this document use \cref or \Cref instead.
+%
+% \newlicense{<name>}{<display text>}{<url>}
+% \license{<name>}
+% Define a license in the preamble with displayed name and URL with \newlicense
+% and use it in the document with \license.
+% Changes catcodes for the <url> only so that special characters
+% can be used there without worrying (except for curly braces).
+%
+% \formatcode{<texcode>}
+% Formats inline code.
+% It does not change catcodes or performs any other kind of magic.
+% <texcode> is executed as TeX code.
+
+\usepackage{relsize}
+
+
+\makeatletter
+\newcommand{\version}{\newcommand\theversion}
+\newcommand{\package}{\newcommand\thepackage}
+\newcommand{\thedate}{\@date}
+\AtBeginDocument{%
+ \let\thedate=\@date
+ \ifundef{\theversion}{}{\appto\@date{\strut\\\strut\thepackage~\theversion}}%
+}
+\makeatother
+
+\makeatletter
+\newcommand\parskipintoc[1]{%
+ \def\@starttoc##1{%
+ \begingroup
+ \makeatletter
+ \parskip=#1\relax
+ \@input{\jobname.##1}%
+ \if@filesw
+ \expandafter\newwrite\csname tf@##1\endcsname
+ \immediate\openout\csname tf@##1\endcsname \jobname.##1\relax
+ \fi
+ \@nobreakfalse
+ \endgroup
+ }
+}
+\makeatother
+\parskipintoc{0pt plus .6em minus 1pt}
+
+\newcommand{\bigpar}{\par{\centering*~*~*\pagebreak[3]\par}}
+\newcommand{\bigparinlist}{\par\medskip\pagebreak[3]\par}
+\let\OriginalItemize=\itemize
+\def\itemize{\OriginalItemize\let\bigpar\bigparinlist}
+
+\newcommand{\eTeX}{\texorpdfstring{\href{https://ctan.org/pkg/etex}{\ensuremath{\varepsilon}-\TeX}}{eTeX}}
+\newcommand{\TikZ}{Ti\emph{k}Z}
+
+\newcommand{\radioon}{\radio{\fill circle (.45);}}
+\newcommand{\radiooff}{\radio\relax}
+\newcommand{\radio}[1]{\tikz[x=1ex,y=1ex,baseline=-.6ex,very thin]{\draw circle (.75);#1}}
+
+
+\newcommand{\filename}{\emph}
+
+\newcommand{\pkgoptn}{\optn}
+\newcommand{\key}{\optn}
+\let\pkgoptn=\optn
+\let\key=\optn
+\let\handler=\optn
+% Do *not* add the optional argument, otherwise \renewcommand would not only redefine \optn
+% but also two internal macros which \pkgoptn and \key depend on.
+\renewcommand{\optn}[1]{\PackageError{macros}{\string\optn\space is ambiguous}{Please use \string\key\space for macro/environment options and \string\pkgoptn\space for package/class options.}}
+
+\newcommand{\val}[1]{#1}
+
+\makeatletter
+\newcommand*{\DescribeHandler}[2][]{\DTXD@margintagindex{#1}{#2}{Handler}{handler}{usage}}
+
+\newcommand{\errormessage}{%
+ \begingroup
+ \let\do=\@makeother
+ \dospecials
+ \@makeother`
+ \catcode`{=1
+ \catcode`}=2
+ \catcode` =10
+ \do@errormessage
+}
+\newcommand{\do@errormessage}[1]{%
+ \endgroup
+ \enquote{\texttt{#1}}%
+}
+\makeatother
+
+
+\newrobustcmd{\sectionname}[1]{{\let\formatcode\formatcodeinsection\emph{#1}}}
+
+
+\makeatletter
+\newcommand{\license@csname}[1]{license@cs@#1}
+\newcommand{\FormatLicense}{\emph}
+
+\newcommand{\newlicense}[2]{%
+ \begingroup
+ \let\do=\@makeother
+ \dospecials
+ \catcode`{=1
+ \catcode`}=2
+ \newlicense@do{#1}{#2}%
+}
+\newcommand{\newlicense@do}[3]{% #1: name, #2: display text, #3: url
+ \endgroup
+ \expandafter \newcommand \csname\license@csname{#1}\endcsname{\href{#3}{\FormatLicense{#2}}}%
+}
+
+\newcommand{\license}[1]{% #1: name
+ \ifcsname\license@csname{#1}\endcsname
+ \csname\license@csname{#1}\endcsname
+ \else
+ \PackageError{macros}{license name `#1' undefined}{}%
+ \fi
+}
+
+
+% ---------- \formatcode ---------
+
+\newcommand{\formatcode}[1]{{\ttfamily\smaller[.5]\fboxsep=.5pt\colorbox{codebackground!50}{\vphantom\}\colorlet{linkcolor}{codelinkcolor}#1}}}
+\newcommand{\formatcodeinsection}[1]{{\ttfamily#1}}
+\newcommand{\formatcodeinmarginpar}[1]{\formatcodeinsection{\small#1}}
+
+% patch section commands and toc to use \formatcodeinsection instead of \formatcode
+\newcommand{\patchsection}[3]{% #1: command to be patched, #2: code to be inserted before, #3 code to be appended
+ \expandafter\let\csname @@originalsec@\string#1\endcsname #1%
+ \expandafter\def\csname @@sec@\string#1\endcsname##1##2{#2\csname @@originalsec@\string#1\endcsname##1{##2}#3}%
+ \def#1##1##{\csname @@sec@\string#1\endcsname{##1}}%
+}
+\@tfor \@sec@cmd :=\section\subsection\subsubsection \do{%
+ \expandafter\expandafter\expandafter\patchsection\expandafter\@sec@cmd\expandafter{%
+ \csname My\expandafter\string\@sec@cmd Hook\endcsname
+ \let\@original@formatcode=\formatcode
+ \let\formatcode=\formatcodeinsection
+ }{%
+ \let\formatcode=\@original@formatcode
+ }%
+}
+\let\@@original@toc=\tableofcontents
+\def\tableofcontents{{\let\formatcode\formatcodeinsection\DisableLinks\@@original@toc}}
+
+% patch \marginpar to use \formatcodeinmarginpar instead of \formatcode
+\let\@@original@marginpar=\marginpar
+\renewcommand\marginpar[1]{\@@original@marginpar{\let\formatcode=\formatcodeinmarginpar#1}}
+
+
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/markdown.tex b/macros/latex/contrib/easyfloats/doc/preamble/markdown.tex
new file mode 100644
index 0000000000..44662c79aa
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/markdown.tex
@@ -0,0 +1,153 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Allows markdown like syntax:
+% *emph*
+% `code`
+%
+% If `<code>` is used in an argument <code> cannot contain:
+% - comment characters (percent sign)
+% - unbalanced curly braces
+%
+% If `<code>` is used in a context where fragile commands break
+% (e.g. an entry of the table of contents or list of figures):
+% - control sequences and active characters *after* the first token
+% must be preceded by \string or \protect
+%
+% If `<code>` is used in a pdf string (e.g. in \section):
+% - control sequences *after* the first token must be preceded by \cmd
+% - active characters *after* the first token must be preceded by \string
+% - curly braces *after* the first token must be escaped or preceded by \string
+%
+% If you add prefixes like `\string` or `\cmd` in a normal execution context
+% they will (of course) be treated as code to be displayed.
+% Therefore it may be necessary to pass different code for these three cases:
+% \section[\texorpdfstring
+% {`\emph{page\string~42}`}
+% {`\emph\{page\string~42\}`}]
+% {`\emph{page~42}`}
+%
+% Warning: \section uses \write without \immediate.
+% If the definition of ` is different where it is written
+% e.g. if the next page break is inside of a minted environment
+% you will get into trouble.
+%
+% Warning: With * being an active character you cannot just
+% use starred versions of environments.
+% \starred expands to a * with catcode other:
+% \begin{examplecode\starred}
+% <code>
+% \end{examplecode\starred}
+% I am redefining \@ifstar to recognize active * as well.
+% So starred commands can be used usual.
+%
+% Warning: This should be loaded last so that the
+% category changing code is appended to the hook last.
+% Otherwise there is trouble with minted.
+%
+% depends on
+% \LinkKeyword{<keywordtype>}{<keyword>}<formatmacro>{<text>}
+% from preamble/keydoc.tex
+
+\usepackage{etoolbox}
+
+\newcommand{\starred}{*}
+
+\providecommand{\mintinline}[1]{\verb}%}
+
+\makeatletter
+% An alternative version of \@ifstar which also recognizes an active star.
+% I am not changing \@ifstar here because the active * is defined in \AtBeginDocument.
+% So in the preamble \newcommand would check if the next token is an undefined control sequence token.
+% If it was it would be discarded and it would try to define the next token.
+\let\@markdown@original@ifstar=\@ifstar
+\catcode`*=\active
+\def\@markdown@ifstar#1#2{%
+ \@markdown@original@ifstar
+ {#1}%
+ {%
+ \@ifnextchar*%
+ {\@firstoftwo{#1}}%
+ {#2}%
+ }%
+}
+\@makeother*
+
+\protected\def\IfProtectedContextGobble#1{\ifx\@thirdofthree#1\relax\else#1\fi}
+\newcommand\IfUnprotectedContext{%
+ \IfProtectedContextGobble\@thirdofthree
+ \@firstoftwo
+}
+
+\catcode``=\active
+\newcommand\MarkdownVerb{%
+ \begingroup
+ \@examplecode@setcatcodes
+ \catcode\string``=\active
+ \futurelet \@MarkdownVerb@nexttoken \@MarkdownVerb@do
+}
+\long\def\@MarkdownVerb@do#1`{%
+ \IfKeywordUndefined{}{\detokenize{#1}}{%
+ \ifcat \noexpand\@MarkdownVerb@nexttoken a%
+ \xckey`#1`%
+ \else
+ \xc`#1`%
+ \fi
+ }{%
+ \catcode\string` =10
+ \catcode\string`\^^M=9
+ \def\do{\LinkKeyword{}{\detokenize{#1}}\@firstofone\@firstofone}%
+ \scantokens{\appto\do{{#1}}}%
+ \do
+ }%
+ \endgroup
+}
+\def\StringifyMarkdownVerb#1`{\string#1\noexpand`}
+\def\PdfStringifyMarkdownVerb#1#2`{%
+ \ifcat\relax\noexpand#1\relax
+ \cmd#1%
+ \else
+ \string#1%
+ \fi
+ \detokenize{#2}%
+}
+\@makeother`
+
+\write\@auxout{\string\catcode\string\string``=\active}
+
+% \AfterEndPreamble is important when used with minted
+\AfterEndPreamble{%
+ \catcode`*=\active
+ \appto\dospecials{\do\*}%
+ \scantokens{\def\ActiveAsterisc{*}}%
+ \edef\do{\def\expandonce\ActiveAsterisc##1\expandonce\ActiveAsterisc{\noexpand\emph{##1}}}%
+ \do
+ \let\@ifstar=\@markdown@ifstar
+ %
+ \catcode``=\active
+ %% If I add ` to \dospecials \mintinline will change it to catcode other
+ %% therefore not finding the active ` which marks the end resulting in
+ %% ! Paragraph ended before \minted@inline@ii was complete.
+ %% I could change the definition of \mintinline to expect an other `
+ %% but that would fail when using `...` inside of an argument.
+ %% Whether ` is contained in \dospecials or not does not seem to bother \verb.
+ %\appto\dospecials{\do\`}%
+ \scantokens{%
+ \def`{%
+ \texorpdfstring{%
+ \IfUnprotectedContext%
+ {\MarkdownVerb}
+ {\noexpand`\StringifyMarkdownVerb}%
+ }{%
+ \PdfStringifyMarkdownVerb
+ }%
+ }%
+ }%
+}
+
+\makeatother
diff --git a/macros/latex/contrib/easyfloats/doc/preamble/pdfstring.tex b/macros/latex/contrib/easyfloats/doc/preamble/pdfstring.tex
new file mode 100644
index 0000000000..0a94b3d720
--- /dev/null
+++ b/macros/latex/contrib/easyfloats/doc/preamble/pdfstring.tex
@@ -0,0 +1,35 @@
+% !TeX root = ../easyfloats.tex
+
+% Copyright © 2020 E. Zöllner
+% Alternatively to the terms of the LPPL, at your choice,
+% you can redistribute and/or modify this file under the
+% terms of the Do What The Fuck You Want To Public License, Version 2,
+% as published by Sam Hocevar. See http://www.wtfpl.net/about/.
+
+% Redefines \cmd so that it can be used in a pdf string,
+% e.g. in \section{...}.
+% Please note that additionally to the restrictions
+% named in the ltxdoc documentation you cannot use \cmd{\ }.
+% That is a bug in ltxdoc and unrelated to pdf strings.
+%
+% This must be loaded last, after all other modifications
+% to the \cmd macro.
+
+\let\PdfstringOriginalCmd=\cmd
+\renewcommand{\cmd}[1]{%
+ \texorpdfstring
+ {\PdfstringOriginalCmd{#1}}
+ {\expandafter\PdfstringCmd\string#1\relax}%
+}
+
+\def\PdfstringCmd#1#2#3\relax{%
+ \textbackslash
+ \ifnum\noexpand`\\=\noexpand`#2
+ \textbackslash
+ \else\ifnum\noexpand`\%=\noexpand`#2
+ \%%
+ \else
+ #2%
+ \fi\fi
+ #3%
+}