% \iffalse meta-comment
%
% Copyright (C) 2014-2018 by Dominik Siegel
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.2 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.2 or later is part of all distributions of
% LaTeX version 1999/12/01 or later.
%% 
%% To produce the documentation, do the following
%%
%%    latex fancylabel.dtx
%%    latex fancylabel.dtx
%%    makeindex -s gind.ist -o fancylabel.ind fancylabel.idx
%%    latex fancylabel.dtx
%
% <package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
% <package>\ProvidesPackage{fancylabel}
% <package>[2017/12/30 v1.1]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[numbering=continuous,families={mark,sym},level=sub,sort=true]{fancylabel}
\usepackage{subfig}
\usepackage[hidelinks]{hyperref}
\GetFileInfo{fancylabel.dtx}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\OnlyDescription
\date{2017/12/30}
\begin{document}
    \DocInput{fancylabel.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \changes{v1.0}{2014/07/15}{Initial version}
% \changes{v1.1}{2017/12/30}{Dependencies updated}
%
% \GetFileInfo{fancylabel.sty}
%
% \DoNotIndex{\@auxout,\@end@token,\@ifnextchar,\@ifundefined,\@namedef,\@nameuse,\@onlypreamble}
% \DoNotIndex{\alph,\arabic,\AtEndDocument}
% \DoNotIndex{\csname}
% \DoNotIndex{\DeclareOptionX,\DeclareRobustCommand,\def,\define@choicekey,\define@key}
% \DoNotIndex{\else,\endcsname,\equal,\expandafter}
% \DoNotIndex{\fi}
% \DoNotIndex{\g@addto@macro,\global}
% \DoNotIndex{\ifcase,\ifthenelse,\immediate}
% \DoNotIndex{\NeedsTeXFormat,\newcommand,\newcounter,\newif,\nr}
% \DoNotIndex{\or}
% \DoNotIndex{\PackageError,\PackageWarning,\presetkeys,\ProcessOptionsX,\ProvidesPackage}
% \DoNotIndex{\relax,\RequirePackage}
% \DoNotIndex{\setcounter,\stepcounter,\string}
% \DoNotIndex{\val}
% \DoNotIndex{\write}
% \DoNotIndex{\xdef}
%
% \title{The \textsf{fancylabel} package\thanks{This document corresponds to \textsf{fancylabel}~\fileversion{}, dated \filedate.}}
%
% \author{Dominik Siegel \\ \texttt{dominik.siegel@yahoo.de}}
% 
% \maketitle
%
% \begin{abstract}
%	For \LaTeX{} referencing it is necessary to have unique labels. But sometimes you have similar objects (symbols, chemical structures, etc.) that appear more often than once in your document. When you write your document you cannot know from the beginning on in which position your object appears for the first time. Hence you don't know whether to place a |\label| or a |\ref|. 
%
% This package basically provides the two new commands |\fancylabel| and |\fancyref|. With the |\fancylabel| command you don't have to know if it is time to set a |\label| or a |\ref|, |\fancylabel| will decide this for you.
%
% Additionally this package allows you various different numerations including numbering order, numbering level and numbering families.
% \end{abstract}
%
%
% \tableofcontents
%
% \section{Introduction}
%
% The idea of referencing in \LaTeX{} is to associate an object with a |\label|. Whenever you want to refer to it you just use |\ref|. This works as long as you have an unique object like a figure, a table, a section etc. But if you want the refer to repeating objects which are expected to have the same number like symbols, (chemical-) structures etc. referencing becomes more complex. 
%
% \newcounter{mylabelcounter}
% \newcommand{\mylabel}[1]{\refstepcounter{mylabelcounter}\themylabelcounter\label{#1}}
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{cccc}
%         \Huge$\rightarrow$ & \Huge$\leftarrow$ & 
%         \Huge$\rightarrow$ & \Huge$\Leftarrow$ \\
%         \mylabel{arrow1}   & \mylabel{arrow2}  & 
%         \ref{arrow1}       & \mylabel{arrow3}
%     \end{tabular}
%     \caption{Some repeating objects. Here we refer to symbol \ref{arrow2}.}
% \end{figure}
%
% In our example same arrows are supposed to get the same number. We define a counter and a new label command. This was actually quite simple. But the big disadvantage of this solution is, that you always have to take care where your object occurs for the first time. At the first occurrence you have to label it, at any other occurrence you have to refer. Every time you change the order you have to adjust the labeling by hand.
%
% \begin{verbatim}
% \newcounter{mylabelcounter}
% \newcommand{\mylabel}[1]{\refstepcounter{mylabelcounter}\themylabelcounter\label{#1}}
% \begin{figure}[h]
% ...figure code...
%     \begin{tabular}{cccc}
%         \Huge$\rightarrow$ & \Huge$\leftarrow$ &
%         \Huge$\rightarrow$ & \Huge$\Leftarrow$ \\
%         \mylabel{arrow1}   & \mylabel{arrow2}  &
%         \ref{arrow1}       & \mylabel{arrow3}
%     \end{tabular}
% ...figure code...
% \end{figure}
% \end{verbatim}
%
% Beside other additional functions and options this is exactly what the \textsf{fancylabel} package does for you. Whenever you insert an object you can use |\fancylabel|. The package will recognize if the label already exists and therefore decides whether to label or to refer.
%
% \begin{verbatim}
% \begin{figure}[h]
% ...figure code...
%     \begin{tabular}{cccc}
%         \Huge$\rightarrow$  & \Huge$\leftarrow$   &
%         \Huge$\rightarrow$  & \Huge$\Leftarrow$   \\
%         \fancylabel{arrow1} & \fancylabel{arrow2} &
%         \fancylabel{arrow1} & \fancylabel{arrow3}
%     \end{tabular}
% ...figure code...
% \end{figure}
% \end{verbatim}
% \fancylabel*{arrow1,arrow2,arrow3}
%
%
% \section{Package Commands}
% \subsection{Label commands}
% \DescribeMacro{\fancylabel}
% \DescribeMacro{\fancylabel*}
% |\fancylabel[<family>]{<marker>}|\\
% |\fancylabel*[<family>]{<marker>}|\vspace{0.5em}
%
% \noindent The |\fancylabel| command always checks if a label for |<marker>| already exists and creates it if not. Then it prints the reference as |\fancyref| does. Additionally a |<family>| can be defined (For description see section \ref{fam}). The starred versions create a label without printing the reference. 
%
% The argument |<marker>| might also be a comma-separated list of indentifiers. In this case |\fancylabel| creates a label for all so far undefined indentifiers and prints a list of references. This list can be sorted and compressed automatically (see section \ref{sort} and \ref{compress}).
%
%
% \subsection{Sublabel commands}
% \DescribeMacro{\fancysublabel}
% \DescribeMacro{\fancysublabel-}
% \DescribeMacro{\fancysublabel*}
% |\fancysublabel[<family>]{<marker>}{<submarker>}|\\
% |\fancysublabel-[<family>]{<marker>}{<submarker>}|\\
% |\fancysublabel*[<family>]{<marker>}{<submarker>}|\vspace{0.5em}
% 
% \noindent The |\fancysublabel| command is working in the same way as |\fancylabel| while providing a second level of referencing. If the corresponding label for |<marker>| was not previously defined, it will be created as well. The output of |\fancysublabel| is the complete reference consisting in label and sublabel (e.\,g. 1a). The output of |\fancysublabel-| is only the sublabel (e.\,g. a). The starred version |\fancysublabel*| creates the sublabel without any output.
%
% While the argument |<marker>| has to be a single indentifier, the |<submarker>| argument might be a comma-separated list. In this case |\fancysublabel| creates a sublabel for all so far undefined indentifiers and prints a list of references. This list can be sorted and compressed automatically (see section \ref{sort} and \ref{compress}).
%
%
% \subsection{Ref and subref commands}
% \DescribeMacro{\fancyref}
% \DescribeMacro{\fancyref*}
% \DescribeMacro{\fancysubref}
% \DescribeMacro{\fancysubref-}
% \DescribeMacro{\fancysubref*}
% |\fancyref[<family>]{<marker>}|\\
% |\fancyref*[<family>]{<marker>}|\\
% |\fancysubref[<family>]{<marker>}{<submarker>}|\\
% |\fancysubref-[<family>]{<marker>}{<submarker>}|\\
% |\fancysubref*[<family>]{<marker>}{<submarker>}|\vspace{0.5em}
% 
% \noindent The function of these commands is compareable to their corresponding label commands. |\fancyref| prints the reference of |<marker>| and remembers that this |<marker>| has been requested. |\fancyref*| remembers the request without any output. 
%
% |\fancysubref| prints the label and sublabel of |<marker>| and |<submarker>| and remembers the request. |\fancysubref-| prints only the sublabel and remembers the request. |\fancysubref*| does only remember the request.
%
%
% \section{Options}
% \subsection{The families option}\label{fam}
% \DescribeMacro{families=}
% |\usepackage[families={<comma-separated list>}]{fancylabel}|\vspace{0.5em}
%
% \noindent You can define different families for your labels to have different counters. This can be done with the |families| option. If you don't specify the family in label or ref commands |family=default| will be used. This is the only predefined family.
%
%
% \begin{verbatim}
% \begin{figure}[h]
% ...figure code...
%     \begin{tabular}{cccc}
%         \Huge$\rightarrow$        & \Large\textcopyright     &
%         \Huge$\oplus$             & \Huge$\ominus$           \\
%         \fancylabel{arrow1}       & \fancylabel[mark]{mark1} &
%         \fancylabel[sym]{symbol1} & \fancylabel[sym]{symbol2} 
%     \end{tabular}
% ...figure code...
% \end{figure}
% \end{verbatim}
%
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{cccc}
%         \Huge$\rightarrow$       & \Large\textcopyright      &
%         \Huge$\oplus$            & \Huge$\ominus$            \\
%         \fancylabel{arrow1}       & \fancylabel[mark]{mark1} &
%         \fancylabel[sym]{symbol1} & \fancylabel[sym]{symbol2} 
%     \end{tabular}
%     \caption{Objects of different families. For this example the families \texttt{mark} and \texttt{sym} have been defined using the family option.}
% \end{figure}
%
% 
%
% The (sub-)labels and (sub-)refs will have |<family>-| as prefix. This Prefix can be changed by redefining |\fancylabelformat<family>| and |\fancysublabelformat<family>|. For example the definition of the default-prefix can be changed by:
% \begin{verbatim}
% \renewcommand{\fancylabelformatdefault}{\arabic{fancylabel}}
% \end{verbatim}
%
%
% \subsection{The IgnoreFamilies option}
% \DescribeMacro{IgnoreFamilies=}
% |\usepackage[IgnoreFamilies=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent If the option |IgnoreFamilies=true|, every label will be interpreted as it would be part of the |default| family.
%
% \subsection{The numbering option}
% \DescribeMacro{numbering=}
% |\usepackage[numbering=<value>]{fancylabel}|\vspace{0.5em}
%
% \noindent The option |numbering| can have one of the following values: |continuous| (default), |ondemand| or |referenced|. We will now have a look on the following code compiled with different values for this option.
%
% \begin{verbatim}
% ...figure code...
%     \begin{tabular}{cccc}
%         \Huge$\Rightarrow$  & \Huge$\Leftrightarrow$    &
%         \Huge$\Leftarrow$   & \Huge$\rightleftharpoons$ \\
%         \fancylabel{arrow4} & \fancylabel{arrow5}       &
%         \fancylabel{arrow6} & \fancylabel{arrow7}
%     \end{tabular}
%     \caption{This is some random text where I refer to symbol%
%              \fancyref{arrow7} and symbol \fancyref{arrow5}.}
% ...figure code...
% \end{verbatim}
%
% \DescribeMacro{numbering=continuous}
% The |continuous| numbering means, that every |\fancylabel| will get its reference. The referencing order is in the order |\fancylabel| asked for.
%
% \fancylabelResetCounter{default}
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{cccc}
%         \Huge$\Rightarrow$  & \Huge$\Leftrightarrow$    &
%         \Huge$\Leftarrow$   & \Huge$\rightleftharpoons$ \\
%         \fancylabel{arrow4} & \fancylabel{arrow5}       &
%         \fancylabel{arrow6} & \fancylabel{arrow7}
%     \end{tabular}
%     \caption{This is some random text where I refer to symbol \fancyref{arrow7} and symbol \fancyref{arrow5}.}
% \end{figure}
%
% \DescribeMacro{numbering=ondemand}
% The |ondemand| numbering means, that a |\fancylabel| will only get its reference, if a |\fancyref| refered to it. The referencing order is in the order |\fancylabel| asked for.
%
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{cccc}
%         \Huge$\Rightarrow$  & \Huge$\Leftrightarrow$    &
%         \Huge$\Leftarrow$   & \Huge$\rightleftharpoons$ \\
%                             & 1                         &
%                             & 2
%     \end{tabular}
%     \caption{This is some random text where I refer to symbol 2 and symbol 1.}
% \end{figure}
%
% \DescribeMacro{numbering=referenced}
% The |referenced| numbering means, that a |\fancylabel| will only get its reference, if a |\fancyref| refered to it. The referencing order is in the order |\fancyref| asked for.
%
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{cccc}
%         \Huge$\Rightarrow$  & \Huge$\Leftrightarrow$    &
%         \Huge$\Leftarrow$   & \Huge$\rightleftharpoons$ \\
%                             & 2                         &
%                             & 1
%     \end{tabular}
%     \caption{This is some random text where I refer to symbol 1 and symbol 2.}
% \end{figure}
%
%
%
% \subsection{The level option}
% \DescribeMacro{level=}
% |\usepackage[level=<value>]{fancylabel}|\vspace{0.5em}
%
% \noindent The option |level| can have one of the following values: |sub| (default) or |same|. The value |sub| means, that all sublabels defined by |\fancysublabel| are interpreted as thought (two level numbering). The value |same| means, that all sublabels are interpreted as the would be labels defined with |\fancylabel| (one level numbering).
%
% \begin{verbatim}
% \begin{figure}[h]
%     \centering
%     \begin{tabular}{ccc}
%         \Huge$\diamondsuit$              & 
%         \Huge$\heartsuit$                &
%         \Huge$\spadesuit$                \\
%         \fancysublabel{cards}{diamond}   &
%         \fancysublabel{cards}{heart}     &
%         \fancysublabel{cards}{spade}     \\
%     \end{tabular}
% \end{figure}
% \end{verbatim}
%
% \captionsetup[subfigure]{labelformat=empty}
% \begin{figure}[h]
%     \centering
%     \subfloat[Option \texttt{level=sub}.]{
%     \begin{tabular}{ccc}
%         \Huge$\diamondsuit$              & 
%         \Huge$\heartsuit$                &
%         \Huge$\spadesuit$                \\
%         \fancysublabel{cards}{diamond}   &
%         \fancysublabel{cards}{heart}     &
%         \fancysublabel{cards}{spade}     \\
%     \end{tabular}
%     }\quad\quad
%     \subfloat[Option \texttt{level=same}.]{%     
%     \begin{tabular}{ccc}
%         \Huge$\diamondsuit$              & 
%         \Huge$\heartsuit$                &
%         \Huge$\spadesuit$                \\
%         5                                &
%         6                                &
%         7                                \\
%     \end{tabular}
%     }
% \end{figure}
%
%
% \subsection{The sort option}\label{sort}
% \DescribeMacro{sort=}
% |\usepackage[sort=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent If |sort=true| the output of fancylabels und fancyrefs will be sorted. By default this option is |false|.
%
%
% \subsection{The compress option}\label{compress}
% \DescribeMacro{compress=}
% |\usepackage[compress=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent If |compress=true| the output of fancylabels und fancyrefs compressed. By default this option is |false|.
%
%
% \subsection{The CompressLink option}
% \DescribeMacro{CompressLink=}
% |\usepackage[CompressLink=<separator>]{fancylabel}|\vspace{0.5em}
%
% \noindent With the |CompressLink| option you can define the separator between the compressed labels. The default value is |CompressLink={-}|.
%
%
% \subsection{The CompressTwo option}
% \DescribeMacro{CompressTwo=}
% |\usepackage[CompressTwo=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent By this option you can define if compression takes place even if there are only two sequential labels. By default this option is |false|. Example: |CompressTwo=true| $\rightarrow$ 1-2 and 1-3 or |CompressTwo=false| $\rightarrow$ 1,2 but 1-3.
%
%
% \subsection{The ListLastSublabelOnly option}
% \DescribeMacro{ListLastSublabelOnly=}
% |\usepackage[ListLastSublabelOnly=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent If |ListLastSublabelOnly=true| (default), the output of a list of fancysublabels of fancysublabels is e.\,g. 1a-d,e. If |ListLastSublabelOnly=false|, the output of a list of fancysublabels of fancysublabels is e.\,g. 1a-1d,1e.
%
%
% \subsection{The ListSeparator option}
% \DescribeMacro{ListSeparator=}
% |\usepackage[ListSeparator=<separator>]{fancylabel}|\vspace{0.5em}
%
% \noindent This option defines the separator between two non-compressed values in a list. By default, |ListSeparator={,\hskip-0.16667em{ }}| which is a small white space allowing linebreak.
%
%
% \subsection{The ListLastLabelSeparator option}
% \DescribeMacro{ListLastLabelSeparator=}
% |\usepackage[ListLastLabelSeparator=<separator>]{fancylabel}|\vspace{0.5em}
%
% \noindent This option defines the separator between the last two values in a list (e.\,g. \texttt{ListLastLabelSeparator=\{\raisebox{-0.23em}{\textasciitilde}and\raisebox{-0.23em}{\textasciitilde}}\} $\rightarrow$ 1a-c,d~and~f). By default, this option has the same value as the |ListSeparator| option. Note: This option will only be applied in label commands!
%
%
% \subsection{The ListLastRefSeparator option}
% \DescribeMacro{ListLastRefSeparator=}
% |\usepackage[ListLastRefSeparator=<separator>]{fancylabel}|\vspace{0.5em}
%
% \noindent This option behaves like the |ListLastLabelSeparator| option but will only be applied in ref commands.
%
%
% \subsection{The DisableFamilyCheck option}
% \DescribeMacro{DisableFamilyCheck=}
% |\usepackage[DisableFamilyCheck=<boolean>]{fancylabel}|\vspace{0.5em}
%
% \noindent When a new |\fancylabel| is defined the \textsf{fancylabel} package checks whether this |<marker>| has already been used in other families and prints a warning. The option |DisableFamilyCheck=true| disables this check. The default value is |DisableFamilyCheck=false|.
%
%
% \section{Customization}
% \subsection{Reset counters}
% The label counters of each family can be reset by using the following command. Note that |<number>=0| means that the next label will get the value 1. Note: This might cause crazy lists if the options |sort| or |compress| are used!
% \begin{verbatim}
% \renewcommand{\fancylabel@familystorage@<family>}{<number>}
% \end{verbatim}
%
%
% \subsection{Label und sublabel format}
% The format of labels and sublabels of each family can be adjusted by redefining the corresponding labelformat. In the following example you have to replace |<family>| by |default| to adjust the format of the default family.
% \begin{verbatim}
% \renewcommand{\fancylabelformat<family>}{\arabic{fancylabel}}
% \renewcommand{\fancysublabelformat<family>}{\arabic{fancylabel}\alph{fancysublabel}}
% \renewcommand{\fancyonlysublabelformat<family>}{\alph{fancysublabel}}
% \end{verbatim}
% 
%
% \subsection{NewLabelEvent}
% If you want to execute a macro everytime a new label has been defined you can modify the following command:
% \begin{verbatim}
% \fancylabelNewLabelEvent
% \end{verbatim}
% 
%
% \subsection{ShowLabelEvent}
% If you want to execute a macro everytime a label is shown you can modify the following command:
% \begin{verbatim}
% \fancylabelShowLabelEvent
% \end{verbatim}
% 
%
% \subsection{ShowRefEvent}
% If you want to execute a macro everytime a label is shown you can modify the following command:
% \begin{verbatim}
% \fancylabelShowRefEvent
% \end{verbatim}
%
%
% \subsection{Lists of labels}
% The \textsf{fancylabel} package draws up a comma-separated list of all labels that have been defined for each family. You can use these lists for further costumization.
% \begin{verbatim}
% \fancylabel@list@<family>
% \end{verbatim}
%
% \section{Change history}
% 	\begin{itemize}
%		\item[2014/07/15] Initial version
%		\item[2017/12/30] Dependencies updated (\textsf{xifthen} instead of \textsf{ifthen})
%	\end{itemize}
%
% \StopEventually{}
%
% \section{The implementation}
% 
% \subsection{Identification}
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2005/12/01]
\ProvidesPackage{fancylabel}[2017/12/30 v1.1 Referencing in a fancy way]
%    \end{macrocode}
%
% \subsection{Loading packages and define counters}
%    \begin{macrocode}
\RequirePackage{xkeyval}
\RequirePackage{xifthen}
\RequirePackage{suffix}
\newcounter{fancylabel}
\setcounter{fancylabel}{0}
\newcounter{fancysublabel}
\setcounter{fancysublabel}{0}
\presetkeys{fancylabel}{numbering=continuous,%
                      level=sub,%
                      IgnoreFamilies=false,%
                      sort=false,%
                      compress=false,%
                      CompressLink={-},%
                      CompressTwo=false,%
                      ListLastSublabelOnly=true,
                      ListSeparator={,\hskip-0.16667em{ }},%
                      ListLastLabelSeparator=\fancyref@ListSeparator,%
                      ListLastRefSeparator=\fancyref@ListSeparator,%
                      DisableFamilyCheck=false%
                      }{}
%    \end{macrocode}
%
% \subsection{The options}
% \begin{macro}{\fancyref@addtolist}
%    \begin{macrocode}
\newcommand{\fancyref@addtolist}[2]{%
    % #1=value to be added to the list #2
    % #2=list
    \ifthenelse{\equal{#1}{}}{}{%
        \ifthenelse{\equal{#2}{}}{}{%
            \g@addto@macro{#2}{,}%
        }%
        \g@addto@macro{#2}{#1}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@addtoprintlist}
%    \begin{macrocode}
\newcommand{\fancyref@addtoprintlist}[2]{%
    % #1=value to be added to the list #2
    % #2=list
    \ifthenelse{\equal{#1}{}}{}{%
        \ifthenelse{\equal{#2}{}}{}{%
            \g@addto@macro{#2}{\fancyref@ListSeparator}%
        }%
        \g@addto@macro{#2}{#1}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{families=}
%    \begin{macrocode}
\define@key{fancylabel}{families}{%
    \fancyref@foreach{\fancyref@DefineFamily}{}{#1}%
}
\newcommand{\fancyref@ListOfFamilies}{}
\newcommand{\fancyref@DefineFamily}[2]{%
    % #1=empty
    % #2=family
    \@namedef{fancylabel@familystorage@#2}{0}%
    \@namedef{fancylabelformat#2}{#2-\arabic{fancylabel}}%
    \@namedef{fancyonlysublabelformat#2}{\alph{fancysublabel}}%
    \@namedef{fancysublabelformat#2}{#2-\arabic{fancylabel}\alph{fancysublabel}}%
    \@namedef{fancylabel@list@#2}{}%
    \fancyref@addtolist{#2}{\fancyref@ListOfFamilies}%
}
\@onlypreamble\fancyref@DefineFamily
\fancyref@DefineFamily{}{default}
\renewcommand{\fancylabelformatdefault}{\arabic{fancylabel}}
\renewcommand{\fancysublabelformatdefault}{\arabic{fancylabel}\alph{fancysublabel}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{numbering=}
%    \begin{macrocode}
\define@choicekey*+{fancylabel}{numbering}[\val\nr]{continuous,ondemand,referenced}{%
    % ##1=family
    % ##2=label
    % ##3=sublabel
    \ifcase\nr\relax%
        % numbering=continuous
        % Label will be set un the first time, \fancylabel{} is called
        % Order of labels depends on the appearance of fancylabel{}
        \newcommand{\fancyref@define@LabelUndef}[3]{%
            \fancyref@newlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@show@LabelUndef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@define@LabelDef}[3]{}%
        \newcommand{\fancyref@show@LabelDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@define@RefUndef}[3]{}%
        \newcommand{\fancyref@show@RefUndef}[3]{%
            \@ifundefined{fancyref@PrevRun@##1@##2@##3}{%
                \fancyref@labelerror{##2}{##3}%
                ???%
            }{%
                \fancyref@showlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@define@RefDef}[3]{}%
        \newcommand{\fancyref@show@RefDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
    \or%
        % numbering=ondemand
        % Only set label if it was asked for during the last run
        % Order of labels depends on the appearance of fancylabel{}
        \newcommand{\fancyref@define@LabelUndef}[3]{%	
            \@ifundefined{fancyref@AskedPrevRun@##1@##2@##3}{}{%
                \fancyref@newlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@show@LabelUndef}[3]{%	
            \@ifundefined{fancyref@AskedPrevRun@##1@##2@##3}{}{%
                \fancyref@showlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@define@LabelDef}[3]{}%
        \newcommand{\fancyref@show@LabelDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@define@RefUndef}[3]{}%
        \newcommand{\fancyref@show@RefUndef}[3]{%
            \@ifundefined{fancyref@PrevRun@##1@##2@##3}{%
                \fancyref@labelerror{##2}{##3}%
                ???%
            }{%
                \fancyref@showlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@define@RefDef}[3]{}%
        \newcommand{\fancyref@show@RefDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
    \or%
        % numbering=referenced
        % Only set label if it was asked for during the last run
        % Order of labels depends on the appearance of fancyref{}
        \newcommand{\fancyref@define@LabelUndef}[3]{}%
        \newcommand{\fancyref@show@LabelUndef}[3]{%
            \@ifundefined{fancyref@AskedPrevRun@##1@##2@##3}{}{%
                \fancyref@showlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@define@LabelDef}[3]{}%
        \newcommand{\fancyref@show@LabelDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@define@RefUndef}[3]{%
            \fancyref@newlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@show@RefUndef}[3]{%
            \@ifundefined{fancyref@PrevRun@##1@##2@##3}{%
                \fancyref@labelerror{##2}{##3}%
                ???%
            }{%
                \fancyref@showlabel{##1}{##2}{##3}%
            }%
        }%
        \newcommand{\fancyref@define@RefDef}[3]{%
            \fancyref@newlabel{##1}{##2}{##3}%
        }%
        \newcommand{\fancyref@show@RefDef}[3]{%
            \fancyref@showlabel{##1}{##2}{##3}% Show label
        }%
    \fi%
}{%
    \PackageError{fancylabel}{This value is not allowed. Allowed values are:%
                         'continuous'(default), 'ondemand', 'referenced'.}{}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{level=}
%    \begin{macrocode}
\define@choicekey*+{fancylabel}{level}[\val\nr]{sub,same}{%
    % ##1=family
    % ##2=label
    % ##3=sublabel
    \ifcase\nr\relax%
        % level=sub
        \DeclareRobustCommand\fancysublabel[3][default]{{%
            \fancysubreftrue%
            \fancyref@subrefminusfalse%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysublabel-[3][default]{{%
            \fancysubreftrue%
            \fancyref@subrefminustrue%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysublabel*[3][default]{{%
            \renewcommand{\@@fancylabel@show}[2]{}%
            \fancysubreftrue%
            \fancyref@subrefminusfalse%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \DeclareRobustCommand\fancysubref[3][default]{{%
            \fancysubreftrue%
            \fancyref@subrefminusfalse%
            \@fancyref{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysubref-[3][default]{{%
            \fancysubreftrue%
            \fancyref@subrefminustrue%
            \@fancyref{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysubref*[3][default]{{%
            \renewcommand{\@@fancylabel@show}[2]{}%
            \fancysubreftrue%
            \fancyref@subrefminusfalse%
            \@fancyref{##1}{##2}{##3}%
        }}%
    \or%
        % level=same
        \DeclareRobustCommand\fancysublabel[3][default]{{%
            \fancysubreffalse%
            \fancyref@subrefminusfalse%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysublabel-[3][default]{{%
            \fancysubreffalse%
            \fancyref@subrefminustrue%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysublabel*[3][default]{{%
            \renewcommand{\@@fancylabel@show}[2]{}%
            \fancysubreffalse%
            \fancyref@subrefminusfalse%
            \@fancylabel{##1}{##2}{##3}%
        }}%
        \DeclareRobustCommand\fancysubref[3][default]{{%
            \fancysubreffalse%
            \fancyref@subrefminusfalse%
            \@fancyref{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysubref-[3][default]{{%
            \fancysubreffalse%
            \fancyref@subrefminustrue%
            \@fancyref{##1}{##2}{##3}%
        }}%
        \WithSuffix\DeclareRobustCommand\fancysubref*[3][default]{{%
            \renewcommand{\@@fancylabel@show}[2]{}%
            \fancysubreffalse%
            \fancyref@subrefminusfalse%
            \@fancyref{##1}{##2}{##3}%
        }}%
    \fi%
}{%
    \PackageError{fancylabel}{This value is not allowed. Allowed values are:%
                         'sub'(default), 'same'.}{}%
}
\newif\iffancyref@subrefminus\fancyref@subrefminusfalse
%    \end{macrocode}
% \end{macro}
% \begin{macro}{IgnoreFamilies=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{IgnoreFamilies}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{sort=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{sort}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{compress=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{compress}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{CompressLink=}
%    \begin{macrocode}
\define@key{fancylabel}{CompressLink}{\def\fancyref@CompressLink{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{CompressTwo=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{CompressTwo}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{ListLastSublabelOnly=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{ListLastSublabelOnly}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{ListSeparator=}
%    \begin{macrocode}
\define@key{fancylabel}{ListSeparator}{\edef\fancyref@ListSeparator{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{ListLastLabelSeparator=}
%    \begin{macrocode}
\define@key{fancylabel}{ListLastLabelSeparator}{\edef\fancyref@ListLastLabelSeparator{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{ListLastRefSeparator=}
%    \begin{macrocode}
\define@key{fancylabel}{ListLastRefSeparator}{\edef\fancyref@ListLastRefSeparator{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{DisableFamilyCheck=}
%    \begin{macrocode}
\define@boolkey{fancylabel}{DisableFamilyCheck}{}
%    \end{macrocode}
% \end{macro}
% \subsection{Error routines}
%    \begin{macrocode}
% Error routines
\newif\iffancyref@rerunerror\fancyref@rerunerrorfalse	% ReRun error
\newif\iffancysubref\fancysubreffalse	% Subref or Ref
\AtEndDocument{%
    \iffancyref@rerunerror%
        \PackageWarning{fancylabel}{Fancylabels may have changed. %
                                  Please run latex again.}%
    \fi%
}
\newcommand{\fancyref@labelerror}[2]{%
    % #1=label
    % #2=sublabel
    \ifthenelse{\equal{#2}{}}{%
        \PackageWarning{fancylabel}{Undefined fancylabel "#1".}%
    }{%
        \PackageWarning{fancylabel}{Undefined fancysublabel "#1@#2".}%
    }%
    \global\fancyref@rerunerrortrue%
}
%    \end{macrocode}
% \subsection{User macros}
% \begin{macro}{\fancylabel}
%    \begin{macrocode}
\DeclareRobustCommand\fancylabel[2][default]{{%
    % #1=family
    % #2=label or list of labels
    \fancysubreffalse%
    \@fancylabel{#1}{#2}{}%
}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancylabel*}
%    \begin{macrocode}
\WithSuffix\DeclareRobustCommand\fancylabel*[2][default]{{%
    % #1=family
    % #2=label or list of labels
    \renewcommand{\@@fancylabel@show}[2]{}%
    \fancysubreffalse%
    \@fancylabel{#1}{#2}{}%
}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref}
%    \begin{macrocode}
\DeclareRobustCommand\fancyref[2][default]{{%
    % #1=family
    % #2=label or list of labels
    \@fancyref{#1}{#2}{}%
}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref*}
%    \begin{macrocode}
\WithSuffix\DeclareRobustCommand\fancyref*[2][default]{{%
    % #1=family
    % #2=label or list of labels
    \renewcommand{\@@fancylabel@show}[2]{}%
    \@fancyref{#1}{#2}{}%
}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancylabelNewLabelEvent}
%    \begin{macrocode}
\newcommand{\fancylabelNewLabelEvent}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancylabelShowLabelEvent}
%    \begin{macrocode}
\newcommand{\fancylabelShowLabelEvent}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancylabelShowRefEvent}
%    \begin{macrocode}
\newcommand{\fancylabelShowRefEvent}{}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancylabelResetCounter}
%    \begin{macrocode}
\newcommand{\fancylabelResetCounter}[1]{%
    % #1=family
    \@ifundefined{fancylabel@familystorage@#1}{%
        \PackageError{fancylabel}{No fancylabel family '#1' defined.}{}%
    }{%
        \@namedef{fancylabel@familystorage@#1}{0}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \subsection{Helper macros}
% \begin{macro}{\@fancylabel}
%    \begin{macrocode}
\newif\iffancyref@showlabel@FirstSublabelInList%
\fancyref@showlabel@FirstSublabelInListtrue%
\newcommand{\@fancylabel}[3]{%
    % #1=family
    % #2=label or list of labels
    % #3=sublabel or list of sublabels
    \@fancylabelANDref{#1}{#2}{#3}%
    % Define labels
    \expandafter\fancyref@@sort\expandafter{\@fancylabel@list}{\@@fancylabel@define}%
    % Print labels
    \setcounter{fancyref@sort@x}{0}%
    \expandafter\fancyref@@sort\expandafter{\fancyref@compress@list}{\@@fancylabel@show}%
    \fancyref@print@list%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@fancylabelANDref}
%    \begin{macrocode}
\newcommand{\@fancylabelANDref}[3]{%
    % #1=family
    % #2=label or list of labels
    % #3=sublabel or list of sublabels
    \def\fancyref@sort@list{}%
    \def\fancyref@sort@labellist@unsorted{}%
    \def\fancyref@compress@list{}%
    \def\fancyref@print@list{}%
    \ifthenelse{\equal{#3}{}}{%
        % true => List of labels
        \newcommand{\@fancylabel@list}{#2}%
        \newcommand{\@@fancylabel@define}[2]{%
            % ##1=
            % ##2=label (from list)
            \@@@fancylabel@define{#1}{##2}{#3}%
        }%
        \newcommand{\@@fancyref@define}[2]{%
            % ##1=
            % ##2=label (from list)
            \@@@fancyref@define{#1}{##2}{#3}%
        }%
        \def\fancyref@@@@@sort{%
            fancyref@PrevRun@#1@\fancyref@@sort@value @%
        }%
        \def\fancyref@@@compress{%
            fancyref@PrevRun@#1@\fancyref@@compress@value @%
        }%
        \newcommand{\fancyref@@@compress@entry}{%
            {#1}{\fancyref@@compress@value}{}%
        }%
    }{%
        % false => List of sublabels
        \newcommand{\@fancylabel@list}{#3}%
        \newcommand{\@@fancylabel@define}[2]{%
            % ##1=
            % ##2=sublabel (from list)
            \@@@fancylabel@define{#1}{#2}{##2}%
        }%
        \newcommand{\@@fancyref@define}[2]{%
            % ##1=
            % ##2=sublabel (from list)
            \@@@fancyref@define{#1}{#2}{##2}%
        }%
        \def\fancyref@@@@@sort{%
            fancyref@PrevRun@#1@#2@\fancyref@@sort@value%
        }%
        \def\fancyref@@@compress{%
            fancyref@PrevRun@#1@#2@\fancyref@@compress@value%
        }%
        \newcommand{\fancyref@@@compress@entry}{%
            {#1}{#2}{\fancyref@@compress@value}%
        }%
    }%
    % Sort
    \fancyref@sort{\@fancylabel@list}%
    % Compress
    \fancyref@compress{\fancyref@sort@list}%
    % Add the so far undefined labels to this list
    \ifthenelse{\equal{\fancyref@sort@labellist@unsorted}{}}{}{%
        \KV@fancylabel@compressfalse%
        \fancyref@compress{\fancyref@sort@labellist@unsorted}%
        \expandafter\fancyref@addtolist\expandafter{\fancyref@sort@labellist@unsorted}%
                                                   {\fancyref@sort@list}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@@fancylabel@define}
%    \begin{macrocode}
\newcommand{\@@@fancylabel@define}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancylabel@familystorage@#1}{%
        \PackageError{fancylabel}{No fancylabel family '#1' defined. %
                                Use package option families for definition.}{}%
    }{%
        \@ifundefined{fancyref@ThisRun@#1@#2@#3}{%
            \fancyref@define@LabelUndef{#1}{#2}{#3}%
        }{%
            \fancyref@define@LabelDef{#1}{#2}{#3}%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancylabel@show}
%    \begin{macrocode}
\newcommand{\@@fancylabel@show}[2]{%
    % #1=
    % #2={<family>}{<label>}{<sublabel>},{<family>}{<label>}{<sublabel>}
    \@@fancylabelANDref@show%
    % Get first and second item
    \expandafter\fancyref@@sort\expandafter{#2}{\@@fancylabel@@show}%
    % Produce the output
    \edef\fancyref@ListLastSeparator{\fancyref@ListLastLabelSeparator}%
    \@@fancylabelANDref@show@%
    \expandafter\@@@fancylabel@show\@@fancylabel@@show@begin%
    \@@fancylabelANDref@show@@%
    % Add the \fancylabelShowLabelEvent if the label is not empty
    \ifthenelse{\equal{\fancyref@print@list}{}}{}{%
       \g@addto@macro{\fancyref@print@list}{\fancylabelShowLabelEvent}%
    }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancyref@show}
%    \begin{macrocode}
\newcommand{\@@fancyref@show}[2]{%
    % #1=
    % #2={<family>}{<label>}{<sublabel>},{<family>}{<label>}{<sublabel>}
    \@@fancylabelANDref@show%
    % Get first and second item
    \expandafter\fancyref@@sort\expandafter{#2}{\@@fancylabel@@show}%
    % Produce the output
    \edef\fancyref@ListLastSeparator{\fancyref@ListLastRefSeparator}%
    \@@fancylabelANDref@show@%
    \expandafter\@@@fancyref@show\@@fancylabel@@show@begin%
    \@@fancylabelANDref@show@@%
    % Add the \fancylabelShowRefEvent
    % Add the \fancylabelShowLabelEvent if the label is not empty
    \ifthenelse{\equal{\fancyref@print@list}{}}{}{%
       \g@addto@macro{\fancyref@print@list}{\fancylabelShowRefEvent}%
    }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancylabelANDref@show}
%    \begin{macrocode}
\newcommand{\@@fancylabelANDref@show}{%
    \edef\@@fancylabel@@show@begin{}%
    \edef\@@fancylabel@@show@begin@entry{}%
    \edef\@@fancylabel@@show@end{}%
    \edef\@@fancylabel@@show@end@entry{}%
    \edef\@@fancylabel@@show@entry{}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancylabelANDref@show@}
%    \begin{macrocode}
\newcommand{\@@fancylabelANDref@show@}{%
    \stepcounter{fancyref@sort@x}%
    \ifthenelse{\thefancyref@sort@x = \@@fancylabel@@show@LengthOfPrintList}{}{%
        % This is the last item of the list
        \ifthenelse{\equal{\@@fancylabel@@show@end}{}}{%
            \edef\fancyref@ListSeparator{\fancyref@ListLastSeparator}%
        }{}%
    }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancylabelANDref@show@@}
%    \begin{macrocode}
\newcommand{\@@fancylabelANDref@show@@}{%
    \ifthenelse{\equal{@@fancylabel@@show@entry}{}}{}{%
        % \fancyref@showlabel has been executed
        % this means a label will be printed
        \edef\@@fancylabel@@show@begin@entry{\@@fancylabel@@show@entry}%
        \ifthenelse{\equal{\@@fancylabel@@show@end}{}}{}{%
            \expandafter\@@@fancylabel@show\@@fancylabel@@show@end%
            \edef\@@fancylabel@@show@end@entry{\@@fancylabel@@show@entry}%
        }%
        % Add to list
        \ifthenelse{\equal{\@@fancylabel@@show@end@entry}{}}{%
            % No compressing
            \edef\fancyref@print@list@entry{\@@fancylabel@@show@begin@entry}%
        }{%
            % Compressing
            \edef\fancyref@print@list@entry{\@@fancylabel@@show@begin@entry%
                                            \fancyref@CompressLink%
                                            \@@fancylabel@@show@end@entry}%
        }%
        \expandafter\fancyref@addtoprintlist\expandafter{%
            \fancyref@print@list@entry%
        }{%
            \fancyref@print@list%
        }%
    }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancylabel@@show}
%    \begin{macrocode}
\newcommand{\@@fancylabel@@show}[2]{%
    % #1=
    % #2={<family>}{<label>}{<sublabel>}
    \ifthenelse{\equal{\@@fancylabel@@show@begin}{}}{%
        \edef\@@fancylabel@@show@begin{#2}%
    }{%
        \edef\@@fancylabel@@show@end{#2}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@@fancylabel@show}
%    \begin{macrocode}
\newcommand{\@@@fancylabel@show}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancylabel@familystorage@#1}{%
        \PackageError{fancylabel}{No fancylabel family '#1' defined. %
                                Use package option families for definition.}{}%
    }{%
        \@ifundefined{fancyref@ThisRun@#1@#2@#3}{%
            \fancyref@show@LabelUndef{#1}{#2}{#3}%
        }{%
            \fancyref@show@LabelDef{#1}{#2}{#3}%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@@fancyref@show}
%    \begin{macrocode}
\newcommand{\@@@fancyref@show}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancylabel@familystorage@#1}{%
        \PackageError{fancylabel}{No fancylabel family '#1' defined. %
                                Use package option families for definition.}{}%
    }{%
        \@ifundefined{fancyref@ThisRun@#1@#2@#3}{%
            \fancyref@show@RefUndef{#1}{#2}{#3}%
        }{%
            \fancyref@show@RefDef{#1}{#2}{#3}%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@fancyref}
%    \begin{macrocode}
\newcommand{\@fancyref}[3]{%
    % #1=family
    % #2=label or list of labels
    % #3=sublabel or list of sublabels
    \@fancylabelANDref{#1}{#2}{#3}%
    % Define labels
    \expandafter\fancyref@@sort\expandafter{\@fancylabel@list}{\@@fancyref@define}%
    % Print labels
    \setcounter{fancyref@sort@x}{0}%
    \expandafter\fancyref@@sort\expandafter{\fancyref@compress@list}{\@@fancyref@show}%
    \fancyref@print@list%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@fancyref}
%    \begin{macrocode}
\newcommand{\@@fancyref}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancyref@AskedThisRun@#1@#2@#3}{%
        \global\@namedef{fancyref@AskedThisRun@#1@#2@#3}{#2}%
        \immediate\write\@auxout{%
            \string\fancyref@aux{fancyref@AskedPrevRun@#1@#2@#3}{#2}%
        }%
    }{}%
    \@@@fancyref{#1}{#2}{#3}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@@fancyref@define}
%    \begin{macrocode}
\newcommand{\@@@fancyref@define}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancyref@AskedThisRun@#1@#2@#3}{%
        \global\@namedef{fancyref@AskedThisRun@#1@#2@#3}{#2}%
        \immediate\write\@auxout{%
            \string\fancyref@aux{fancyref@AskedPrevRun@#1@#2@#3}{#2}%
        }%
    }{}%
    \@ifundefined{fancyref@PrevRun@#1@#2@#3}{%
        \fancyref@define@RefUndef{#1}{#2}{#3}%
    }{%
        \fancyref@define@RefDef{#1}{#2}{#3}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@newlabel}
%    \begin{macrocode}
\newcommand{\fancyref@newlabel}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancyref@ThisRun@#1@#2@#3}{%
        \ifKV@fancylabel@DisableFamilyCheck%
        \else%
            \expandafter\fancyref@CheckOtherFamilies%
            \expandafter{\fancyref@ListOfFamilies}{#1}{#2}%
            \iffancyref@@@@CheckOtherFamilies@error%
                \PackageWarning{fancylabel}{Label '#2' has been used in %
                                            multiple families.}%
            \fi%
        \fi%
        % Subref or Ref
        \iffancysubref% Subref
            \fancyref@@newsublabel{#1}{#2}{#3}%
        \else% Ref
            \fancyref@@newlabel{#1}{#2}{#3}%
        \fi%
    }{}%
    % Show Package Warning if labels have changed since the last run
    \@ifundefined{fancyref@PrevRun@#1@#2@#3}{%	
        \global\fancyref@rerunerrortrue%
    }{%
        \ifthenelse{\equal{\@nameuse{fancyref@ThisRun@#1@#2@#3}}%
                          {\@nameuse{fancyref@PrevRun@#1@#2@#3}}}{}{%
            \global\fancyref@rerunerrortrue%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@newlabel}
%    \begin{macrocode}
\newcommand{\fancyref@@newlabel}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \ifKV@fancylabel@IgnoreFamilies%
        \setcounter{fancylabel}{\@nameuse{fancylabel@familystorage@default}}%
        \stepcounter{fancylabel}%
        \expandafter\xdef\csname fancylabel@familystorage@default\endcsname{\thefancylabel}%
    \else%
        \setcounter{fancylabel}{\@nameuse{fancylabel@familystorage@#1}}%
        \stepcounter{fancylabel}%
        \expandafter\xdef\csname fancylabel@familystorage@#1\endcsname{\thefancylabel}%
    \fi%
    \immediate\write\@auxout{%
        \string\fancyref@aux{fancyref@PrevRun@#1@#2@#3}{\thefancylabel}%
    }%
    \immediate\write\@auxout{%
        \string\fancyref@addtolist{\string{#2\string}}{\string\fancylabel@list@#1}%
    }%
    \expandafter\xdef\csname fancyref@ThisRun@#1@#2@#3\endcsname{\thefancylabel}%
    % Uses specified Event following the newlabel command
    \fancylabelNewLabelEvent%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@newsublabel}
%    \begin{macrocode}
\newcommand{\fancyref@@newsublabel}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \@ifundefined{fancyref@ThisRun@#1@#2@}{%
        \fancyref@@newlabel{#1}{#2}{}%
    }{}%
    \@ifundefined{fancyref@highestsub@#1@#2}{%        
        \setcounter{fancysublabel}{0}%
    }{%
        \setcounter{fancysublabel}{\@nameuse{fancyref@highestsub@#1@#2}}%
    }%
    \stepcounter{fancysublabel}%
    \immediate\write\@auxout{%
        \string\fancyref@aux{fancyref@PrevRun@#1@#2@#3}{\thefancysublabel}%
    }%
    \expandafter\xdef\csname fancyref@ThisRun@#1@#2@#3\endcsname{\thefancysublabel}%
    \expandafter\xdef\csname fancyref@highestsub@#1@#2\endcsname{\thefancysublabel}%	
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@showlabel}
%    \begin{macrocode}
\newcommand{\fancyref@showlabel}[3]{%
    % #1=family
    % #2=label
    % #3=sublabel
    \iffancysubref% \fancysubref and level=sub
        \@ifundefined{fancyref@PrevRun@#1@#2@}{%
            \fancyref@rerunerrortrue%
        }{%
            \setcounter{fancylabel}{\@nameuse{fancyref@PrevRun@#1@#2@}}%
        }%
        \@ifundefined{fancyref@PrevRun@#1@#2@#3}{%
            \fancyref@rerunerrortrue%
        }{%
            \setcounter{fancysublabel}{\@nameuse{fancyref@PrevRun@#1@#2@#3}}%
        }%
        \iffancyref@subrefminus% minus => only subref without ref
            \ifKV@fancylabel@IgnoreFamilies%
                \edef\fancylabelthisformat{\@nameuse{fancyonlysublabelformatdefault}}%
            \else%
                \edef\fancylabelthisformat{\@nameuse{fancyonlysublabelformat#1}}%
            \fi%
        \else% Label and Sublabel
            \iffancyref@showlabel@FirstSublabelInList%
                % This is the very first label
                \ifKV@fancylabel@IgnoreFamilies%
                    \edef\fancylabelthisformat{\@nameuse{fancysublabelformatdefault}}%
                \else%
                    \edef\fancylabelthisformat{\@nameuse{fancysublabelformat#1}}%
                \fi%
                \fancyref@showlabel@FirstSublabelInListfalse%
            \else%
                % Any label after the first one
                \ifKV@fancylabel@ListLastSublabelOnly%
                    % Output: 1a-c,d
                    \ifKV@fancylabel@IgnoreFamilies%
                        \edef\fancylabelthisformat{\@nameuse{fancyonlysublabelformatdefault}}%
                    \else%
                        \edef\fancylabelthisformat{\@nameuse{fancyonlysublabelformat#1}}%
                    \fi%
                \else%
                    % Output: 1a-1c,1d
                    \ifKV@fancylabel@IgnoreFamilies%
                        \edef\fancylabelthisformat{\@nameuse{fancysublabelformatdefault}}%
                    \else%
                        \edef\fancylabelthisformat{\@nameuse{fancysublabelformat#1}}%
                    \fi%
                \fi%
            \fi%
        \fi%
    \else% \fancyref or \fancysubref and level=same
        \@ifundefined{fancyref@PrevRun@#1@#2@#3}{%
            \fancyref@rerunerrorfalse%
        }{%
            \setcounter{fancylabel}{\@nameuse{fancyref@PrevRun@#1@#2@#3}}%
        }%
        \ifKV@fancylabel@IgnoreFamilies%
            \edef\fancylabelthisformat{\@nameuse{fancylabelformatdefault}}%
        \else%
            \edef\fancylabelthisformat{\@nameuse{fancylabelformat#1}}%
        \fi%
    \fi%	
    \edef\@@fancylabel@@show@entry{\fancylabelthisformat}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@CheckOtherFamilies}
%    \begin{macrocode}
\newcommand{\fancyref@CheckOtherFamilies}[3]{%
    % #1=list of families
    % #2=current family
    % #3=label
    \fancyref@foreach{\fancyref@@CheckOtherFamilies{#3}}{#2}{#1}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@CheckOtherFamilies}
%    \begin{macrocode}
\newcommand{\fancyref@@CheckOtherFamilies}[3]{%
    % #1=label
    % #2=current family
    % #3=family (from list)
    \xdef\fancyref@helper{\csname fancylabel@list@#3\endcsname}%
    \ifthenelse{\equal{#2}{#3}}{}{%
        \expandafter\fancyref@@@CheckOtherFamilies\expandafter{\fancyref@helper}{#1}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@CheckOtherFamilies}
%    \begin{macrocode}
\newcommand{\fancyref@@@CheckOtherFamilies}[2]{%
    % #1=list of labels
    % #2=label
    \fancyref@foreach{\fancyref@@@@CheckOtherFamilies}{#2}{#1}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@@CheckOtherFamilies}
%    \begin{macrocode}
\newif\iffancyref@@@@CheckOtherFamilies@error
\fancyref@@@@CheckOtherFamilies@errorfalse
\newcommand{\fancyref@@@@CheckOtherFamilies}[2]{%
    % #1=label
    % #2=label (from list)
    \ifthenelse{\equal{#1}{#2}}{%
        \fancyref@@@@CheckOtherFamilies@errortrue%
    }{}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@aux}
%    \begin{macrocode}
\newcommand{\fancyref@aux}[2]{% Helps to read the aux file
    \global\@namedef{#1}{#2}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@foreach}
%    \begin{macrocode}
%%% Thanks to 
%%% http://stackoverflow.com/questions/2402354/split-comma-separated-parameters-in-latex
% Functional foreach construct 
% #1 - Function to call on each comma-separated item in #3
% #2 - Parameter to pass to function in #1 as first parameter
% #3 - Comma-separated list of items to pass as second parameter to function #1
\def\fancyref@foreach#1#2#3{%
    \fancyref@@test@foreach{#1}{#2}#3,\@end@token%
}

% Internal helper function - Eats one input
\def\fancyref@@swallow#1{}

% Internal helper function - Checks the next character after #1 and #2 and 
% continues loop iteration if \@end@token is not found 
\def\fancyref@@test@foreach#1#2{%
    \@ifnextchar\@end@token%
        {\fancyref@@swallow}%
        {\fancyref@@foreach{#1}{#2}}%
}

% Internal helper function - Calls #1{#2}{#3} and recurses
% The magic of splitting the third parameter occurs in the pattern matching of the \def
\def\fancyref@@foreach#1#2#3,#4\@end@token{%
    #1{#2}{#3}%
    \fancyref@@test@foreach{#1}{#2}#4\@end@token%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\newcounter{fancyref@sort@x}
\setcounter{fancyref@sort@x}{0}
\newcounter{fancyref@sort@y}
\setcounter{fancyref@sort@y}{0}
%    \end{macrocode}
% \begin{macro}{\fancyref@sort}
%    \begin{macrocode}
\newcommand{\fancyref@sort}[1]{%
    % #1=comma-separated list of labels or sublabels
    \ifKV@fancylabel@sort%
        % Generate a list of all values
        \def\fancyref@sort@valuelist@sorted{}%
        \setcounter{fancyref@sort@x}{0}%
        \expandafter\fancyref@@sort\expandafter{#1}{\fancyref@@@sort}%
        % Generate a sorted list of values
        \edef\fancyref@sort@arraylength{\thefancyref@sort@x}%
        \setcounter{fancyref@sort@x}{0}%
        \whiledo{\thefancyref@sort@x < \fancyref@sort@arraylength}{%
            \setcounter{fancyref@sort@y}{0}%
            % Set \fancyref@sort@smallest@temp the first list entry that is not 0
            \whiledo{\thefancyref@sort@y < \fancyref@sort@arraylength}{%
                \ifthenelse{\@nameuse{fancyref@sort@valuelist@\thefancyref@sort@y} = 0}{%
                    \stepcounter{fancyref@sort@y}%
                }{%
                    \edef\fancyref@sort@smallest@temp{\thefancyref@sort@y}%
                    \setcounter{fancyref@sort@y}{\fancyref@sort@arraylength}%
                }%
            }%
            \setcounter{fancyref@sort@y}{0}%
            % Find the smallest value in the list
            \whiledo{\thefancyref@sort@y < \fancyref@sort@arraylength}{%
                \ifthenelse{\@nameuse{fancyref@sort@valuelist@\thefancyref@sort@y} = 0}{}{%
                    \ifthenelse{\@nameuse{fancyref@sort@valuelist@\thefancyref@sort@y} < % 
                                \@nameuse{fancyref@sort@valuelist@\fancyref@sort@smallest@temp}}{%
                        \edef\fancyref@sort@smallest@temp{\thefancyref@sort@y}%
                    }{}%
                }%
                \stepcounter{fancyref@sort@y}%
            }%
            % Add this smallest value to the list
            \edef\fancyref@sort@smallest{%
                \@nameuse{fancyref@sort@valuelist@\fancyref@sort@smallest@temp}%
            }%
            \expandafter\fancyref@addtolist\expandafter{\fancyref@sort@smallest}%
                                                       {\fancyref@sort@valuelist@sorted}%
            \expandafter\edef\csname fancyref@sort@valuelist@\fancyref@sort@smallest@temp\endcsname{0}%
            \stepcounter{fancyref@sort@x}%
        }%
        % Generate a sorted list of labels
        \ifthenelse{\equal{\fancyref@sort@valuelist@sorted}{}}{}{%
            \expandafter\fancyref@@sort\expandafter{\fancyref@sort@valuelist@sorted}{\fancyref@@@@sort}%
        }%
    \else%
        \expandafter\fancyref@addtolist\expandafter{#1}{\fancyref@sort@list}%
    \fi%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@sort}
%    \begin{macrocode}
\newcommand{\fancyref@@sort}[2]{%
    % #1=comma-separated list
    % #2=function to be executed on this list
    \fancyref@foreach{#2}{}{#1}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@sort}
%    \begin{macrocode}
\newcommand{\fancyref@@@sort}[2]{%
    % #1=
    % #2=label (from list)
    \def\fancyref@@sort@value{#2}%
    \@ifundefined{\fancyref@@@@@sort}{%
        \fancyref@addtolist{#2}{\fancyref@sort@labellist@unsorted}%
    }{%
        \expandafter\edef\csname fancyref@sort@labellist@\@nameuse{\fancyref@@@@@sort}\endcsname{#2}%
        \expandafter\edef\csname fancyref@sort@valuelist@\thefancyref@sort@x\endcsname{%
            \@nameuse{\fancyref@@@@@sort}%
        }%
        \stepcounter{fancyref@sort@x}%
    }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@@sort}
%    \begin{macrocode}
\newcommand{\fancyref@@@@sort}[2]{%
    % #1=
    % #2=value (from sorted list of values)
    \fancyref@addtolist{\@nameuse{fancyref@sort@labellist@#2}}{\fancyref@sort@list}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@compress}
%    \begin{macrocode}
\newcommand{\fancyref@compress}[1]{%
    % #1=list of labels or sublabels
    \def\fancyref@compress@begin{}%
    \def\fancyref@compress@begin@entry{}%
    \def\fancyref@compress@end{}%    
    \def\fancyref@compress@end@entry{}%
    \setcounter{fancyref@sort@y}{0}%
    \ifKV@fancylabel@compress%
        \ifthenelse{\equal{#1}{}}{}{%
            % Compress List
            \expandafter\fancyref@@sort\expandafter{#1}{\fancyref@@compress}%
            % Add last entry
            \fancyref@@@@compress@stop%
        }%
    \else%
        \expandafter\fancyref@@sort\expandafter{#1}{\fancyref@@nocompress}%
    \fi%
    \edef\@@fancylabel@@show@LengthOfPrintList{\thefancyref@sort@y}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@compress}
%    \begin{macrocode}
\newcommand{\fancyref@@compress}[2]{%
    % #1=
    % #2=value (from sorted list of values)
    \def\fancyref@@compress@value{#2}%
    \ifthenelse{\equal{\fancyref@compress@begin}{}}{%
        % Start compressing
        \fancyref@@@@compress@start%
    }{%
        \stepcounter{fancyref@sort@x}%
        \ifthenelse{\@nameuse{\fancyref@@@compress} = \thefancyref@sort@x}{%
            % Continue compressing
            \fancyref@@@@compress@continue%
        }{%
            % Stop compressing and begin a new compressing
            \fancyref@@@@compress@stop%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@@compress@start}
%    \begin{macrocode}
\newcommand{\fancyref@@@@compress@start}{%
    \edef\fancyref@compress@begin{\fancyref@@@compress}%
    \edef\fancyref@compress@begin@entry{\fancyref@@@compress@entry}%
    \setcounter{fancyref@sort@x}{\@nameuse{\fancyref@compress@begin}}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@@compress@continue}
%    \begin{macrocode}
\newcommand{\fancyref@@@@compress@continue}{%
    \edef\fancyref@compress@end{\fancyref@@@compress}%
    \edef\fancyref@compress@end@entry{\fancyref@@@compress@entry}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@@@compress@stop}
%    \begin{macrocode}
\newcommand{\fancyref@@@@compress@stop}{%
    \ifKV@fancylabel@CompressTwo%
        % Compress even if difference is only 1
        \edef\fancyref@compress@listentry{{{\fancyref@compress@begin@entry},{\fancyref@compress@end@entry}}}%
        \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
    \else%
        % Compress if difference > 1
        \setcounter{fancyref@sort@x}{\@nameuse{\fancyref@compress@begin}}%
        \stepcounter{fancyref@sort@x}%
        % Avoid empty \fancyref@compress@end
        \ifthenelse{\equal{\fancyref@compress@end}{}}{%
            \edef\fancyref@compress@listentry{{{\fancyref@compress@begin@entry},{\fancyref@compress@end@entry}}}%
            \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
        }{%
            \ifthenelse{\@nameuse{\fancyref@compress@end} = \thefancyref@sort@x}{%
                % Difference = 1
                \edef\fancyref@compress@listentry{{{\fancyref@compress@begin@entry},{}}}%
                \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
                \edef\fancyref@compress@listentry{{{\fancyref@compress@end@entry},{}}}%
                \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
            }{%
                % Difference > 1
                \edef\fancyref@compress@listentry{%
                    {{\fancyref@compress@begin@entry},{\fancyref@compress@end@entry}}%
                }%
                \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
            }%
        }%
    \fi%
    \edef\fancyref@compress@begin{\fancyref@@@compress}%
    \edef\fancyref@compress@begin@entry{\fancyref@@@compress@entry}%
    \edef\fancyref@compress@end{}%
    \edef\fancyref@compress@end@entry{}%
    \setcounter{fancyref@sort@x}{\@nameuse{\fancyref@compress@begin}}%
    \stepcounter{fancyref@sort@y}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fancyref@@nocompress}
%    \begin{macrocode}
\newcommand{\fancyref@@nocompress}[2]{%
    % #1=
    % #2=value (from sorted list of values)
    \stepcounter{fancyref@sort@y}%
    \def\fancyref@@compress@value{#2}%
    \edef\fancyref@compress@listentry{{{\fancyref@@@compress@entry},{}}}%
    \expandafter\fancyref@addtolist\expandafter{\fancyref@compress@listentry}{\fancyref@compress@list}%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\ProcessOptionsX<fancylabel>
%    \end{macrocode}
%
%
\endinput
% \Finale
