summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/easyfloats
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-12-21 22:19:11 +0000
committerKarl Berry <karl@freefriends.org>2020-12-21 22:19:11 +0000
commit40af42087ad5180e7ef930675b5eefa5e86f1363 (patch)
treebbe03a551197b14a06661a294893ea049e8b4b85 /Master/texmf-dist/source/latex/easyfloats
parent2feb3ea7213bfb38a1b508a11c899cf8b01cb053 (diff)
easyfloats (21dec20)
git-svn-id: svn://tug.org/texlive/trunk@57195 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/easyfloats')
-rw-r--r--Master/texmf-dist/source/latex/easyfloats/easyfloats.dtx1897
-rw-r--r--Master/texmf-dist/source/latex/easyfloats/easyfloats.ins82
2 files changed, 1979 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/easyfloats/easyfloats.dtx b/Master/texmf-dist/source/latex/easyfloats/easyfloats.dtx
new file mode 100644
index 00000000000..eea9932e40c
--- /dev/null
+++ b/Master/texmf-dist/source/latex/easyfloats/easyfloats.dtx
@@ -0,0 +1,1897 @@
+% easyfloats.dtx
+% Copyright 2020 E. Zöllner
+%
+% 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 E. Zöllner.
+%
+% This work consists of the files listed in easyfloats-file-list.txt.
+% The official git repository is https://gitlab.com/erzo/latex-easyfloats
+
+
+% dtx files (documented tex files) allow "to put the user documentation,
+% code documentation and code itself in one place."
+% https://www.texdev.net/2009/10/05/the-dtx-format/
+% see also
+% https://www.texdev.net/2009/10/06/a-model-dtx-file/
+% https://ctan.org/pkg/dtxtut
+%
+% This file is a lot simpler, it contains nothing but the package code with comments.
+% Technically it could be used instead of the sty file.
+% easyfloats.ins reads this file, strips comments and indentation using docstrip
+% and writes the result to the sty file in order to make it faster.
+
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{easyfloats}[2020/12/20 v1.0.0]
+
+
+% ========== options ==========
+
+% load either graphicx or graphbox
+\newif\ifesf@loadgraphics
+% load graphbox
+\newif\ifesf@loadgraphbox
+% load longtable
+\newif\ifesf@loadlongtable
+% load array
+\newif\ifesf@loadarray
+% load booktabs
+\newif\ifesf@loadbooktabs
+% print a warning if figure or table is used directly
+\newif\ifesf@warnstandardfloats
+\esf@warnstandardfloatstrue
+
+\DeclareOption{graphicx}{%
+ \esf@loadgraphicstrue
+ \esf@loadgraphboxfalse
+}
+\DeclareOption{graphbox}{%
+ \esf@loadgraphicstrue
+ \esf@loadgraphboxtrue
+}
+\DeclareOption{nographic}{%
+ \esf@loadgraphicsfalse
+ \esf@loadgraphboxfalse
+}
+
+\DeclareOption{longtable}{%
+ \esf@loadlongtabletrue
+}
+\DeclareOption{nolongtable}{%
+ \esf@loadlongtablefalse
+}
+
+\DeclareOption{booktabs}{%
+ \esf@loadbooktabstrue
+}
+\DeclareOption{nobooktabs}{%
+ \esf@loadbooktabsfalse
+}
+
+\DeclareOption{array}{%
+ \esf@loadarraytrue
+}
+\DeclareOption{noarray}{%
+ \esf@loadarrayfalse
+}
+
+% If I spell this with spaces LaTeX complains:
+% > Unknown option `allowstandardfloats'
+% It seems spaces are ignored by \usepackage
+% but not by \DeclareOption.
+% clsguide says:
+% > Note that the name of an option should contain
+% > only those characters allowed in a ‘LaTeX name’
+% So maybe it's better to not rely on that behaviour.
+\DeclareOption{allowstandardfloats}{%
+ \esf@warnstandardfloatsfalse
+}
+
+%\DeclareOption*{\objectset{\CurrentOption}}
+
+
+\ExecuteOptions{graphicx, array, booktabs}
+
+% \relax is in definition order, starred is in specification order
+\ProcessOptions\relax
+
+
+% ========== required packages ==========
+
+\RequirePackage{etoolbox}
+\RequirePackage{pgfkeys}
+
+% The float package defines the placement option H so that I don't need to
+% provide a separate inline/floating option and deal with spacing and captions
+% of inline objects. I can just use the usual environments like always.
+% It also defines float styles which move the caption to the top or bottom of
+% the object. It makes things easier for me because I can just insert the
+% caption somewhere independent of the object type.
+% I am *not* making use of it's capability to define new float types.
+% Please note that \floatplacement is overridden if the placement option is non-empty.
+\RequirePackage{float}
+
+% By default there is no space between a table and it's caption (at least with
+% the standard document classes). The caption package fixes this.
+% The caption package defines the \phantomcaption command (see object environment).
+% The caption package is required by the subcaption package.
+% It also gives the possibility to customize the layout of captions. But I am
+% leaving it to the user to do this if desired.
+\RequirePackage{caption}
+
+% subobjects
+\RequirePackage{environ}
+
+% "Die Pakete subfigure.sty und subfig.sty werden nicht mehr weiterentwickelt
+% und sind inkompatibel zu einigen aktuelleren Paketen wie hyperref.sty.
+% Als Ersatz bei Kompatibilitätsproblemen empfiehlt sich subcaption.sty."
+% (l2tabu, Version 2.4 vom 3. Februar 2016, Seite 16)
+\RequirePackage{subcaption}
+
+% \includegraphics
+\ifesf@loadgraphics
+ \ifesf@loadgraphbox
+ % extension for graphicx
+ \RequirePackage{graphbox}
+ \else
+ \RequirePackage{graphicx}
+ \fi
+\fi
+
+% Set long tables which are not floating
+% but can span across page breaks.
+% Requires several runs.
+\ifesf@loadlongtable
+ \RequirePackage{longtable}
+\fi
+
+% Additional features in column specification like <, >, !.
+% Changes also the behaviour of rules but that is irrelevant if you use booktabs.
+\ifesf@loadarray
+ \RequirePackage{array}
+\fi
+
+% Macros for formating tables.
+\ifesf@loadbooktabs
+ \RequirePackage{booktabs}
+\fi
+
+
+% ========== init ==========
+
+\newif\ifobject@directkeys
+\object@directkeystrue
+
+\newif\if@inobject
+\newif\if@firstsubobject
+\newif\if@containssubobjects
+
+\floatstyle{plaintop}
+\restylefloat{table}
+\floatstyle{plain}
+\restylefloat{figure}
+
+
+% ========== hooks ==========
+
+\newif\ifobject@isgraphic
+
+\newcommand{\object@hook}{}
+\newcommand{\subobject@hook}{}
+\newcommand{\object@graphic@hook}{}
+
+\newrobustcmd{\AtBeginObject}[1]{\appto\object@hook{#1}}
+\newrobustcmd{\AtBeginSubobject}[1]{\appto\subobject@hook{#1}}
+\newrobustcmd{\AtBeginGraphicObject}[1]{\appto\object@graphic@hook{#1}}
+
+
+% ========== key management ==========
+
+\newcommand{\esf@ifpgfkeyhasvalue}[1]{% #1: key, #2: executed if #1 is set, #3: executed if #1 has not been set
+ % WARNING: Trying to get the value defines the key to \relax if it
+ % was undefined (because of \csname). Setting the key to \relax is
+ % discouraged because it causes inconsistent behaviour [TikZ & PGF
+ % Manual v3.1.5b page 976 \pgfkeysifdefined].
+ % With eTeX: \pgfkeysifdefined will report the key as *defined*.
+ % Without eTeX: \pgfkeysifdefined will report the key as *un*defined.
+ % Therefore don't use this macro with undefined keys. If you do use
+ % it with an undefined key it will be treated as if it has been set [!].
+ \pgfkeysgetvalue{#1}{\esf@tmp@value}%
+ \ifx \pgfkeysnovalue@text \esf@tmp@value
+ \expandafter \@secondoftwo
+ \else
+ \expandafter \@firstoftwo
+ \fi
+}
+
+\newcommand{\esf@ifpgfkeyexists}[3]{%
+ % I cannot use \@firstoftwo and \@secondoftwo because \pgfkeysifdefined
+ % does not close the if statement before expanding the 2nd and 3rd argument
+ \pgfkeysifdefined{#1}
+ {#2}
+ {\pgfkeysifdefined{#1/.@cmd}{#2}{#3}}%
+}
+\newcommand{\esf@ifpgfkeyrequiresvalue}[3]{% #1: key, #2: then block, #3: else block
+ \pgfkeysifdefined{#1/.@def}{%
+ \pgfkeysgetvalue{#1/.@def}{\esf@tmp@value}%
+ \ifx \esf@tmp@value \pgfkeysvaluerequired
+ #2%
+ \else
+ #3%
+ \fi
+ }{%
+ #3%
+ }%
+}
+
+\newcommand{\esf@ifkeyvalkeyexists}[4]{% #1: family, #2: key, #3: then block, #4: else block
+ % \ifcsdef would treat \relax as defined, \ifcsundef does not
+ \ifcsundef{KV@#1@#2}{#4}{#3}%
+}
+\newcommand{\esf@ifkeyvalkeyrequiresvalue}[2]{% #1: family, #2: key, #3: then block, #4: else block
+ % \ifcsdef would treat \relax as defined, \ifcsundef does not
+ \ifcsundef{KV@#1@#2@default}%
+}
+
+\newcommand{\esf@pgfkeyscopyvalue}[2]{% #1: key to be set, #2 key to take the value from
+ % WARNING: the order of arguments is opposite of the shell command cp
+ % because all pgf macros take the key they operate on as first argument.
+ \pgfkeysgetvalue{#2}{\esf@tmp@value}%
+ \pgfkeyslet{#1}{\esf@tmp@value}%
+}
+\newcommand{\esf@pgfkeysvalueappend}[2]{% #1: key to be set, #2 value to be appended
+ \pgfkeysgetvalue{#1}{\esf@tmp@value}%
+ \appto\esf@tmp@value{#2}%
+ \pgfkeyslet{#1}{\esf@tmp@value}%
+}
+
+\pgfqkeys{/handlers}{%
+ % ------- recommended -------
+ .esf@recommended/.code={%
+ \esf@ifpgfkeyhasvalue{\pgfkeyscurrentpath}{%
+ % do nothing
+ }{%
+ \edef\esf@tmp@path{\pgfkeyscurrentpath}%
+ \PackageWarning{easyfloats}{Recommended key '\strippath\esf@tmp@path' not given. #1\ifx\pgfkeysnovalue#1\@empty\else. \fi This warning occured}%
+ }%
+ },
+ %
+ % ------- mandatory -------
+ .esf@mandatory/.code={%
+ \esf@ifpgfkeyhasvalue{\pgfkeyscurrentpath}{%
+ % do nothing
+ }{%
+ \edef\esf@tmp@path{\pgfkeyscurrentpath}%
+ \PackageError{easyfloats}{Mandatory key '\strippath\esf@tmp@path' not given\ifx\pgfkeysnovalue#1\@empty\else. \fi #1}{}%
+ }%
+ },
+ %
+ %
+ % ------- save unknown -------
+ % I can't use /pgf/keyfilters/defined with /pgf/key filter handlers/append filtered to
+ % because that appends full keys which are incompatible with keyval.
+ .esf@exec on unknown/.code={% #1: control sequence taking two args: key and value
+ \pgfkeysalso{\pgfkeyscurrentpath/.unknown/.code=% ##1: value
+ #1{\pgfkeyscurrentname}{##1}%
+ }%
+ },
+ %
+ % ------- also from -------
+ .esf@also from/.code={% #1: expandable control sequence containing options
+ \pgfkeysalsofrom{#1}%
+ },
+ %
+ % ------- debugging -------
+ .show boolean/.code={%
+ \begingroup
+ \renewcommand\pgfkeys@handle@boolean[2]{% ##1: if name, ##2: value
+ \expandafter \show \csname if##1\endcsname
+ }%
+ \edef\esf@tmp@path{\pgfkeyscurrentpath}%
+ \pgfkeysalso{\esf@tmp@path}%
+ \endgroup
+ },
+ .show boolean/.value forbidden,
+}
+
+\newcommand{\AppendToOptionsList}[3]{% #1: macro to append to, #2: key, #3: value
+ \ifdefvoid#1%
+ {}%
+ {\appto#1{, }}%
+ \eappto#1{#2}%
+ \ifx \pgfkeysnovalue #3\relax
+ % do nothing
+ \else
+ \appto#1{={#3}}%
+ \fi
+}
+
+\newcommand{\strippath}[1]{%
+ \expandafter\strippath@do#1/\pgfeov
+}
+\def\strippath@do#1/#2\pgfeov{%
+ \if\relax\detokenize{#2}\relax
+ #1%
+ \else
+ \strippath@do#2\pgfeov
+ \fi
+}
+
+
+% ========== other helper ==========
+
+\newcommand{\IfEnvironmentExistsOrIsEmpty}[1]{% #1: environment name, #2: then block, #3: else block
+ \ifstrempty{#1}{%
+ \let\IfEnvironmentExistsOrIsEmpty@do=\@firstoftwo
+ }{\IfEnvironmentExists{#1}{%
+ \let\IfEnvironmentExistsOrIsEmpty@do=\@firstoftwo
+ }{%
+ \let\IfEnvironmentExistsOrIsEmpty@do=\@secondoftwo
+ }}%
+ \IfEnvironmentExistsOrIsEmpty@do
+}
+
+\newcommand{\IfEnvironmentExists}[3]{% #1: environment name, #2: then block, #3: else block
+ \ifcsmacro{#1}{%
+ % I am not checking the existence of end#1 because for tabularx that is \relax.
+ #2%
+ }{%
+ #3%
+ }%
+}
+
+
+% \patchcmd replaces the first occurence only.
+% therefore I am recursing as long as patching was successful
+% to make sure that each occurrence was replaced.
+% it is important to replace with \textunderscore instead of \_
+% because otherwise it would replace \_ by \\_ and loop infinitely.
+\newcommand{\PatchUnderscore}[1]{% #1: macro
+ \patchcmd{#1}
+ {_}{\textunderscore}
+ {\PatchUnderscore#1}{}%
+}
+
+
+% ========== object ==========
+
+\newif\ifobject@warnotherenv
+\newif\ifobject@warnnolabel
+\newif\ifobject@warnnocaption
+\newif\ifobject@showenv
+
+% ---------- set object options ----------
+
+\newrobustcmd{\objectset}{% #1: options
+ \@ifnextchar [%]
+ \objectset@appendtostyles
+ \objectset@direct
+}
+
+\newcommand{\objectset@direct}{% #1: options
+ \pgfqkeys{/object}%
+}
+
+\newcommand{\GobbleLeadingSpaceIn}[1]{\edef#1{\expandafter\@firstofone#1}}
+
+\def\objectset@appendtostyles[#1]#2{% #1: style #2: options
+ \pgfkeyssetvalue{/object.check/env}{}%
+ \pgfqkeys{/object.check}{%
+ .esf@exec on unknown=\AppendOptionToObjectStyleGroups{#1},
+ #2%
+ }%
+}
+
+% ---------- check object options ----------
+
+\newcommand{\CheckObjectOption}[2]{% #1: key, #2: value, #3: executed if valid
+ % if #3 is *not* executed an error message is printed
+ %
+ % It is important to reset it at the beginning
+ % because the \Check* macros do not expand any
+ % of the two arguments if they throw an error.
+ \let\CheckObjectOption@handleArg=\@gobble
+ \esf@ifpgfkeyexists{/object/#1}{%
+ \esf@ifpgfkeyrequiresvalue{/object/#1}{%
+ \ifx \pgfkeysnovalue #2\relax
+ \PackageError{easyfloats}{The key '#1' requires a value. I am going to ignore this key}{}%
+ \else
+ \let\CheckObjectOption@handleArg=\@firstofone
+ \fi
+ }{%
+ \let\CheckObjectOption@handleArg=\@firstofone
+ }%
+ }{\CheckObjectGraphicOption{#1}{#2}{%
+ \let\CheckObjectOption@handleArg=\@firstofone
+ }{\CheckObjectEnvArgs{#1}{#2}{%
+ \let\CheckObjectOption@handleArg=\@firstofone
+ }{%
+ \PackageError{easyfloats}{I do not know the key '#1' and I am going to ignore it. Perhaps you misspelled it}{}%
+ }}}%
+ \CheckObjectOption@handleArg
+}
+
+
+% ---------- available object options ----------
+
+\pgfqkeys{/object}{%
+ %
+ % ------- mandatory -------
+ %
+ % The environment to use (figure|table)
+ % An empty value is allowed for longtable
+ % but that is intentionally left undocumented.
+ type/.initial,
+ type/.value required,
+ type/.code=\@ifundefined{fps@#1}
+ {\PackageError{easyfloats}{Invalid value for key 'type': '#1'. I am going to ignore this option}{}}
+ {\pgfkeyssetvalue{/object/type}{#1}},
+ %
+ % Where to place the caption, see float package (plain|plaintop|ruled|boxed)
+ % If empty do *not* perform a restyle.
+ % This is ignored if type is empty.
+ float style/.initial=,
+ float style/.value required,
+ %
+ %
+ % ------- recommended -------
+ %
+ % The caption displayed above or below the content (depending on the float style).
+ % There is *no* dot added automatically behind it.
+ caption/.initial,
+ caption/.value required,
+ caption/.prefix code={%
+ \esf@ifpgfkeyhasvalue{/object/caption}{%
+ \PackageWarning{easyfloats}{Overwriting existing value for caption with "#1"}%
+ }{%
+ % ok
+ }%
+ },
+ %
+ % A label which can be referenced by e.g. \ref{label} or \refpage{label}
+ label/.initial,
+ label/.value required,
+ label/.prefix code={%
+ \esf@ifpgfkeyhasvalue{/object/label}{%
+ \PackageWarning{easyfloats}{Overwriting existing value for label with "#1"}%
+ }{%
+ % ok
+ }%
+ },
+ %
+ %
+ % ------- optional -------
+ %
+ % Where to put the float on the page ([htbp]+ | H | <empty>)
+ % (empty means to *not* pass the optional placement argument to the foating environment)
+ % This is more powerful than \floatplacement because it allows H.
+ placement/.initial=,
+ placement/.value required,
+ %
+ % The caption used in the list of figures/list of tables
+ list caption/.initial,
+ list caption/.value required,
+ %
+ % An addition to the caption (at the object only, not in a list)
+ details/.initial=,
+ details/.value required,
+ %
+ details sep/.initial=.\space,
+ details sep/.value required,
+ %
+ % An additional label which can be used synonymously to label.
+ % If this key is given several times, only the last one will have an effect.
+ add label/.initial,
+ add label/.value required,
+ %
+ % TeX code which is inserted at the beginning of the type environment
+ align/.initial=\centering,
+ align/.value required,
+ %
+ % TeX code which is inserted at the beginning of the type environment (before align)
+ exec/.initial=,
+ exec/.value required,
+ exec +/.code=\esf@pgfkeysvalueappend{/object/exec}{#1},
+ exec +/.value required,
+ exec+/.forward to=/object/exec +,
+ exec+/.value required,
+ %
+ % An additional inner environment to wrap the content in like tabular, tabularx, tikzpicture
+ env/.code=\IfEnvironmentExistsOrIsEmpty{#1}
+ {\pgfkeyssetvalue{/object/env}{#1}}%
+ {\PackageError{easyfloats}{Environment #1 which you passed to the key 'env' does not exist}{}},
+ env/.value required,
+ env=,
+ %
+ % Specify that this object contains subobjects.
+ % This means that if env has a non-empty value
+ % this value is used for subobject env
+ % and env is set to an empty value.
+ sub/.forward to=/object/contains subobjects,
+ contains subobjects/.is if = @containssubobjects,
+ %
+ %
+ % ------- tables -------
+ % first head and last foot are optional but if they are given they have priority.
+ % head and foot always need to have a value even if it's just empty.
+ %
+ first head/.initial,
+ first head/.value required,
+ %
+ head/.initial=,
+ head/.value required,
+ %
+ foot/.initial=,
+ foot/.value required,
+ %
+ last foot/.initial,
+ last foot/.value required,
+ %
+ table head style/.code=\pgfkeysdef{/object/table head}{\pgfqkeys{/object}{#1}},
+ table head style/.value required,
+ table head style={%
+ first head =
+ \toprule
+ #1 \\
+ \midrule,
+ head =
+ #1 \\
+ \midrule,
+ foot =
+ \midrule
+ \ifx\object@tableBreakText\@empty
+ \else
+ \multicolumn{\the\LT@cols}{r@\relax}{\object@tableBreakText}%
+ \fi,
+ last foot =
+ \bottomrule,
+ },
+ %
+ % text displayed in the non-last foot of a table
+ table break text/.code=\def\object@tableBreakText{#1},
+ table break text/.value required,
+ table break text = (to be continued),
+ %
+ %
+ % ------- warnings -------
+ %
+ warn no caption/.is if=object@warnnocaption,
+ warn no caption=true,
+ %
+ warn no label/.is if=object@warnnolabel,
+ warn no label=true,
+ %
+ warn other env/.is if=object@warnotherenv,
+ warn other env=false,
+ %
+ %
+ % ------- debugging -------
+ %
+ show env args/.is if=object@showenv,
+ show env args=false,
+ %
+ %
+ % ------- subobject -------
+ % .value required is code duplication but
+ % it is necessary for \esf@ifpgfkeyrequiresvalue.
+ % It also changes the error message to report
+ % this key instead of the linked key.
+ %
+ subobject linewidth/.forward to=/subobject/linewidth,
+ subobject linewidth/.value required,
+ subobject env/.forward to=/subobject/env,
+ subobject env/.value required,
+ %
+ subcaptionbox/.forward to=/subobject/subcaptionbox,
+ subcaptionbox/.value forbidden,
+ subpage/.forward to=/subobject/subpage,
+ subpage/.value forbidden,
+ %
+ subcaptionbox inner pos/.forward to=/subobject/subcaptionbox inner pos,
+ subcaptionbox inner pos/.value required,
+ %
+ subpage inner pos/.forward to=/subobject/subpage inner pos,
+ subpage inner pos/.value required,
+ subpage height/.forward to=/subobject/subpage height,
+ subpage height/.value required,
+ subpage outer pos/.forward to=/subobject/subpage outer pos,
+ subpage outer pos/.value required,
+ subpage align/.forward to=/subobject/subpage align,
+ subpage align/.value required,
+ %
+ subobject sep/.forward to=/subobject/sep,
+ subobject sep/.value required,
+ %
+ subobject hor/.forward to=/subobject/hor,
+ %subobject hor/ value is allowed but not necessary
+ subobject hor sep/.forward to=/subobject/hor sep,
+ subobject hor sep/.value required,
+ subobject hor sep+/.forward to=/subobject/hor sep+,
+ subobject hor sep+/.value required,
+ subobject hor sep +/.forward to=/subobject/hor sep +,
+ subobject hor sep +/.value required,
+ %
+ subobject ver/.forward to=/subobject/ver,
+ %subobject ver/ value is allowed but not necessary
+ subobject ver sep/.forward to=/subobject/ver sep,
+ subobject ver sep/.value required,
+ subobject ver sep+/.forward to=/subobject/ver sep+,
+ subobject ver sep+/.value required,
+ subobject ver sep +/.forward to=/subobject/ver sep +,
+ subobject ver sep +/.value required,
+ %
+ subobject exec/.forward to=/subobject/exec,
+ subobject exec/.value required,
+ subobject exec+/.forward to=/subobject/exec+,
+ subobject exec+/.value required,
+ subobject exec +/.forward to=/subobject/exec +,
+ subobject exec +/.value required,
+ %
+ subobject warn no caption/.forward to=/subobject/warn no caption,
+ %value is allowed but not necessary
+ subobject warn no label/.forward to=/subobject/warn no label,
+ %value is allowed but not necessary
+ %
+ %
+ % ------- unknown handler / key patterns -------
+ %
+ % Two key patterns are defined to automatically pass arguments to the environments specified by the env option if the environment name matches.
+ % `<envname> arg` is for a single mandatory (undelimited) argument. It is wrapped in braces.
+ % `<envname> args` is not wrapped in braces and can be used for several arguments or an optional argument.
+ % It cannot be used for a single mandatory argument because \pgfkeys strips several levels of braces.
+ .unknown/.code={%
+ \ObjectProcessKeyPattern{\pgfkeyscurrentname}{#1}{%
+ \pgfkeysgetvalue{/object/.really unknown/.@cmd}{\esf@tmp@err}%
+ \esf@tmp@err#1\pgfeov
+ }%
+ },
+ % Setting an unknown key handler shall not override env args but set an additional unknown handler.
+ .unknown/.code/.code={%
+ \pgfkeysdef{/object/.really unknown}{#1}%
+ },
+ .really unknown/.code={%
+ \edef\do{\noexpand\pgfkeys{/errors/unknown key={\pgfkeyscurrentkey}{\unexpanded{#1}}}}%
+ \do
+ },
+}
+
+\pgfqkeys{/object.check}{%
+ env/.initial=,
+ env/.code={%
+ \ifx \pgfkeysnovalue #1\relax
+ \PackageError{easyfloats}{The key 'env' requires a value. I am going to ignore this key}{}%
+ \else
+ \IfEnvironmentExistsOrIsEmpty{#1}{%
+ % set env so that I can use the value to check args
+ \pgfkeyssetvalue{/object.check/env}{#1}%
+ % call the unknown handler which appends it to the style
+ % unlike '/errors/unknown key' '.unknown' does not take the key as argument
+ % but it may require \pgfkeyscurrentpath and \pgfkeyscurrentname to be set
+ \pgfkeys@split@path
+ \pgfkeysvalueof{\pgfkeyscurrentpath/.unknown/.@cmd}#1\pgfeov
+ }{%
+ \PackageError{easyfloats}{Environment #1 which you passed to the key 'env' does not exist}{}%
+ }%
+ \fi
+ },
+ type/.code={%
+ % set type so that I can use the value in \NewObjectStyleGroup
+ \pgfkeyssetvalue{/object.check/type}{#1}%
+ % call the unknown handler which appends it to the style
+ % unlike '/errors/unknown key' '.unknown' does not take the key as argument
+ % but it may require \pgfkeyscurrentpath and \pgfkeyscurrentname to be set
+ \pgfkeys@split@path
+ % Without the braces I got "Undefined control sequence. [...] \pgfeov"
+ % \pgfkeys strips several levels of braces around an argument.
+ % (I have already experienced that while experimenting with <env> args.
+ % That is the reason why I defined two separate keys arg and args.)
+ % I am assuming that because of that the \pgfeov ended the argument of some
+ % pgfkeys internal macro too early causing undefined behavior.
+ % I am preventing this from happening by hiding \pgfeov inside of braces
+ % which are inside of the argument so they won't get stripped.
+ % I put \@firstofone in front of them so that they do not function as a group.
+ \@firstofone{\pgfkeysvalueof{\pgfkeyscurrentpath/.unknown/.@cmd}#1\pgfeov}%
+ },
+}
+
+% ---------- process key patterns ----------
+
+\newcommand{\ObjectProcessKeyPattern}[2]{% #1: key, #2: value, #3: else
+ \expandafter\ObjectProcessKeyPattern@expandedkey\expandafter{#1}{#2}%
+}
+
+\newcommand{\ObjectProcessKeyPattern@expandedkey}[2]{% #1: key, #2: value, #3: else
+ \ObjectProcessGraphicOption@expandedkey{#1}{#2}{%
+ \@gobble
+ }{%
+ \ObjectProcessArgs@expandedkey{#1}{#2}\relax
+ }%
+}
+
+% ---------- process graphic options ----------
+
+\ifesf@loadgraphics
+
+% do not confuse this with \CheckGraphicobjectOption
+\newcommand{\CheckObjectGraphicOption}[2]{% #1: key, #2: value
+ % #3: executed if valid, #4: executed if *not* a graphic option
+ % Please note that if the option looks like a graphic option
+ % but is not valid neither #3 nor #4 is executed.
+ % Instead an appropriate error message is printed.
+ \begingroup
+ \let\ObjectCheckGraphicOption@aftergroup=\@gobbletwo
+ \renewcommand{\AppendToOptionsList}[3]{%
+ \let\ObjectCheckGraphicOption@aftergroup=\@firstoftwo
+ }%
+ \ObjectProcessGraphicOption{#1}{#2}{%
+ \let\ObjectCheckGraphicOption@aftergroup=\@secondoftwo
+ }%
+ \expandafter
+ \endgroup
+ \ObjectCheckGraphicOption@aftergroup
+}
+
+\newcommand{\ObjectProcessGraphicOption}[2]{% #1: key, #2: value
+ % #3: executed if *not* a graphic option
+ \expandafter\ObjectProcessGraphicOption@expandedkey\expandafter{#1}{#2}\relax
+}
+\newcommand{\ObjectProcessGraphicOption@expandedkey}[2]{% #1: key, #2: value
+ % #3: executed if graphic option, #4: executed if *not* a graphic option
+ \ObjectProcessGraphicOption@checkoption#1graphic \pgfeov{#2}%
+}
+\long\def\ObjectProcessGraphicOption@checkoption#1graphic #2\pgfeov#3{% #1: empty if graphic option, #2: key, #3: value
+ % #4: executed if graphic option, #5: executed if *not* a graphic option
+ \def\esf@tmp@arg{#1}%
+ \ifx \esf@tmp@arg \@empty
+ \edef\esf@opgoco@key{\StripGraphicSpace#2\pgfeov}%
+ \CheckGraphicobjectOption{\esf@opgoco@key}{#3}{%
+ \AppendGraphicobjectOption{\esf@opgoco@key}{#3}%
+ }%
+ \expandafter \@firstoftwo
+ \else
+ \expandafter \@secondoftwo
+ \fi
+}
+
+\def\StripGraphicSpace#1graphic \pgfeov{#1}
+
+\else %\ifesf@loadgraphics
+
+\newcommand{\CheckObjectGraphicOption}[2]{% #1: key, #2: value
+ % #3: executed if valid, #4: executed if *not* a graphic option
+ \@secondoftwo
+}
+
+\newcommand{\ObjectProcessGraphicOption@expandedkey}[2]{% #1: key, #2: value
+ % #3: executed if graphic option, #4: executed if *not* a graphic option
+ \@secondoftwo
+}
+
+\fi %\ifesf@loadgraphics
+
+% ---------- process env args ----------
+
+\newcommand{\@object@envkey}{/object/env}
+\newcommand{\CheckObjectEnvArgs}[2]{% #1: key, #2: value
+ % #3: executed if valid, #4: executed if *not* an <env> arg
+ % Please note that if the option looks like an <env> arg
+ % but is not valid neither #3 nor #4 is executed.
+ % Instead an appropriate error message is printed.
+ \begingroup
+ \edef\ObjectCheckArgs@key{#1}%
+ \let\ObjectCheckArgs@aftergroup=\@gobbletwo
+ \pgfkeysgetvalue{/object.check/env}{\esf@tmp@env}%
+ \pgfkeys{\@object@envkey/.expand once=\esf@tmp@env}%
+ \renewcommand{\ObjectDefineEnvargs}[2]{% ##1: env name, ##2: arguments
+ \let\ObjectCheckArgs@aftergroup=\@firstoftwo
+ }%
+ \ObjectProcessArgs{\ObjectCheckArgs@key}{#2}{%
+ \let\ObjectCheckArgs@aftergroup=\@secondoftwo
+ }%
+ \expandafter
+ \endgroup
+ \ObjectCheckArgs@aftergroup
+}
+
+
+\newcommand{\ObjectProcessArgs}[2]{% #1: key, #2: value, #3: else
+ \expandafter\ObjectProcessArgs@expandedkey\expandafter{#1}{#2}\relax
+}
+
+\newcommand{\ObjectProcessArgs@expandedkey}[2]{% #1: key, #2: value, #3: then, #4: else
+ \IfEndsOnSpacePlus{#1}{%
+ \let\ObjectProcessArgs@csdef=\csappto
+ \expandafter\ObjectProcessArgs@checkArgs\expandafter{\StripSpacePlus#1\pgfeov}{#2}%
+ }{\IfEndsOnPlus{#1}{%
+ \let\ObjectProcessArgs@csdef=\csappto
+ \expandafter\ObjectProcessArgs@checkArgs\expandafter{\StripPlus#1\pgfeov}{#2}%
+ }{%
+ \let\ObjectProcessArgs@csdef=\csdef
+ \ObjectProcessArgs@checkArgs{#1}{#2}%
+ }}%
+}
+
+\newrobustcmd{\IfEndsOn}[2]{% #1: end character, #2: text
+ \def\IfEndsOn@do##1#1##2\pgfeov{%
+ \ifstrequal{##2}{}{%
+ \let\do=\@secondoftwo
+ }{\ifstrequal{##2}{#1}{%
+ \let\do=\@firstoftwo
+ }{%
+ \def\do{\IfEndsOn@do##2\pgfeov}%
+ }}%
+ \do
+ }%
+ \IfEndsOn@do#2#1\pgfeov
+}
+\newcommand{\IfEndsOnPlus}{\IfEndsOn+}
+\newcommand{\IfEndsOnSpacePlus}{\IfEndsOn{ +}}
+
+\def\StripSpacePlus#1 +\pgfeov{#1}
+\def\StripPlus#1+\pgfeov{#1}
+
+
+\newcommand{\ObjectProcessArgs@checkArgs}[2]{% #1: key, #2: value, #3: then, #4: else
+ \ObjectProcessArgs@do#1 args\pgfeov{#2}%
+}
+\long\def\ObjectProcessArgs@do#1 arg#2\pgfeov#3{% #1: env name, #2: test value, #3: arguments, #4: then, #5: else
+ \let\ObjectProcessArgs@do@after=\@firstoftwo
+ \ifstrequal{#2}{ args}{%
+ \ObjectDefineEnvargsCheckName{#1}{{#3}}%
+ }{\ifstrequal{#2}{s args}{%
+ \ObjectDefineEnvargsCheckName{#1}{#3}%
+ }{\ifstrequal{#2}{s}{%
+ \ifstrequal{#1}{arg}{%
+ \ObjectDefineEnvargsAuto{{#3}}%
+ }{\ifstrequal{#1}{args}{%
+ \ObjectDefineEnvargsAuto{#3}%
+ }{%
+ \let\ObjectProcessArgs@do@after=\@secondoftwo
+ }}%
+ }{%
+ \let\ObjectProcessArgs@do@after=\@secondoftwo
+ }}}%
+ \ObjectProcessArgs@do@after
+}
+\newcommand{\ObjectDefineEnvargsCheckName}[2]{% #1: env name, #2: arguments
+ \ifobject@directkeys
+ \pgfkeysgetvalue{\@object@envkey}{\esf@tmp@env}%
+ \ifdefvoid{\esf@tmp@env}{%
+ }{\ifdefstring{\esf@tmp@env}{#1}{%
+ }{%
+ \ifobject@warnotherenv
+ \PackageWarning{easyfloats}{Defining 'arg(s)' for #1 but 'env=\esf@tmp@env'}%
+ \fi
+ }}%
+ \fi
+ \IfEnvironmentExists{#1}
+ {\ObjectDefineEnvargs{#1}{#2}}
+ {\PackageError{easyfloats}{Environment #1 for which you set 'arg(s)' does not exist}{}}%
+}
+\newcommand{\ObjectDefineEnvargsAuto}[1]{% #1: arguments
+ \pgfkeysgetvalue{\@object@envkey}{\esf@tmp@env}%
+ \ifx \esf@tmp@env \@empty
+ \PackageError{easyfloats}{'env' for 'arg(s)' is not defined}{}%
+ \else
+ \ObjectDefineEnvargs{\esf@tmp@env}{#1}%
+ \fi
+}
+\newcommand{\ObjectDefineEnvargs}[2]{% #1: env name, #2: arguments
+ \ObjectProcessArgs@csdef{object@#1 env@args}{#2}%
+}
+
+
+\newcommand{\ObjectAppendEnvargs}[1]{% #1: macro
+ \ifcsname object@\pgfkeysvalueof{\@object@envkey} env@args\endcsname
+ \eappto#1{\csexpandonce{object@\pgfkeysvalueof{\@object@envkey} env@args}}%
+ \fi
+}
+
+
+% ---------- object environment ----------
+
+\newcommand{\object@head}{}
+\newcommand{\object@foot}{}
+\newcommand{\object@restorestandardfloats}{}
+
+\newcommand{\object@label}[1]{%
+ \pgfkeys{/object/label={#1}}%
+}%
+\newcommand{\object@caption}[2][\pgfkeysnovalue]{%
+ \pgfkeys{/object/caption={#2}}%
+ \ifx \pgfkeysnovalue #1\relax
+ \pgfkeys{/object/list caption={#2}}%
+ \else
+ \pgfkeys{/object/list caption={#1}}%
+ \fi
+}
+\newcommand{\object@longtable@label}[1]{%
+ \ObjectDefineEnvargs{longtable}{\label{#1}}%
+}%
+\newcommand{\object@longtable@caption}[2][\pgfkeysnovalue]{%
+ \ifx \pgfkeysnovalue #1\relax
+ \ObjectDefineEnvargs{longtable}{\caption{#2}}%
+ \else
+ \ObjectDefineEnvargs{longtable}{\caption[#1]{#2}}%
+ \fi
+ \def\object@longtable@caption@sep{\ObjectDefineEnvargs{longtable}{\\}}%
+}
+
+\newenvironment{object}[1]{% #1: options
+ \if@inobject
+ \PackageError{easyfloats}{object environment may not be nested}{Did you mean to use the subobject environment instead?}%
+ \fi
+ \@inobjecttrue
+ %
+ \object@restorestandardfloats
+ %
+ \object@hook
+ \ifobject@isgraphic
+ \object@graphic@hook
+ \global\object@isgraphicfalse
+ \fi
+ %
+ % ---------- options ---------
+ %
+ \pgfqkeys{/object}{%
+ #1,
+ %
+ % ------- mandatory -------
+ type/.esf@mandatory=It should be the name of a floating environment like figure or table,
+ float style/.esf@mandatory={It should be one of plain, plaintop, ruled or boxed. See float package},
+ env/.esf@mandatory=It should be the name of an environment like tabular or empty,
+ }%
+ %
+ % ------- contains subobjects -------
+ \if@containssubobjects
+ \pgfkeysgetvalue{/object/env}{\esf@tmp@env}%
+ \ifx \esf@tmp@env \@empty
+ \else
+ \pgfkeys{/subobject/env/.expand once=\esf@tmp@env}%
+ \pgfkeyssetvalue{/object/env}{}%
+ \fi
+ \fi
+ %
+ % ---------- prepare ---------
+ %
+ \pgfkeysgetvalue{/object/env}{\esf@tmp@env}%
+ \ifdefstring\esf@tmp@env{longtable}{%
+ \object@longtable@prepare
+ }{%
+ \esf@ifpgfkeyhasvalue{/object/first head}{%
+ \pgfkeysgetvalue{/object/first head}{\object@head}%
+ }{%
+ \pgfkeysgetvalue{/object/head}{\object@head}%
+ }%
+ \esf@ifpgfkeyhasvalue{/object/last foot}{%
+ \pgfkeysgetvalue{/object/last foot}{\object@foot}%
+ }{%
+ \pgfkeysgetvalue{/object/foot}{\object@foot}%
+ }%
+ }%
+ %
+ \pgfkeysgetvalue{/object/type}{\esf@tmp@type}%
+ \ifx\esf@tmp@type\@empty
+ \let\object@floatenv@begin=\relax
+ \let\object@floatenv@end=\relax
+ \else
+ \pgfkeysgetvalue{/object/float style}{\esf@tmp@floatstyle}%
+ \ifx \esf@tmp@floatstyle \@empty
+ \else
+ \floatstyle{\esf@tmp@floatstyle}%
+ \restylefloat{\esf@tmp@type}%
+ \fi
+ \edef\object@floatenv@begin{\expandonce{\csname\esf@tmp@type\endcsname}}%
+ \edef\object@floatenv@end{\expandonce{\csname end\esf@tmp@type\endcsname}}%
+ \pgfkeysgetvalue{/object/placement}{\esf@tmp@placement}%
+ \ifx \esf@tmp@placement \@empty
+ % do nothing
+ \else
+ \eappto\object@floatenv@begin{[\esf@tmp@placement]}%
+ \fi
+ \fi
+ %
+ \pgfkeysgetvalue{/object/details}{\object@details}%
+ \ifx \object@details \@empty
+ % do nothing
+ \else
+ \preto\object@details{\pgfkeysvalueof{/object/details sep}}%
+ \fi
+ %
+ \pgfkeysgetvalue{/object/env}{\esf@tmp@env}%
+ \ifx \esf@tmp@env \@empty
+ % if you change this remember to update \object@lookahead@beforesubobject
+ \def\object@innerenv@begin{\object@head\ignorespaces}%
+ \def\object@innerenv@end{\unskip\object@foot}%
+ \else
+ \edef\object@innerenv@begin{\expandonce{\csname\esf@tmp@env\endcsname}}%
+ \edef\object@innerenv@end{\expandonce{\csname end\esf@tmp@env\endcsname}}%
+ \ObjectAppendEnvargs{\object@innerenv@begin}%
+ \eappto\object@innerenv@begin{\expandonce{\object@head}}%
+ \epreto\object@innerenv@end{\expandonce{\object@foot}}%
+ \let\object@lookahead@begin=\object@innerenv@begin
+ \ifobject@showenv
+ \show\object@innerenv@begin
+ \fi
+ \let\object@innerenv@begin=\object@lookahead
+ \fi
+ %
+ \global \@firstsubobjecttrue
+ %
+ % ---------- execute ---------
+ %
+ \object@floatenv@begin
+ \let\esf@original@label=\label
+ \let\esf@original@caption=\caption
+ \let\label=\object@label
+ \let\caption=\object@caption
+ \pgfkeysvalueof{/object/exec}%
+ \pgfkeysvalueof{/object/align}%
+ \object@innerenv@begin
+}{%
+ \object@innerenv@end
+ \if@containssubobjects
+ \if@firstsubobject
+ \PackageWarning{easyfloats}{'contains subobjects' is true but the object does not contain any subobjects.}%
+ \fi
+ \fi
+ \let\label=\esf@original@label
+ \let\caption=\esf@original@caption
+ \object@processCaptionAndLabel
+ \object@floatenv@end
+}
+
+\newcommand{\object@processCaptionAndLabel}{%
+ % position of caption (above/below) is handled by float package (see float style)
+ \esf@ifpgfkeyhasvalue{/object/caption}{%
+ \esf@ifpgfkeyhasvalue{/object/list caption}%
+ {\pgfkeysgetvalue{/object/list caption}{\esf@tmp@caption@short}}%
+ {\pgfkeysgetvalue{/object/caption}{\esf@tmp@caption@short}}%
+ \caption[\esf@tmp@caption@short]{\pgfkeysvalueof{/object/caption}\object@details}%
+ }{%
+ \ifobject@warnnocaption
+ \PackageWarning{easyfloats}{%
+ No caption given.
+ This object will not show up in the list of figures/tables/whatsoever.
+ If captions for subfigures are given they will be placed incorrectly in the list of figures.
+ If you are using hyperref links to this figure may turn out wrong.
+ This warning occured%
+ }%
+ \fi
+ % Generate an anchor for a \label.
+ % \phantomcaption is defined in the caption-package but
+ % documented in subcaption for the subfigure environment.
+ % It appears that here (without a subfigure but within a figure)
+ % references are output correctly but links created by hyperref
+ % which should be pointing to this object point to the previous caption.
+ \phantomcaption
+ }%
+ % ------- label -------
+ \esf@ifpgfkeyhasvalue{/object/label}{%
+ \label{\pgfkeysvalueof{/object/label}}%
+ }{%
+ \ifobject@warnnolabel
+ \PackageWarning{easyfloats}{%
+ No label given.
+ Without a label you cannot reference this object.
+ This warning occured%
+ }%
+ \fi
+ }%
+ \esf@ifpgfkeyhasvalue{/object/add label}%
+ {\label{\pgfkeysvalueof{/object/add label}}}%
+ {}%
+}
+
+\newcommand{\object@longtable@prepare}{%
+ \pgfkeyssetvalue{/object/type}{}%
+ \pgfkeyssetvalue{/object/align}{}%
+ \let\object@label=\label
+ \let\object@caption=\caption
+ \let\ObjectProcessArgs@csdef=\csappto
+ %
+ \let\esf@original@label=\label
+ \let\esf@original@caption=\caption
+ \let\label=\object@longtable@label
+ \let\caption=\object@longtable@caption
+ \let\object@longtable@caption@sep=\relax
+ % it seems possible to have a label without a caption in a longtable
+ % which actually makes sense because \caption may appear several times
+ % so it makes sense to increase the counter somewhere else.
+ \let\phantomcaption=\relax
+ \object@processCaptionAndLabel
+ \let\object@processCaptionAndLabel=\relax
+ \object@longtable@caption@sep
+ \let\label=\esf@original@label
+ \let\caption=\esf@original@caption
+ %
+ \esf@ifpgfkeyhasvalue{/object/first head}{%
+ \ObjectDefineEnvargs{longtable}{\pgfkeysvalueof{/object/first head}}%
+ }{%
+ \ObjectDefineEnvargs{longtable}{\pgfkeysvalueof{/object/head}}%
+ }%
+ \ObjectDefineEnvargs{longtable}{%
+ \endfirsthead
+ \pgfkeysvalueof{/object/head}%
+ \endhead
+ \pgfkeysvalueof{/object/foot}%
+ \endfoot
+ }%
+ \esf@ifpgfkeyhasvalue{/object/last foot}{%
+ \ObjectDefineEnvargs{longtable}{\pgfkeysvalueof{/object/last foot}}%
+ }{%
+ \ObjectDefineEnvargs{longtable}{\pgfkeysvalueof{/object/foot}}%
+ }%
+ \ObjectDefineEnvargs{longtable}{%
+ \endlastfoot
+ }%
+}
+
+
+% ---------- lookahead for subobjects ----------
+
+\newcommand{\object@lookahead@nosubobject}{%
+ \object@lookahead@begin
+}
+\newcommand{\object@lookahead@beforesubobject}{%
+ \PackageWarning{easyfloats}{It seems you have forgotten to specify 'contains subobjects'. I am using the value of 'env' for the subobjects instead of for \@currenvir.}%
+ \pgfkeysgetvalue{/object/env}{\esf@tmp@env}%
+ \pgfkeys{/subobject/env/.expand once=\esf@tmp@env}%
+ \pgfkeyssetvalue{/object/env}{}%
+ \let\object@innerenv@end=\unskip
+ %\ignorespaces unnecessary because I just checked
+ %that the next token is the start of a subobject
+}
+
+\newcommand{\object@lookahead}{%
+ \futurelet \next \object@lookahead@checknext
+}
+\newcommand{\object@lookahead@checknext}{%
+ \ifx \next \@implicitspace
+ \let\object@lookahead@gobble=\@gobblespace
+ \let\object@lookahead@do=\object@lookahead
+ \else\ifx \next \par
+ \let\object@lookahead@gobble=\@gobble
+ \let\object@lookahead@do=\object@lookahead
+ \else\ifx \next \begin
+ \let\object@lookahead@gobble=\@empty
+ \let\object@lookahead@do=\object@lookahead@checkbegin
+ \else\ifx \next \includegraphicsubobject
+ \let\object@lookahead@gobble=\@empty
+ \let\object@lookahead@do=\object@lookahead@beforesubobject
+ \else
+ \let\object@lookahead@gobble=\@empty
+ \let\object@lookahead@do=\object@lookahead@nosubobject
+ \fi \fi \fi \fi
+ \expandafter \object@lookahead@do \object@lookahead@gobble
+}
+\newcommand{\object@lookahead@checkbegin}[2]{% #1: \begin, #2: environment name
+ \ifstrequal{#2}{subobject}
+ \object@lookahead@beforesubobject
+ \object@lookahead@nosubobject
+ #1{#2}%
+}
+
+\@firstofone{\let\@implicitspace= }
+\@firstofone{\def\@gobblespace} {}
+
+
+% ========== object styles ==========
+
+\newcommand{\IfObjectStyleExists}[1]{% #1: style name or group name, #2: then block, #3: else block
+ \ifcsmacro{object@style@#1}%
+}
+\newcommand{\IfObjectStyleNotGroup}[1]{% #1: style name, #2: then block, #3: else block
+ \IfObjectStyleExists{#1}
+ {\edef\esf@tmp@do{\ifcsstring{object@stylegroup@#1}{{#1}}}\esf@tmp@do}%
+ \@secondoftwo
+}
+
+\newcommand{\objectstyle@init}[1]{% #1: style name or group name
+ \expandafter \newcommand \csname object@style@#1\endcsname{/utils/exec=\object@directkeysfalse}%
+ \expandafter \newcommand \csname object@stylegroup@#1\endcsname{}%
+}
+
+\newrobustcmd{\AddObjectStyleToGroup}[2]{% #1: group name, #2: style name
+ \IfObjectStyleExists{#1}{%
+ \IfObjectStyleNotGroup{#2}{%
+ \AddObjectStyleToGroup@do{#1}{#2}%
+ }{%
+ \PackageError{easyfloats}{Undefined object style: #2}{In this case you cannot use a style group instead of a group.}%
+ }}{%
+ \PackageError{easyfloats}{Undefined object style group: #1}{}%
+ }%
+}
+\newrobustcmd{\AddObjectStyleToGroup@do}[2]{% #1: group name, #2: style name
+ \expandafter\eappto\csname object@stylegroup@#1\endcsname{{#2}}%
+}
+\newrobustcmd{\ShowObjectStylesInGroup}[1]{%
+ \expandafter\show\csname object@stylegroup@#1\endcsname
+}
+
+\newcommand{\AppendOptionToObjectStyleGroups}[3]{% #1: list of style groups, #2: key, #3: value
+ \CheckObjectOption{#2}{#3}{%
+ \@for\esf@aotosg@group:=#1\do{%
+ \GobbleLeadingSpaceIn\esf@aotosg@group
+ \AppendOptionToObjectStyleGroup\esf@aotosg@group{#2}{#3}%
+ }%
+ }%
+}
+\newcommand{\AppendOptionToObjectStyleGroup}[3]{% #1: style group, #2: key, #3: value
+ \IfObjectStyleExists{#1}{%
+ \expandafter \let \expandafter \esf@tmp@listofstyles \csname object@stylegroup@#1\endcsname
+ \def\esf@tmp@loop{\@tfor\esf@aotosg@style:=}%
+ \expandafter\esf@tmp@loop\esf@tmp@listofstyles \do {%
+ \AppendOptionToObjectStyle\esf@aotosg@style{#2}{#3}%
+ }%
+ }{%
+ \PackageError{easyfloats}{Undefined object style: '#1'}{}%
+ }%
+}
+\newcommand{\AppendOptionToObjectStyle}[3]{% #1: style, #2: key, #3: value
+ \expandafter\AppendToOptionsList\csname object@style@#1\endcsname{#2}{#3}%
+}
+\newrobustcmd{\ShowObjectStyleOptions}[1]{%
+ \IfObjectStyleNotGroup{#1}
+ {\expandafter\show\csname object@style@#1\endcsname}%
+ {\PackageError{easyfloats}{Undefined object style: '#1'}{}}%
+}
+
+
+% ---------- style groups ----------
+
+\newrobustcmd{\NewObjectStyleGroup}[2]{% #1: group name, #2: list of style names
+ \IfObjectStyleExists{#1}{%
+ \PackageError{easyfloats}{Style or style group with the name '#1' exists already}{}%
+ }{%
+ \objectstyle@init{#1}%
+ \@for\esf@nosg@style:=#2\do{%
+ \GobbleLeadingSpaceIn\esf@nosg@style
+ \AddObjectStyleToGroup{#1}{\esf@nosg@style}%
+ }%
+ }%
+}
+
+% ---------- object styles ----------
+
+\newrobustcmd{\NewObjectStyle}[2]{% #1: name, #2: options
+ \IfObjectStyleExists{#1}{%
+ \PackageError{easyfloats}{Style or style group with the name '#1' exists already}{}%
+ }{%
+ \objectstyle@init{#1}%
+ \AddObjectStyleToGroup@do{#1}{#1}%
+ %hack into \objectset[#1] to retrieve the value of type
+ \pgfkeyssetvalue{/object.check/type}{\pgfkeysnovalue}%
+ \objectset[#1]{#2}%
+ \esf@ifpgfkeyhasvalue{/object.check/type}{%
+ \edef\@do{\noexpand\DeprecateStandardFloatObject{\pgfkeysvalueof{/object.check/type}}{#1object}}%
+ \@do
+ }{%
+ \PackageError{easyfloats}{Missing required key 'type'}%
+ }%
+ %
+ \AddObjectStyleToGroup{all}{#1}%
+ %
+ \newenvironment{#1object}[1]{% #1: options
+ \object{%
+ .esf@also from/.expand once=\csname object@style@#1\endcsname,
+ /utils/exec=\object@directkeystrue,
+ ##1,
+ }%
+ }{%
+ \endobject
+ }%
+ \pgfkeysgetvalue{/object.check/type}{\NewObjectStyle@type}%
+ \edef\@do{\noexpand\AfterPreamble{%
+ \noexpand\IfEnvironmentExists{sub\NewObjectStyle@type}{%
+ \noexpand\PackageInfo{easyfloats}{environment 'sub\NewObjectStyle@type' exists already}%
+ }{\NewObjectStyle@IfCaptionNewEnough{%
+ \noexpand\PackageInfo{easyfloats}{declaring new caption subtype 'sub\NewObjectStyle@type'}%
+ \noexpand\DeclareCaptionSubType{\NewObjectStyle@type}%
+ }{%
+ \noexpand\PackageWarning{easyfloats}{The caption package is too old for me to define the subtype automatically. Please insert `\string\AtBeginDocument{\string\DeclareCaptionSubType{\NewObjectStyle@type}}' before loading this package}%
+ }%
+ }%
+ }}\@do
+ }%
+}
+
+\@ifpackagelater{caption}{2020/08/30}
+ {\let\NewObjectStyle@IfCaptionNewEnough=\@firstoftwo}
+ {\let\NewObjectStyle@IfCaptionNewEnough=\@secondoftwo}
+
+
+\newcommand{\DeprecateStandardFloatObject}[2]{% #1: float environment, #2: alternative object environment
+ \ifesf@warnstandardfloats
+ \ifcsmacro{esf@#1@alternatives}{%
+ \expandafter \appto \csname esf@#1@alternatives\endcsname{ or #2}%
+ }{%
+ \AtBeginDocument{%
+ \csletcs{esf@original#1}{#1}%
+ \expandafter \preto\csname#1\endcsname{\PackageWarning{easyfloats}{In order to profit from the advantages of the easyfloats package please use \csname esf@#1@alternatives\endcsname\space instead}}%
+ }%
+ \expandafter \def \csname esf@#1@alternatives\endcsname{#2}%
+ \ifesf@loadgraphics
+ \ifstrequal{#1}{table}{%
+ % do nothing
+ }{%
+ \expandafter \appto \csname esf@#1@alternatives\endcsname{ or \string\includegraphicobject}%
+ }%
+ \fi
+ \eappto\object@restorestandardfloats{\let\expandonce{\csname #1\endcsname}=\expandonce{\csname esf@original#1\endcsname}}%
+ }%
+ \fi
+}
+
+
+% ---------- default styles ----------
+
+\NewObjectStyleGroup{all}{}
+
+\NewObjectStyle{table}{type=table}
+\NewObjectStyle{figure}{type=figure}
+
+
+% ========== include graphic object ==========
+
+\newif\ifgraphicobject@autocaption
+\newif\ifgraphicobject@autolabel
+\newif\ifgraphicobject@autocaption@strippath
+\newif\ifgraphicobject@autolabel@strippath
+\newif\ifgraphicobject@warnenv
+\newif\ifgraphicobject@noenv
+
+\ifesf@loadgraphics
+
+\newcommand\object@graphic@env{figureobject}
+\newcommand\object@graphic@path{/object}
+\newcommand\object@graphic@options{}
+
+\newrobustcmd{\graphicobjectstyle}[1]{%
+ \IfObjectStyleNotGroup{#1}{%
+ \def\object@graphic@env{#1object}%
+ }{%
+ \PackageError{easyfloats}{Undefined object style: '#1'}{}%
+ }%
+}
+
+% do not confuse this with \CheckObjectGraphicOption
+% this corresponds to \CheckObjectOption
+\newcommand{\CheckGraphicobjectOption}[2]{% #1: key, #2: value, #3: executed if valid
+ % if #3 is *not* executed an error message is printed
+ \let\CheckGraphicobjectOption@handleArg=\@gobble
+ \esf@ifpgfkeyexists{/graphicobject/#1}{%
+ \esf@ifpgfkeyrequiresvalue{/graphicobject/#1}{%
+ \ifx \pgfkeysnovalue #2\relax
+ \PackageError{easyfloats}{The key '#1' requires a value. I am going to ignore this key}{}%
+ \else
+ \let\CheckGraphicobjectOption@handleArg=\@firstofone
+ \fi
+ }{%
+ \let\CheckGraphicobjectOption@handleArg=\@firstofone
+ }%
+ }{\esf@ifkeyvalkeyexists{Gin}{#1}{%
+ \esf@ifkeyvalkeyrequiresvalue{Gin}{#1}{%
+ \ifx \pgfkeysnovalue #2\relax
+ \PackageError{easyfloats}{The key '#1' requires a value. I am going to ignore this key}{}%
+ \else
+ \let\CheckGraphicobjectOption@handleArg=\@firstofone
+ \fi
+ }{%
+ \let\CheckGraphicobjectOption@handleArg=\@firstofone
+ }%
+ }{%
+ \PackageError{easyfloats}{'#1' is not a valid graphic option key}
+ {If you intended to use a graphbox option please make sure that you loaded this package with the option 'graphbox'.}%
+ }}%
+ \CheckGraphicobjectOption@handleArg
+}
+
+\newcommand{\AppendGraphicobjectOption}[2]{% #1: key, #2: value
+ \AppendToOptionsList{\object@graphic@options}{#1}{#2}%
+}
+\newcommand{\includegraphicobject@SetGraphicobjectOption}[2]{% #1: key, #2: value
+ \pgfkeysalso{#1={#2}}%
+}
+
+% available options
+\pgfqkeys{/graphicobject}{%
+ auto caption/.is if=graphicobject@autocaption,
+ auto caption=true,
+ %
+ auto label/.is if=graphicobject@autolabel,
+ auto label=true,
+ %
+ auto caption strip path/.is if=graphicobject@autocaption@strippath,
+ auto caption strip path=false,
+ %
+ auto label strip path/.is if=graphicobject@autolabel@strippath,
+ auto label strip path=false,
+ %
+ warn env/.is if=graphicobject@warnenv,
+ warn env=true,
+ %
+ no env/.is if=graphicobject@noenv,
+ no env=true,
+}
+
+\newrobustcmd{\includegraphicobject}{% [#1: graphicstyle], [#2: options], #3: graphic filename without extension
+ \let\includegraphicobject@after=\@empty
+ \@ifnextchar [%
+ \includegraphicobject@firstarg
+ \includegraphicobject@parseoptions
+}
+\def\includegraphicobject@firstarg[#1]{%
+ \begingroup
+ \@ifnextchar [%
+ {%
+ \begingroup
+ \let\includegraphicobject@after=\endgroup
+ \graphicobjectstyle{#1}%
+ \includegraphicobject@parseoptions
+ }%
+ {%
+ \includegraphicobject@parseoptions[#1]%
+ }%
+}
+
+\newcommand{\includegraphicobject@parseoptions}{% [#1: options], #2: graphic filename without extension
+ % expanding \object@graphic@env before is important for subcaptionbox
+ % otherwise I get the error \begin{subobject} ended by \end{subobject}
+ \@ifnextchar [
+ {\expandafter\includegraphicobject@do\expandafter{\object@graphic@env}}
+ {\expandafter\includegraphicobject@do\expandafter{\object@graphic@env}[]}%
+}
+\def\includegraphicobject@do#1[#2]#3{% #1: environment name, #2: options, #3: graphic filename without extension
+ \global\object@isgraphictrue
+ \begin{#1}{%
+ /utils/exec=\def\object@graphic@options@tmp{}%
+ \let\AppendGraphicobjectOption\includegraphicobject@SetGraphicobjectOption,
+ .unknown/.code={%
+ \esf@ifkeyvalkeyexists{Gin}{\pgfkeyscurrentname}{%
+ \AppendToOptionsList{\object@graphic@options@tmp}{\pgfkeyscurrentname}{##1}%
+ }{%
+ \let\pgfkeys@searchalso@name=\pgfkeyscurrentname
+ \pgfkeysalso{%
+ /graphicobject/\pgfkeys@searchalso@name={##1},
+ }%
+ }%
+ },
+ .esf@also from=\object@graphic@options,
+ #2,
+ /utils/exec=
+ \ifgraphicobject@autocaption
+ \esf@ifpgfkeyhasvalue{\object@graphic@path/caption}{%
+ % do nothing
+ }{%
+ \def\graphicobject@caption{#3}%
+ \PatchUnderscore\graphicobject@caption
+ \ifgraphicobject@autocaption@strippath
+ \protected@edef\graphicobject@caption{\strippath\graphicobject@caption}%
+ \fi
+ \pgfkeyslet{\object@graphic@path/caption}{\graphicobject@caption}%
+ }%
+ \fi
+ \ifgraphicobject@autolabel
+ \esf@ifpgfkeyhasvalue{\object@graphic@path/label}{%
+ % do nothing
+ }{%
+ \def\graphicobject@label{#3}%
+ \ifgraphicobject@autolabel@strippath
+ \protected@edef\graphicobject@label{\strippath\graphicobject@label}%
+ \fi
+ \pgfkeyslet{\object@graphic@path/label}{\graphicobject@label}%
+ }%
+ \fi
+ \ifgraphicobject@warnenv
+ \pgfkeysalso{env/.get=\esf@tmp@env}%
+ \ifx \esf@tmp@env \@empty
+ \else
+ \ifdefstring{\object@graphic@env}{subobject}
+ {\edef\esf@tmp@name{\string\includegraphicsubobject}}
+ {\edef\esf@tmp@name{\string\includegraphicobject}}%
+ \ifgraphicobject@noenv
+ \PackageWarning{easyfloats}{I am ignoring 'env=\esf@tmp@env' in \esf@tmp@name}%
+ \else
+ \PackageWarning{easyfloats}{'env=\esf@tmp@env' in \esf@tmp@name. Is that intended?}%
+ \fi
+ \fi
+ \fi
+ \ifgraphicobject@noenv
+ \pgfkeysalso{env=}%
+ \fi
+ ,
+ }
+ \expandafter\includegraphics\expandafter[\object@graphic@options@tmp]{#3}%
+ \end{#1}%
+ % if this is \@empty it should not interfere with \ignorespacesafterend (\ignorespaces) or \@endparenv (\@doendpe)
+ \includegraphicobject@after
+}
+
+\newrobustcmd{\includegraphicsubobject}{%
+ \begingroup
+ \def\object@graphic@env{subobject}%
+ \def\object@graphic@path{/subobject}%
+ \def\includegraphicobject@after{\endgroup\ignorespaces}%
+ \includegraphicobject@parseoptions
+}
+
+
+\fi %\ifesf@loadgraphics
+
+
+% ========== sub object ==========
+
+\newif\ifsubobject@warnnolabel
+\newif\ifsubobject@warnnocaption
+
+% available options
+\pgfqkeys{/subobject}{%
+ % A label for the left/right part of the content
+ label/.initial,
+ label/.value required,
+ %
+ % A caption displayed above or below the sub content
+ % (depending on the float style).
+ % There is *no* dot added automatically behind it.
+ caption/.initial,
+ caption/.value required,
+ %
+ % A caption used in the list of figures/tables/...
+ % for the left/right part of the content.
+ list caption/.initial,
+ list caption/.value required,
+ %
+ % An addition to the caption (at the object only, not in a list)
+ details/.initial=,
+ details/.value required,
+ %
+ details sep/.initial=.\space,
+ details sep/.value required,
+ %
+ % TeX code which is inserted before env
+ exec/.initial=,
+ exec/.value required,
+ exec +/.code=\esf@pgfkeysvalueappend{/subobject/exec}{#1},
+ exec +/.value required,
+ exec+/.forward to=/subobject/exec +,
+ exec+/.value required,
+ %
+ % The width argument of \subcaptionbox or subfigure.
+ % For \subcaptionbox an empty value is allowed
+ % meaning that the argument is not passed so that
+ % \subcaptionbox takes the width of the content.
+ linewidth/.initial=.5\linewidth,
+ linewidth/.value required,
+ %
+ % Use the \subcaptionbox command.
+ % Aligns the captions.
+ % Does not allow verbatim content.
+ % Is *not* compatible with env=tabularx.
+ subcaptionbox/.code=
+ \let\subobject@begin\subobject@subcaptionbox
+ \let\subobject@end\endsubobject@subcaptionbox,
+ subcaptionbox/.value forbidden,
+ % Use the subfigure/subtable environment.
+ % Requires linewidth.
+ subpage/.code=
+ \let\subobject@begin\subobject@subpage
+ \let\subobject@end\endsubobject@subpage,
+ subpage/.value forbidden,
+ %
+ % ------- subcaptionbox options -------
+ % Horizontal position of the content in the box.
+ % Allowed values: c, l, r, s, <empty> or any
+ % justification defined with \DeclareCaptionJustification
+ % (see the caption package documentation).
+ % An empty value means that this optional argument is
+ % *not* passed to the \subcaptionbox command.
+ % This option has no effect if linewidth is empty.
+ % I discourage using this option because it destroys
+ % the alignment of (sub)object and (sub)caption.
+ subcaptionbox inner pos/.initial=,
+ subcaptionbox inner pos/.value required,
+ %
+ % ------- subfigure/subtable options -------
+ % The subfigure/subtable environments are minipages
+ % and take the same arguments.
+ % http://tug.org/texinfohtml/latex2e.html#minipage
+ %
+ % The vertical position of the minipage on the baseline.
+ % Allowed values: c, t, b, auto, <empty>.
+ % auto means t if the caption is displayed at the top
+ % or b if the caption is displayed at the bottom
+ % so that the captions are aligned if the minipages
+ % have the same height.
+ % <empty> is equivalent to c.
+ subpage outer pos/.initial=auto,
+ subpage outer pos/.value required,
+ %
+ % The height of the minipage.
+ % An empty value means that this optional argument is
+ % *not* passed to the subfigure/subtable environment.
+ subpage height/.initial=,
+ subpage height/.value required=,
+ %
+ % The vertical position of the content on the minipage.
+ % Allowed values: t, c, b, s, <empty>.
+ % <empty> means that this optional argument is
+ % *not* passed to the subfigure/subtable environment.
+ % This option has no effect if subpage height is <empty>.
+ subpage inner pos/.initial=,
+ subpage inner pos/.value required,
+ %
+ % TeX code which is inserted at the beginning of the subfigure/subtable environment
+ subpage align/.initial=\centering,
+ subpage align/.value required,
+ %
+ % ------- separator options -------
+ % Insert a separator in front of each subobject
+ % except for the first subobject.
+ sep/.initial=,
+ sep/.value required,
+ %
+ % Place the subobjects side by side.
+ hor/.code=
+ \esf@pgfkeyscopyvalue{/subobject/sep}{/subobject/hor sep}%
+ \esf@pgfkeysvalueappend{/subobject/sep}{#1},
+ hor/.default=,
+ %
+ % The separator to be used when the subobjects
+ % shall be placed side by side.
+ hor sep/.initial=,
+ hor sep/.value required,
+ hor sep+/.forward to=/subobject/hor sep +,
+ hor sep+/.value required,
+ hor sep +/.code=\esf@pgfkeysvalueappend{/subobject/hor sep}{#1},
+ hor sep +/.value required,
+ %
+ % Place the subobjects below each other.
+ ver/.code=
+ \esf@pgfkeyscopyvalue{/subobject/sep}{/subobject/ver sep}%
+ \esf@pgfkeysvalueappend{/subobject/sep}{#1},
+ ver/.default=,
+ %
+ % The separator to be used when the subobjects
+ % shall be placed below eachother.
+ ver sep/.initial=\par\bigskip,
+ ver sep/.value required,
+ ver sep+/.forward to=/subobject/ver sep +,
+ ver sep+/.value required,
+ ver sep +/.code=\esf@pgfkeysvalueappend{/subobject/ver sep}{#1},
+ ver sep +/.value required,
+ %
+ %
+ % ------- warnings -------
+ %
+ warn no caption/.is if=subobject@warnnocaption,
+ warn no caption=true,
+ %
+ warn no label/.is if=subobject@warnnolabel,
+ warn no label=false,
+ %
+ warn other env/.forward to=/object/warn other env,
+ %value is allowed but not necessary
+ %
+ %
+ % ------- debugging -------
+ %
+ show env args/.forward to=/object/show env args,
+ %
+ %
+ % ------- inner environment -------
+ %
+ % An additional inner environment to wrap the content in like tabular, tabularx, tikzpicture
+ env/.code=\IfEnvironmentExistsOrIsEmpty{#1}{%
+ \ifstrequal{#1}{longtable}{%
+ \PackageError{easyfloats}{You cannot use 'env=longtable' in a subobject}
+ {Either use 'env=tabular' instead or combine the subobjects into one longtable.}%
+ \pgfkeyssetvalue{/subobject/env}{tabular}%
+ }{%
+ \pgfkeyssetvalue{/subobject/env}{#1}%
+ }%
+ }{%
+ \PackageError{easyfloats}{Environment #1 which you passed to the key 'env' does not exist}{}%
+ },
+ env/.value required,
+ env=,
+ %
+ % ------- unknown handler / env args -------
+ %
+ % see /object
+ %
+ .unknown/.code={%
+ % Using \ObjectProcessKeyPattern instead of \ObjectProcessArgs
+ % means that keys like `graphic width` can be used in subobjects as well.
+ % For a directly used subobject this should not be allowed.
+ % But I am leaving it in for \includegraphicsubobject so that the same key
+ % which works in \objectset and \includegraphicobject also works there.
+ \ObjectProcessKeyPattern{\pgfkeyscurrentname}{#1}{%
+ \pgfkeysgetvalue{/subobject/.really unknown/.@cmd}{\esf@tmp@err}%
+ \esf@tmp@err#1\pgfeov
+ }%
+ },
+ % Setting an unknown key handler shall not override env args but set an additional unknown handler.
+ .unknown/.code/.code={%
+ \pgfkeysdef{/subobject/.really unknown}{#1}%
+ },
+ .really unknown/.code={%
+ \edef\do{\noexpand\pgfkeys{/errors/unknown key={\pgfkeyscurrentkey}{\unexpanded{#1}}}}%
+ \do
+ },
+}%
+
+\newenvironment{subobject}[1]{% #1: options
+ \if@inobject
+ \else
+ \PackageError{easyfloats}{subobject environment may not be used outside of an object}{Did you mean to use the object environment instead?}%
+ \fi
+ %
+ \subobject@hook
+ \ifobject@isgraphic
+ \object@graphic@hook
+ \global\object@isgraphicfalse
+ \fi
+ %
+ \let\label=\esf@original@label
+ \let\caption=\esf@original@caption
+ %
+ % ------- options -------
+ %
+ \renewcommand\@object@envkey{/subobject/env}%
+ \pgfqkeys{/subobject}{#1}%
+ \ifsubobject@warnnocaption
+ \pgfkeys{/subobject/caption/.esf@recommended}%
+ \fi
+ \ifsubobject@warnnolabel
+ \pgfkeys{/subobject/label/.esf@recommended}%
+ \fi
+ %
+ \esf@ifpgfkeyhasvalue{/subobject/list caption}%
+ {\pgfkeys{/subobject/list caption/.get=\subobject@caption@short}}%
+ {\pgfkeys{/subobject/caption/.get=\subobject@caption@short}}%
+ \pgfkeysgetvalue{/subobject/linewidth}{\subobject@linewidth}%
+ %
+ \pgfkeysgetvalue{/subobject/details}{\subobject@details}%
+ \ifx \subobject@details \@empty
+ % do nothing
+ \else
+ \preto\subobject@details{\pgfkeysvalueof{/subobject/details sep}}%
+ \fi
+ %
+ \pgfkeysgetvalue{/subobject/env}{\esf@tmp@env}%
+ \ifx \esf@tmp@env \@empty
+ \def\subobject@innerenv@begin{\ignorespaces}%
+ \def\subobject@innerenv@end{\unskip}%
+ \else
+ \edef\subobject@innerenv@begin{\expandonce{\csname\esf@tmp@env\endcsname}}%
+ \edef\subobject@innerenv@end{\expandonce{\csname end\esf@tmp@env\endcsname}}%
+ \ObjectAppendEnvargs{\subobject@innerenv@begin}%
+ \ifobject@showenv
+ \show\subobject@innerenv@begin
+ \fi
+ \fi
+ %
+ % ------- execute -------
+ %
+ \if@firstsubobject
+ \else
+ % No need to worry about \parskip.
+ % Inside of a floating environment it appears to be always zero.
+ \pgfkeysvalueof{/subobject/sep}%
+ \fi
+ \subobject@begin
+}{%
+ \subobject@end
+ \global \@firstsubobjectfalse
+}
+
+\NewEnviron{subobject@subcaptionbox}{%
+ \def\subobject@box{%
+ \subcaptionbox[% list caption
+ \subobject@caption@short
+ ]{% caption
+ \pgfkeysvalueof{/subobject/caption}%
+ \subobject@details
+ \esf@ifpgfkeyhasvalue{/subobject/label}
+ {\label{\pgfkeysvalueof{/subobject/label}}}
+ {}%
+ }%
+ }%
+ \ifdefvoid\subobject@linewidth{%
+ % do nothing
+ }{%
+ \appto\subobject@box{[\subobject@linewidth]}%
+ \pgfkeysgetvalue{/subobject/subcaptionbox inner pos}{\subobject@innerpos}%
+ \ifx \subobject@innerpos \@empty
+ % do nothing
+ \else
+ \eappto\subobject@box{[\subobject@innerpos]}%
+ \fi
+ }%
+ \subobject@box{% content
+ \begingroup
+ \renewcommand{\label}[1]{\PackageError{easyfloats}{\string\label\space is not allowed in subobject. Please use the 'label' option instead}{}}%
+ \renewcommand{\caption}[2][]{\PackageError{easyfloats}{\string\caption\space is not allowed in subobject. Please use the 'caption' option instead}{}}%
+ \pgfkeysvalueof{/subobject/exec}%
+ \subobject@innerenv@begin
+ \BODY
+ \subobject@innerenv@end
+ \endgroup
+ }%
+}
+
+\newenvironment{subobject@subpage}{%
+ \ifx \subobject@linewidth \@empty
+ \PackageError{easyfloats}{'linewidth' may not be empty when using the 'subpage' backend}{}%
+ \fi
+ \edef\subobject@subpage@envname{sub\pgfkeysvalueof{/object/type}}%
+ \def\subobject@subpage@begin{\csname\subobject@subpage@envname\endcsname}%
+ \def\subobject@subpage@end{\csname end\subobject@subpage@envname\endcsname}%
+ %
+ \pgfkeysgetvalue{/subobject/subpage outer pos}{\subobject@outerpos}%
+ \ifx \subobject@outerpos \@empty
+ \appto\subobject@subpage@begin{[c]}%
+ \else \ifdefstring \subobject@outerpos {auto}{%
+ \caption@iftop
+ {\eappto\subobject@subpage@begin{[t]}}%
+ {\eappto\subobject@subpage@begin{[b]}}%
+ }{\ifdefstring \subobject@outerpos {Auto}{%
+ \caption@iftop
+ {\eappto\subobject@subpage@begin{[T]}}%
+ {\eappto\subobject@subpage@begin{[B]}}%
+ }{%
+ \eappto\subobject@subpage@begin{[\subobject@outerpos]}%
+ }}\fi
+ \pgfkeysgetvalue{/subobject/subpage height}{\subobject@height}%
+ \ifx \subobject@height \@empty
+ \else
+ \appto\subobject@subpage@begin{[\subobject@height]}%
+ \pgfkeysgetvalue{/subobject/subpage inner pos}{\subobject@innerpos}%
+ \ifx \subobject@innerpos \@empty
+ \else
+ \eappto\subobject@subpage@begin{[\subobject@innerpos]}%
+ \fi
+ \fi
+ %
+ \subobject@subpage@begin{\subobject@linewidth}%
+ \pgfkeysvalueof{/subobject/subpage align}%
+ % \caption@iftop is defined by caption package
+ \caption@iftop{\subobject@subpage@captionAndLabel}{}%
+ \begingroup
+ \renewcommand{\label}[1]{\PackageError{easyfloats}{\string\label\space is not allowed in subobject. Please use the 'label' option instead}{}}%
+ \renewcommand{\caption}[2][]{\PackageError{easyfloats}{\string\caption\space is not allowed in subobject. Please use the 'caption' option instead}{}}%
+ \pgfkeysvalueof{/subobject/exec}%
+ \subobject@innerenv@begin
+}{%
+ \subobject@innerenv@end
+ \endgroup
+ \caption@iftop{}{\subobject@subpage@captionAndLabel}%
+ \subobject@subpage@end
+ \ignorespacesafterend
+}
+\newcommand{\subobject@subpage@captionAndLabel}{%
+ % ------- caption -------
+ % position of caption (above/below) is handled by float package (see float style)
+ \esf@ifpgfkeyhasvalue{/subobject/caption}{%
+ \caption[\subobject@caption@short]{\pgfkeysvalueof{/subobject/caption}\subobject@details}%
+ }{%
+ % Generate an anchor for a \label.
+ \phantomcaption
+ }%
+ % ------- label -------
+ \esf@ifpgfkeyhasvalue{/subobject/label}%
+ {\label{\pgfkeysvalueof{/subobject/label}}}%
+ {}%
+}
+
+\pgfqkeys{/subobject}{subpage}
diff --git a/Master/texmf-dist/source/latex/easyfloats/easyfloats.ins b/Master/texmf-dist/source/latex/easyfloats/easyfloats.ins
new file mode 100644
index 00000000000..c3f1020483b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/easyfloats/easyfloats.ins
@@ -0,0 +1,82 @@
+% !TeX program = tex
+
+%% easyfloats.ins
+%% Copyright 2020 E. Zöllner
+%
+% 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 E. Zöllner.
+%
+% This work consists of the files listed in easyfloats-file-list.txt.
+% The official git repository is https://gitlab.com/erzo/latex-easyfloats
+
+
+% Make easyfloats.dtx faster by stripping comments and indentation
+% and write the result to easyfloats.sty.
+
+\input docstrip.tex
+
+\preamble
+
+Copyright 2020 E. Z\string\"ollner
+
+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.
+Additionally to the rights granted by the LaTeX Project Public License
+you have permission to freely distribute unmodified copies
+of the files \jobname.sty and doc/easyfloats.pdf without other files of this work.
+The other files of this work can be found at:
+https://gitlab.com/erzo/latex-easyfloats
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is E. Z\string\"ollner.
+
+This work consists of the files listed in easyfloats-file-list.txt.
+\endpreamble
+
+\askforoverwritefalse
+\generate{
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\def\lnout{}
+\count0=0
+\def\append#1{\advance\count0 by 1 \expandafter\def\expandafter\lnout\expandafter{\lnout#1}}
+\def\appendmany#1{\ifx\relax#1\else\append{#1}\expandafter\appendmany\fi}
+\obeyspaces
+\appendmany \relax
+\expandafter\appendmany\jobname.sty\relax
+\loop\append{ }\ifnum\count0<48\repeat
+\Msg{****************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the *}
+\Msg{* following file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* \lnout *}
+\Msg{* *}
+\Msg{* To produce the documentation run: *}
+\Msg{* $ cd doc *}
+\Msg{* $ pdflatex easyfloats.tex *}
+\Msg{* $ biber easyfloats *}
+\Msg{* $ pdflatex easyfloats.tex *}
+\Msg{* $ pdflatex easyfloats.tex *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{****************************************************}
+
+\endbatchfile