From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 macros/latex/contrib/dataref/tex/dataref.sty | 952 +++++++++++++++++++++++++++
 1 file changed, 952 insertions(+)
 create mode 100644 macros/latex/contrib/dataref/tex/dataref.sty

(limited to 'macros/latex/contrib/dataref/tex/dataref.sty')

diff --git a/macros/latex/contrib/dataref/tex/dataref.sty b/macros/latex/contrib/dataref/tex/dataref.sty
new file mode 100644
index 0000000000..bb6f013032
--- /dev/null
+++ b/macros/latex/contrib/dataref/tex/dataref.sty
@@ -0,0 +1,952 @@
+%%  Copyright 2013-2017 Christian Dietrich
+%%
+%% 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 Christian Dietrich
+%%
+%% This work consists of the files dataref.dtx and dataref.ins
+%% and the derived file dataref.sty.
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+\ProvidesPackage{dataref}[2017/01/06 v0.6 dataref]
+
+\ifx\drefloaded\undefined
+  \let\drefloaded=\relax
+\else
+  \expandafter\endinput
+\fi
+
+\def\drefutil@packageerror#1#2#3{\errhelp{#3}\errmessage{Package #1 Error: #2}}
+\def\drefutil@packagewarning#1#2{\immediate\write17{Package #1: Warning! #2.}}
+\def\dref@error#1{\drefutil@packageerror{dref}{#1}{}}
+\def\dref@warning#1{\drefutil@packagewarning{dref}{#1}}
+
+\RequirePackage{pgf}
+\usepgflibrary{fpu}
+\RequirePackage{iftex}
+\RequirePackage{kvoptions}
+\RequirePackage{etoolbox}
+
+\SetupKeyvalOptions{
+  family=dref,
+  prefix=dref@
+}
+\DeclareStringOption[/data]{datapath}
+\DeclareStringOption[1]{defaultvalue}
+\DeclareStringOption[none]{annotate}
+\DeclareBoolOption{usagereport}
+\DeclareBoolOption{refall}
+\DeclareBoolOption{ignoremissing}
+\DeclareBoolOption{noassert}
+\ProcessKeyvalOptions*
+
+% Load & Store Layer
+
+\def\dref@set#1#2#3{%
+  \edef\dref@set@path{#3}%
+  \edef\dref@set@value{#2}%
+  \expandafter\pgfkeys@temptoks\expandafter{\dref@set@value}%
+  \expandafter\xdef%
+      \csname pgfk@\dref@datapath\dref@set@path\endcsname%
+  {\the\pgfkeys@temptoks}%
+  % Setting the Unit is a little bit more tricky
+  %% Unit Path Assembly
+  \expandafter\def%
+  \expandafter\dref@set@unitpath%
+  \expandafter{%
+  \csname pgfk@\dref@datapath\dref@set@path @unit\endcsname}%
+  \expandafter\gdef\dref@set@unitpath{#1}%
+  \ifdref@refall%
+     \expandafter\dref@found\expandafter{\dref@set@path}{0}
+     \expandafter\dref@referenced\expandafter{\dref@set@path}{0}%
+  \fi%
+  \dref@debug{\dref@set@path = \dref@set@value (\detokenize{#1})}%
+}
+
+\def\dref@load#1#2#3{%
+  \edef\dref@load@path{#1}%
+  \pgfkeysifdefined{\dref@datapath\dref@load@path}{%
+    \pgfkeysgetvalue{\dref@datapath\dref@load@path}{#2}%
+    \pgfkeysifdefined{\dref@datapath\dref@load@path @unit}{%
+      \pgfkeysgetvalue{\dref@datapath\dref@load@path @unit}{#3}%
+    }{%
+      \def#3{}%
+    }%
+  }{%
+    \edef#2{\dref@defaultvalue}%
+    \def#3{}%
+  }%
+}
+
+\def\drefifdefined#1{%
+  \pgfkeysifdefined{\dref@datapath\drefprefix #1}%{then}{else}
+}
+
+\def\dref@set@fromaux#1#2#3{%
+  \drefifdefined{#2}{%
+    \dref@warning{"\drefprefix #2" set before beginning of document, \string\drefsave{} is ignore}%
+  }{%
+    \dref@set{#1}{#2}{#3}%
+  }%
+}
+
+\def\drefkeys#1{\pgfkeys{/dref/.cd,#1}}
+\def\drefprefix{\pgfkeysvalueof{/dref/prefix}}
+\newif\ifdref@debug
+\def\dref@debug#1{\ifdref@debug \immediate\write17{Package dref: Debug: #1.}\fi}
+
+\drefkeys{
+  .is family,
+  .search also={/pgf/number format},
+  % The @init action is used to initialize all other actions
+  @[/.code={\begingroup%
+    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}% No more dimensions too large
+    \def\drefunit{}% At first we are unitless
+    \aftergroup\edef%
+    \aftergroup\drefresult%
+    \aftergroup{%
+      \aftergroup\drefresult@smuggle%
+      \aftergroup}%
+    \aftergroup\expandafter%
+    \aftergroup\def%
+    \aftergroup\expandafter%
+    \aftergroup\drefunit%
+    \aftergroup\expandafter%
+    \aftergroup{%
+      \aftergroup\drefunit@smuggle%
+      \aftergroup}
+  },
+  @]/.code={% We smuggle \drefresult after the current group
+    \xdef\drefresult@smuggle{\drefresult}%
+    \xdef\drefunit@smuggle{\expandonce\drefunit}%
+    \endgroup%
+  },
+  @init/.style={},
+  % The \drefresult macro holds the current value,
+  % it can be set by value=
+  prefix/.initial={},
+  value/.code={\edef\drefresult{#1}\def\drefunit{}},
+  value=0,
+  path/.estore in={\drefcurrentpath},
+  @init/.append style={},
+  % \drefresult can be set by the @load action
+  @load key to/.code n args={3}{%
+    \dref@load{\drefprefix #1}{#2}{#3}%
+  },
+  @get key to/.style n args={3}{
+    @check key={#1},
+    @reference key={#1},
+    @load key to={#1}{#2}{#3},
+  },
+  @get/.style={%
+    @get key to={\drefcurrentpath}{\drefresult}{\drefunit},
+    unit/@format enable,
+  },
+  % For most commands, we want to check whether a key exists.
+  @check key/.code={%
+    \drefifdefined{#1}{}{%
+      \ifdref@ignoremissing%
+        \dref@warning{undefined key `\drefprefix #1'}%
+      \else%
+        \dref@error{undefined key `\drefprefix #1'}%
+      \fi%
+    }%
+  },
+  % The @set action is used to pipe out \drefresult, before we can
+  % print it. For example, we can use it to save the result to a new
+  % key.
+  @init/.append style={
+    @set/.code={},
+  },
+  set/.style={
+    @set/.append code={%
+      \expandafter\dref@set\expandafter{\drefunit}{\drefresult}{\drefprefix #1}%
+    }
+  },
+  save/.style={
+    set={#1},
+    @set/.append code={%
+      \immediate\write\@auxout{%
+        \noexpand\dref@set@fromaux{\expandonce\drefunit}{\drefresult}{\drefprefix #1}%
+      }%
+    }
+  },
+  to macro/.style={
+    @set/.append code={%
+      \aftergroup\edef%
+      \aftergroup#1%
+      \aftergroup{%
+        \aftergroup\drefresult%
+        \aftergroup}}
+  },
+  %
+  debug/.is if=dref@debug,
+  ignoremissing/.is if=dref@ignoremissing,
+  defaultvalue/.store in=\dref@defaultvalue,
+}
+
+\csdef{dref@ifnum@0}{}
+\csdef{dref@ifnum@1}{}
+\csdef{dref@ifnum@2}{}
+\csdef{dref@ifnum@3}{}
+\csdef{dref@ifnum@4}{}
+\csdef{dref@ifnum@5}{}
+\csdef{dref@ifnum@6}{}
+\csdef{dref@ifnum@7}{}
+\csdef{dref@ifnum@8}{}
+\csdef{dref@ifnum@9}{}
+\csdef{dref@ifnum@-}{}
+\csdef{dref@ifnum@.}{}
+\def\dref@load@ifkey@firstchar#1#2\@nnil{#1}
+\drefkeys{%
+  @get key or value to/.code n args={3}{%
+    \edef\dref@load@path{#1}%
+    \edef\dref@firstchar{\expandafter\dref@load@ifkey@firstchar \dref@load@path\@nnil}%
+    \ifcsdef{dref@ifnum@\dref@firstchar}{%
+      \edef#2{\dref@load@path}%
+    }{%
+      \drefkeys{@get key to={#1}{#2}{#3}}%
+    }%
+  },
+  @get key or value/.style={
+    @get key or value to={\drefcurrentpath}{\drefresult}{\drefunit},
+    unit/@format enable,
+  },
+}
+
+
+% Print layer
+\drefkeys{
+  @init/.append style={
+    @print result/.code={},
+    @print unit/.code={}
+  },
+  @print/.style={@print result, @print unit},
+  print default/.initial={pgf},
+  print/.is choice,
+  print/no/.style={
+    @print result/.code={},
+    @print unit/.code={}
+  },
+  print/default/.style={%
+    print default/.get=\dref@print@format,%
+    print/.expand once=\dref@print@format,
+  },
+  print/raw/.style={
+    @print result/.code={\drefresult}
+  },
+  print/typeout/.style={
+    @print result/.code={\typeout{#1\drefresult}},
+    @print unit/.code={\typeout{\expandonce\drefunit}},
+  },
+  print/show/.style={
+    @print result/.append code={\show\drefresult},
+  },
+  print/pgf/.style={
+    @print result/.code={%
+      \pgfmathprintnumber{\drefresult}%
+    }
+  },
+  print/siunitx/.style={
+    @print result/.code={%
+      \num{\drefresult}%
+    }
+  },
+}
+
+% Compatibility with underscore package
+\def\dref@normalunderscore{_}
+\edef\dref@catcode@underscore{\the\catcode`_}
+\catcode`_=13
+\def\dref@catcode@setup{%
+  \edef _{\dref@normalunderscore}%
+}
+\catcode`_=\dref@catcode@underscore
+
+
+\AtBeginDocument{%
+  \ifdim 13pt = \the\catcode`_pt%
+    % _ is an active character
+    \drefkeys{@[/.append code={%
+        \dref@catcode@setup%
+     }%
+   }%
+  \fi%
+}
+
+\newcommand{\drefset}[3][]{%
+  % I put this version here, since it
+  % provides a sped up mass setting of keys
+  \begingroup%
+    \ifdim 13pt = \the\catcode`_pt%
+      \dref@catcode@setup%
+    \fi%
+    \edef\drefresult{#3}%
+    \def\drefunit{}%
+    \drefkeys{#1}%
+    \expandafter\dref@set\expandafter{\drefunit}%
+       {\drefresult}{\drefprefix #2}%
+  \endgroup%
+}
+
+\newcommand{\drefsave}[3][]{%
+  \drefkeys{@[, @init, value={#3}, #1, save={#2}, @set, @]}%
+}
+
+\newcommand{\drefinput}[2][]{%
+  \begingroup
+  \drefkeys{prefix/.append={#1}}
+  \input{data/#2}
+  \endgroup
+}
+
+
+\def\drefref#1{\drefkeys{@reference key={#1}}}
+
+% From here on, everything should be implemented using pgfkeys
+\protected\def\dref{\@ifstar\dref@starred\dref@unstarred}
+\newcommand{\dref@unstarred}[2][]{%
+  \drefkeys{@[, @init, print=default, path={#2}, #1, @get, @calc, @print, @set,%
+    @annotate={\textbackslash dref[#1]\{#2\}}, @]%
+  }%
+}
+\newcommand{\dref@starred}[2][]{%
+  \drefkeys{@[, @init, print=raw,     path={#2}, #1, @get, @calc, @print, @set,%
+    @annotate={\textbackslash dref*[#1]\{#2\}}, @]%
+  }%
+}
+\def\drefgetvalue#1#2{%
+  \drefkeys{@[,@init, path={#1}, to macro={#2}, @get, @set, @]}%
+}
+\def\drefvalueof#1{%
+  \pgfkeysvalueof{\dref@datapath \drefprefix #1}%
+}
+
+%% dref@ifstrmatch is copied from etextools, but etextools is
+%% incompatible with etoolbox
+%% \ifstrmatch{ pattern }{ string }{ true }{ false }
+\ifPDFTeX%
+  \let\dref@strmatch\pdfmatch
+\fi
+\ifLuaTeX%
+ \newcommand{\dref@strmatch}[2]{%
+  \directlua{%
+    local match = string.find("\luaescapestring{#2}", "\luaescapestring{#1}");%
+    if match then
+      tex.print("1");
+    else
+      tex.print("0");
+    end
+  }%
+}
+\fi
+\long\def\dref@firstoftwo#1#2{\z@#1} %% for romannumeral
+\long\def\dref@secondoftwo#1#2{\z@#2}%% for romannumeral
+\newcommand{\dref@ifstrmatch}[2]{%
+  \romannumeral\csname dref@%
+  \ifnum\dref@strmatch{#1}{#2}=1 first\else second\fi oftwo\endcsname%
+}
+\newcommand{\dref@help@match}[2]{%
+  \dref@ifstrmatch{#1}{#2}%
+}
+\newcommand{\dref@help}[2][]{%
+  \pgfkeysifdefined{#2/help}{%
+    \pgfkeysvalueof{#2/help}%
+  }{#1}%
+}
+\csdef{dref@helps}{}
+\newcommand{\drefsethelp}[2]{
+  \csdef{dref@help@#1}{#2}%
+  \listcsadd{dref@helps}{#1}%
+}
+\newcommand{\drefhelp}[1]{
+  \renewcommand{\do}[1]{%
+    \dref@help@match{##1}{#1}{%
+      \csuse{dref@help@##1}%
+    \listbreak}{}%
+  }%
+  \ifcsvoid{dref@helps}{}{%
+    \dolistcsloop{dref@helps}%
+  }%
+}
+\drefkeys{
+  @reference key/.code={%
+    \edef\dref@thepage{\arabic{page}}%
+    \drefifdefined{#1}{%
+      \immediate\write\@auxout{%
+        \noexpand\dref@found{\drefprefix #1}{\dref@thepage}}%
+    }{%
+      \immediate\write\@auxout{%
+        \noexpand\dref@notfound{\drefprefix #1}{\dref@thepage}}%
+    }%
+    \immediate\write\@auxout{%
+      \noexpand\dref@referenced{\drefprefix #1}{\dref@thepage}}%
+  }
+}
+\def\dref@notfound#1#2{
+  \ifdref@usagereport%
+    \dref@usagereport@notfound{#1}{#2}%
+  \else\relax\fi%
+}
+\def\dref@found#1#2{
+  \ifdref@usagereport%
+    \dref@usagereport@found{#1}{#2}%
+  \else\relax\fi%
+}
+\def\dref@referenced#1#2{
+  \ifdref@usagereport%
+    \dref@usagereport@referenced{#1}{#2}%
+  \else\relax\fi%
+}
+
+
+% The data("") || d() Parser
+\def\dref@parser#1#2{%
+  \edef\@tempa{#1}%
+  \csdef{dref@parser@result}{}%
+  \csdef{dref@parser@state}{}%
+  \expandafter\dref@parser@parse\@tempa\@nnil%
+  \xdef#2{\csuse{dref@parser@result}}%
+}
+
+\def\dref@parser@parse#1#2\@nnil{%
+  %\typeout{#1 State: \csuse{dref@parser@state}}%
+  \ifblank{#1#2}{%
+    \csxdef{dref@parser@result}{\csuse{dref@parser@result}\csuse{dref@parser@state}}%
+  }{%
+    \ifcsdef{dref@parser@\csuse{dref@parser@state}@#1}{%
+      \csuse{dref@parser@\csuse{dref@parser@state}@#1}#2\@nnil%
+    }{%
+      \csxdef{dref@parser@result}{\csuse{dref@parser@result}\csuse{dref@parser@state}#1}%
+      \csdef{dref@parser@state}{}%
+      \ifblank{#2}{}{%
+        \dref@parser@parse#2\@nnil%
+      }%
+    }%
+  }%
+}
+
+\csdef{dref@parser@@d}{\csdef{dref@parser@state}{d}\dref@parser@parse}
+\csdef{dref@parser@d@a}{\csdef{dref@parser@state}{da}\dref@parser@parse}
+\csdef{dref@parser@da@t}{\csdef{dref@parser@state}{dat}\dref@parser@parse}
+\csdef{dref@parser@dat@a}{\csdef{dref@parser@state}{data}\dref@parser@parse}
+\csdef{dref@parser@data@(}{\csdef{dref@parser@state}{data(}\dref@parser@parse}
+\csdef{dref@parser@data(@"}{\dref@parser@tillquote}
+\csdef{dref@parser@d@(}{\dref@parser@tillparen}
+
+\def\dref@parser@tillquote#1")#2\@nnil{%
+  \drefkeys{
+    @get key to={#1}{\dref@math@value}{\dref@math@unit},
+    unit/@combine=\dref@math@unit,
+  }%
+  \csxdef{dref@parser@result}{\csuse{dref@parser@result}(\dref@math@value)}%
+  \csdef{dref@parser@state}{}%
+  \ifblank{#2}{}{\dref@parser@parse#2\@nnil}}
+
+\def\dref@parser@tillparen#1)#2\@nnil{%
+  \drefkeys{@get key to={#1}{\dref@math@value}{\dref@math@unit},
+            unit/@combine=\dref@math@unit}%
+  \csxdef{dref@parser@result}{\csuse{dref@parser@result}(\dref@math@value)}%
+  \csdef{dref@parser@state}{}%
+  \ifblank{#2}{}{\dref@parser@parse#2\@nnil}}%
+
+\def\dref@parser@end#1#2\@nnil{}
+\csdef{dref@parser@@}{\dref@parser@end}
+
+\drefkeys{
+  @init/.append style={%
+    @calc/.code={},%
+  },
+  @calc pgf/.style={
+    @calc/.append code={%
+      \dref@parser{#1}{\dref@calc@@ready}%
+      \pgfmathparse{\dref@calc@@ready}%
+      \dref@debug{#1 -> \dref@calc@@ready = \pgfmathresult}%
+      \edef\drefresult{\pgfmathresult}%
+     }
+  }
+}
+
+\protected\def\drefcalc{\@ifstar\drefcalc@starred\drefcalc@unstarred}
+\newcommand{\drefcalc@unstarred}[2][]{% Unstarred
+  \drefkeys{@[,@init, print=default, @calc pgf={#2}, #1, @calc, @print, @set,%
+    @annotate={\textbackslash drefcalc[#1]\{#2\}},@]}%
+}
+\newcommand{\drefcalc@starred}[2][]{ % Starred
+  \drefkeys{@[,@init, @calc pgf={#2}, #1, @calc, @set,%
+    @annotate={\textbackslash \drefcalc*[#1]\{#2\}},@]%
+  }%
+}
+
+\newcommand{\drefformat}[2][]{%
+  \drefkeys{@[,@init, print=default, value={#2}, #1, @calc, @print, @]}%
+}
+
+\long\def\drefprojection#1#2#3{%
+  \begingroup%
+  \def\rename##1##2{%
+    \drefkeys{@init, path={#1/##1}, set={#2/##2}, @get, @set}%
+  }%
+  \def\id##1{\rename{##1}{##1}}%
+  \def\calc##1##2{%
+    \edef\drefprojection@prefix{\drefprefix}%
+    \drefcalc[prefix={#1}]{##1}%
+    \edef\drefprefix{\drefprojection@prefix}%
+    \drefset{#2/##2}{\drefresult}%
+  }%
+  #3%
+  \endgroup%
+}
+
+
+\newtoks\dref@toks
+\newcount\drefcellcount
+
+\newcommand{\dref@makerow}[2]{%
+  {\global\dref@toks={}%
+    \drefcellcount=\z@%
+    \def\do##1{%
+      \advance\drefcellcount\@ne%
+      \def\@tempa{\doX{##1}}%
+      \expandafter\@tempa\expandafter{\the\drefcellcount}%
+    }%
+    \def\doX##1##2{%
+      \csxdef{@cell\the\drefcellcount}{\detokenize{%
+          #2%
+        }}%
+    }%
+    \expandafter\def\expandafter\arglist\expandafter{#1}%
+    \expandafter\docsvlist\expandafter{\arglist}%
+    \@tempcntb=0\relax%
+    {\loop\ifnum\@tempcntb<\drefcellcount%
+      \advance\@tempcntb by 1\relax%
+      \ifnum \@tempcntb = 1%
+        \edef\@@next{\csuse{@cell\the\@tempcntb}}%
+      \else%
+        \edef\@@next{&\csuse{@cell\the\@tempcntb}}%
+      \fi%
+      \global%
+      \dref@toks%
+      \expandafter=%
+      \expandafter{%
+        \the%
+        \expandafter\dref@toks%
+        \@@next}%
+      \repeat}%
+  }%
+  \expandafter\scantokens\expandafter{\the\dref@toks}%
+}
+
+\long\def\drefrow{\@ifstar{\drefrow@starred}{\drefrow@unstarred}}
+\newcommand{\drefrow@unstarred}[3][]{\dref@makerow{#2}{\dref[#1]{#3}}\ignorespaces}
+\def\drefrow@starred#1#2{\dref@makerow{#1}{#2}\ignorespaces}
+
+\expandafter\ifstrequal\expandafter{\dref@annotate}{pdfcomment}{
+  \RequirePackage{pdfcomment}
+}
+
+
+\drefkeys{
+  annotate/.is choice,
+  annotate/none/.style={@annotate/.code={\relax}},
+  annotate/footnote/.style={@annotate/.code={\footnote{\texttt{##1}}}},
+  annotate/pdfcomment/.style={@annotate/.code={\pdfcomment[opacity=0.4,voffset=2ex]{##1}}},
+  annotate/typeout/.style={@annotate/.code={\typeout{##1}}},
+  annotate=\dref@annotate,
+}
+
+%% Usagereport
+\ifdref@usagereport
+  \RequirePackage{xtab}
+  \RequirePackage{booktabs}
+\fi
+\newcommand{\dref@usagereport@notfound}[2]{}
+\newcommand{\dref@usagereport@found}[2]{}
+
+\csdef{pgfdat@usagereport@keys}{}
+\csdef{pgfdat@usagereport@matchedkeys}{}
+
+\newcommand{\dref@usagereport@referenced}[2]{
+  \ifinlistcs{#2}{dref@usagereport@referenced@#1}{}{
+    \listcsgadd{dref@usagereport@referenced@#1}{#2}
+  }
+  \ifinlistcs{#1}{dref@usagereport@keys}{}{
+    \listcsgadd{dref@usagereport@keys}{#1}
+  }
+}
+\expandafter\def\expandafter\dref@usagereport@strippath@\dref@datapath#1\blanktest{#1}
+
+\newcommand{\dref@usagereport@strippath}[1]{%
+  \expandafter\dref@ifstrmatch\expandafter{\expandafter^\dref@datapath.*$}{#1}%$
+    {\dref@usagereport@strippath@#1\blanktest}%
+    {#1}%
+}
+\newcommand{\dref@usagereport@formatreferencelist}[1]{%
+  \begingroup%
+  \def\sep{}%
+  \renewcommand{\do}[1]{\sep\ifdef{\hyperlink}{\hyperlink{page.##1}{##1}}{##1}\def\sep{, }}%
+  \dolistcsloop{dref@usagereport@referenced@#1}%
+  \endgroup%
+}
+\newif\ifdref@usagereport@keyheader@first
+\dref@usagereport@keyheader@firsttrue
+\newcommand{\dref@usagereport@keyheader}[1]{%
+  \ifdref@usagereport@keyheader@first%
+  \global\dref@usagereport@keyheader@firstfalse%
+  \else%
+    \\%
+  \fi%
+  \textbf{\ifdef{\hypertarget}%
+    {\hypertarget{#1}{\dref@usagereport@strippath{#1}}}%
+    {\dref@usagereport@strippath{#1}}}%
+  & \dref@usagereport@formatreferencelist{#1}%
+  & \drefifdefined{#1}{\dref*[@reference key/.code={}]{#1}}{\textbf{undefined}}%
+}
+
+\def\drefusagereportaftergroup{}
+
+\def\drefusagereportbeforerow{}
+\def\drefusagereportbeforetitle{}
+\def\drefusagereportaftertitle{}
+
+\def\drefusagereportbeforedescription{}
+
+
+\newif\ifdref@withhelp
+\errorcontextlines=23
+\newlength{\dreflinewidth}%
+\newcommand{\dref@usagereport@forhelp}[1]{%
+  \begingroup%
+  \dref@withhelpfalse%
+  \renewcommand{\do}[1]{%
+    \dref@help@match{#1}{##1}{%
+      \dref@withhelptrue%
+    }{}%
+  }%
+  \dolistcsloop{dref@usagereport@keys}%
+  \dref@usagereport@keyheader@firsttrue%
+  \renewcommand{\do}[1]{%
+    \dref@help@match{#1}{##1}{%
+      \drefusagereportbeforerow%
+      \dref@usagereport@keyheader{##1}%
+      \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
+        \listcsgadd{dref@usagereport@matchedkeys}{##1}%
+      }%
+    }{}%
+  }%
+  \ifdref@withhelp
+    \tablehead{\drefusagereportbeforetitle%
+      \hline      & Page  & Value %
+      \drefusagereportaftertitle\\\hline%
+    }%
+    \setlength\tabcolsep{3pt}%
+    \dreflinewidth=\linewidth%
+    \advance\dreflinewidth by -4\tabcolsep%
+    \advance\dreflinewidth by -2\arrayrulewidth%
+    \begin{xtabular}{|p{0.7\dreflinewidth}|p{0.15\dreflinewidth}|p{0.15\dreflinewidth}|}%
+      \dolistcsloop{dref@usagereport@keys}\\\hline
+      \drefusagereportbeforedescription%
+      \multicolumn{3}{|p{\linewidth}|}{\csuse{dref@help@#1}}\\\hline
+    \end{xtabular}%
+  \fi%
+  \drefusagereportaftergroup%
+
+  \endgroup%
+}
+\newif\ifdref@withouthelp
+\newcommand{\dref@usagereport@withouthelp}{%
+  \begingroup%
+  \dref@withouthelpfalse%
+  \renewcommand{\do}[1]{%
+    \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
+      \dref@withouthelptrue%
+    }%
+  }%
+  \dolistcsloop{dref@usagereport@keys}%
+  \dref@usagereport@keyheader@firsttrue%
+  \renewcommand{\do}[1]{%
+    \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
+      \drefusagereportbeforerow%
+      \dref@usagereport@keyheader{##1}%
+    }%
+  }%
+  \ifdref@withouthelp%
+    \tablehead{\drefusagereportbeforetitle%
+      \hline Keys without Description     & Page  & Value %
+      \drefusagereportaftertitle\\\hline%
+    }%
+    \setlength\tabcolsep{3pt}%
+    \dreflinewidth=\linewidth%
+    \advance\dreflinewidth by -4\tabcolsep%
+    \advance\dreflinewidth by -2\arrayrulewidth%
+    \begin{xtabular}{|p{0.7\dreflinewidth}|p{0.15\dreflinewidth}|p{0.15\dreflinewidth}|}%
+      \dolistcsloop{dref@usagereport@keys}\\\hline
+      \drefusagereportbeforedescription%
+      \multicolumn{3}{|p{\linewidth}|}{%
+        \emph{For these keys, no description was given}}\\\hline
+    \end{xtabular}%
+   \fi%
+   \endgroup%
+}
+\newcommand{\drefusagereport}{%
+  \ifdref@usagereport%
+  \ifcsvoid{dref@usagereport@keys}{}{%
+  \begingroup%
+  \renewcommand{\do}[1]{%
+    \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
+      \dref@usagereport@forhelp{##1}%
+    }%
+  }%
+  \dolistcsloop{dref@helps} % For all help text
+  \dref@usagereport@withouthelp\relax
+  \endgroup%
+  }% csempty @keys
+  \fi%
+}
+\drefkeys{
+  noassert/.is if=dref@noassert
+}
+\newcommand{\drefassert}[1]{%
+  \begingroup%
+    \drefcalc*{#1}%
+    \ifdim\drefresult pt = 0pt%
+      \ifdref@noassert%
+        \dref@warning{Assertion failed: #1}%
+      \else%
+        \dref@error{Assertion failed: #1}%
+        \fi%
+     \else
+       \dref@warning{Assertion holds: #1}%
+     \fi%
+  \endgroup%
+}
+\drefkeys{%
+  factor of/.style={%
+    @get key or value to={#1}{\drefrel@tmp}{\drefrel@tmpunit},
+    unit/@assert compatible=\drefrel@tmpunit,
+    @calc pgf/.expanded={(\noexpand\drefresult)/(\drefrel@tmp)},
+    @calc/.append code={\def\drefunit{}},
+  },
+  percent/.style={
+    @calc pgf={100 * (\drefresult)},
+  },
+  percent of/.style={
+    factor of=#1, percent,
+    @calc/.append code={\def\drefunit{}},
+  },
+  scale by/.style={
+    @get key or value to={#1}{\drefrel@tmp}{\drefrel@tmpunit},%
+    unit/@assert unitless=\drefrel@tmpunit,
+    @calc pgf/.expanded={(\drefrel@tmp) * (\noexpand\drefresult)},
+  },
+  product/.style={scale by={#1}},
+  divide by/.style={
+    @get key or value to={#1}{\drefrel@tmp}{\drefrel@tmpunit},%
+    unit/@assert unitless=\drefrel@tmpunit,
+    @calc pgf/.expanded={(\noexpand\drefresult) / (\drefrel@tmp)},
+  },
+  divide/.style={divide by},
+  product/.style={scale by={#1}},
+  increase factor from/.style={
+    @get key or value to={#1}{\drefrel@tmp}{\drefrel@tmpunit},
+    unit/@assert compatible=\drefrel@tmpunit,
+    @calc pgf/.expanded={((\noexpand\drefresult)-(\drefrel@tmp))/(\drefrel@tmp)},
+    @calc/.append code={\def\drefunit{}},
+  },
+  increase percent from/.style={increase factor from={#1}, percent},
+  decrease factor from/.style={increase factor from={#1}, negate},
+  decrease percent from/.style={increase factor from={#1}, negate, percent},
+  increase from/.style={
+    @get key or value to={#1}{\drefrel@tmp}{\drefrel@tmpunit},%
+    unit/@assert compatible=\drefrel@tmpunit,
+    @calc pgf/.expanded={((\noexpand\drefresult)-(\drefrel@tmp))},
+  },
+  decrease from/.style={increase from={#1}, negate},
+  abs/.style={
+    @calc pgf={abs(\drefresult)}
+  },
+  negate/.style={
+    @calc pgf={-1 * (\drefresult)}
+  },
+}
+
+\def\drefrel{\@ifstar\drefrel@starred\drefrel@unstarred}
+
+\newcommand{\drefrel@unstarred}[2][]{%
+  \drefkeys{@[,
+      @init,
+      path={#2}, print=default, #1,
+      @get key or value, @calc, @print, @set,
+    @],
+    @annotate={\textbackslash drefrel[#1]\{#2\}}}%
+}
+
+\newcommand{\drefrel@starred}[2][]{%
+  \drefkeys{
+    @[, @init,
+      path={#2}, #1,
+      @get key or value, @calc, @set,
+    @],
+    @annotate={\textbackslash drefrel[#1]\{#2\}},
+  }%
+}
+
+% Unit scaling
+
+\def\dref@unit@key#1#2{%
+  dref@unit@\expandafter\detokenize\expandafter{#1}@\expandafter\detokenize\expandafter{#2}}
+
+\def\dref@unit@new#1{%
+  \def\dref@unit@scala{}%
+  \def\dref@unit@new@outer##1/##2,##3\@nnil{%
+    \def\dref@outer{\dref@unit@new@outer##3\@nnil}%
+    \listadd{\dref@unit@scala}{##2}%
+    \ifx##3&&%
+       \def\dref@outer{}%
+    \fi%
+    \dref@outer%
+  }%
+  \dref@unit@new@outer#1,\@nnil%
+  \def\dref@unit@new@outer##1/##2,##3\@nnil{%
+    \def\dref@outer{\dref@unit@new@outer##3\@nnil}%
+    \pgfkeys{/dref/units/\detokenize{##2} to \detokenize{##2}/.initial={* 1},%
+      /dref/units/scala \detokenize{##2}/.initial/.expand once={\dref@unit@scala}}%
+    \ifx##3&&%
+       \def\dref@outer{}%
+    \else%
+       \def\dref@unit@factor{}%
+       \dref@unit@new@inner{##2}##3\@stop%
+    \fi%
+    \dref@outer%
+  }
+  \def\dref@unit@new@inner##1##2/##3,##4\@stop{%
+    \def\dref@inner{\dref@unit@new@inner{##1}##4\@stop}%
+    \ifx##4&&\def\dref@inner{}\else\fi%
+    \edef\dref@unit@factor{\dref@unit@factor * ##2}%
+    \pgfkeys{/dref/units/\detokenize{##1} to \detokenize{##3}/.initial/.expanded={* (1 \dref@unit@factor)},%
+             /dref/units/\detokenize{##3} to \detokenize{##1}/.initial/.expanded={/ (1 \dref@unit@factor)},%
+    }%
+    \dref@inner%
+  }%
+  \dref@unit@new@outer#1,\@nnil%
+}
+
+\drefkeys{
+  unit/new scala/.code={%
+     \dref@unit@new{#1}%
+  },
+  unit/.style={
+    unit/@load={#1},
+    unit/@format enable,
+    @get/.append style={unit/@load={#1}}, % Override Unit from loads
+  },
+  unit/@load/.code={% #1 Is plain unit
+    \def\drefunit{#1}%
+  },
+  unit/@try override/.code={% #1 must be unit holding macro
+    \ifx#1\empty#1\else%
+       \expandafter\def\expandafter\drefunit\expandafter{#1}%
+    \fi%
+  },
+  unit/@format enable/.code={%
+    \ifx\drefunit\empty\drefunit\else%
+      \drefkeys{unit/format=default}%
+    \fi%
+  },
+  unit/@assert unitless/.code={%
+    \ifx\drefunit\empty\drefunit\else% We are unit less: good
+    \ifx#1\empty#1\else% Other has no unit, also good
+    \dref@error{At least one should be unitless:
+      \expandafter\detokenize\expandafter{\drefunit},
+      \expandafter\detokenize\expandafter{#1}}
+      % There is some unit here. That is BAD
+    \fi\fi%
+  },
+  unit/@assert compatible/.code={%
+    \ifx\drefunit\empty\drefunit\else% We are unit less: good
+    \ifx#1\empty#1\else% Other has no unit, also good
+      \ifx\drefunit#1\else% Bot equal: also good
+         \dref@error{Incompatible Units:
+           \expandafter\detokenize\expandafter{\drefunit}
+           != \expandafter\detokenize\expandafter{#1}}
+         \fi%
+       \fi%
+    \fi%
+  },
+  unit/@combine/.style={
+    unit/@assert compatible={#1}, unit/@try override={#1}, unit/@format enable
+  },
+  unit/scale to/.code={%
+    \edef\dref@unit@key{/dref/units/\expandafter\detokenize\expandafter{\drefunit} to \detokenize{#1}}%
+    \drefkeys{%
+      \dref@unit@key/.get=\dref@unit@factor,%
+      @calc pgf/.expanded={((\noexpand\drefresult) \dref@unit@factor)},%
+      unit=#1%
+    }%
+  },
+  unit/scale to auto/.default=50,
+  unit/scale to auto/.style={% #1 is the optimal value
+    @calc/.append code={
+      \dref@ifunit{%Only do the scaling, if there is a unit
+      \edef\dref@unit@key{/dref/units/scala \expandafter\detokenize\expandafter{\drefunit}}%
+      % Get all other units in the same scala
+      \drefkeys{\dref@unit@key/.get=\dref@unit@scala}%
+      \expandafter\def\expandafter\drefunit@best\expandafter{\drefunit}%
+      \def\drefunit@bestvalue{\drefresult}%
+      \def\@@score####1{1 / ( abs(#1) - abs(####1))}%
+      \def\do####1{%
+        \edef\dref@unit@key{/dref/units/\expandafter\detokenize\expandafter{\drefunit} to \detokenize{####1}}%
+        \pgfkeys{\dref@unit@key/.get=\dref@unit@factor}%
+        \pgfmathparse{\@@score{\drefunit@bestvalue} < \@@score{\drefresult \dref@unit@factor}}%
+        %\typeout{\drefunit \pgfmathresult \detokenize{####1}}%
+        \ifdim\pgfmathresult pt=1.0 pt%
+          \pgfmathparse{(\drefresult) \dref@unit@factor}%
+          \edef\drefunit@bestvalue{\pgfmathresult}%
+          \def\drefunit@best{####1}%
+           %\typeout{\expandafter\detokenize\expandafter{\drefunit} to
+           %  \detokenize{####1} : \drefunit@bestvalue}%
+        \fi%
+      }%
+      \dolistloop\dref@unit@scala%
+      \edef\drefresult{\drefunit@bestvalue}%
+      \edef\drefunit{\expandonce{\drefunit@best}}%
+      }{}% ! \drefunit=\empty
+    }
+  },
+  unit/format default/.initial={plain},
+  unit/format/.is choice,
+  unit/format/no/.style={unit/format default=no, @print unit/.code={}},
+  unit/format/false/.style={unit/format default=no, @print unit/.code={}},
+  unit/format/plain/.style={
+    unit/format default=plain,
+    @print unit/.code={\dref@ifunit{\,\drefunit}{}}
+  },
+  unit/format/typeout/.style={
+    unit/format default=typeout,
+    @print unit/.code={\dref@ifunit{\expandafter\typeout\expandafter{\drefunit}}{}}
+ },
+  unit/format/siunitx/.style={
+    unit/format default=siunitx,
+    @print unit/.code={\dref@ifunit{\,\expandafter\si\expandafter{\drefunit}}{}}
+  },
+  unit/format/default/.style={%
+    unit/format default/.get=\dref@unit@format,
+    unit/format/.expand once=\dref@unit@format
+  },
+}
+
+\def\dref@ifunit#1#2{%
+  \expandafter\ifblank\expandafter{\drefunit}{#2}{#1}%
+}
+
+
+\endinput
+%%
+%% End of file `dataref.sty'.
-- 
cgit v1.2.3

