%%
%% This is file `dataref.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% dataref.dtx  (with options: `package')
%% dataref.dtx
%%  Copyright 2013 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}
 [2014/08/20 v0.2 dataref]

\ifx\drefloaded\undefined
  \let\drefloaded=\relax
\else
  \expandafter\endinput
\fi
\ifx\PackageError\undefined
  \def\dref@error#1{\immediate\write-1{Package dref: Error! #1.}}%
\else
  \def\dref@error#1{\PackageError{dref}{#1}{}}%
\fi
\RequirePackage{pgf}
\RequirePackage{kvoptions}
\usepgflibrary{fpu}
\usepackage{etoolbox}
\let\origforlistloop\forlistloop
\usepackage{etextools}
\let\forlistloop\origforlistloop
\RequirePackage{xcolor}

\SetupKeyvalOptions{
  family=dref,
  prefix=dref@
}
\DeclareStringOption[/data]{datapath}
\DeclareStringOption[1]{defaultvalue}
\DeclareStringOption[none]{annotate}
\DeclareBoolOption{usagereport}
\DeclareBoolOption{refall}
\DeclareBoolOption{ignoremissing}
\DeclareBoolOption{noassert}
\ProcessKeyvalOptions*
\def\dref@set#1#2{%
    \pgfkeys@temptoks{#2}%
    \expandafter\xdef\csname
    pgfk@\dref@datapath#1\endcsname{\the\pgfkeys@temptoks}%
    \ifdref@refall%
      \expandafter\dref@found\expandafter{\dref@datapath#1}{0}
      \expandafter\dref@referenced\expandafter{\dref@datapath#1}{0}%
    \fi%
}
\def\drefset#1#2{\dref@set{#1}{#2}}

\def\dref@expandable#1{%
  \pgfkeysifdefined{\dref@datapath#1}{%
    \pgfkeysvalueof{\dref@datapath#1}%
  }{%
    \ifdref@ignoremissing%
      \dref@defaultvalue%
    \else%
      \typeout{Dref error: undefined key `#1'}\QUIT%
    \fi%
  }%
}
\def\dref@unexpandable#1{%
  \def\drefcurrentkey{\dref@datapath#1}%
  \pgfkeysifdefined{\drefcurrentkey}{%
    \immediate\write\@auxout{\noexpand\dref@found{\drefcurrentkey}{\thepage}}%
  }{%
    \immediate\write\@auxout{\noexpand\dref@notfound{\drefcurrentkey}{\thepage}}%
    \ifdref@ignoremissing%
       \typeout{Dref warning: undefined key `\drefcurrentkey'}%
       \dref@mkannotate{UNDEFINED: \drefcurrentkey}%
    \else%
       \dref@error{Dref error: undefined key `\drefcurrentkey'}%
    \fi%
  }%
  \immediate\write\@auxout{\noexpand\dref@referenced{\drefcurrentkey}{\thepage}}%
}
\newcommand{\drefifdefined}[3]{
  \def\drefcurrentkey{\dref@datapath#1}%
  \pgfkeysifdefined{\drefcurrentkey}{#2}{#3}%
}
\def\dref{\@ifstar\@@dref\@dref}
\newcommand{\@dref}[2][]{% Unstarred
  \edef\dref@argument{#2}
  \expandafter\dref@unexpandable\expandafter{\dref@argument}%
  \pgfmathparse{\dref@expandable{#2}}%
  \dref@format[#1]{\pgfmathresult}%
  \dref@mkannotate{#2}%
}
\newcommand{\@@dref}[2][]{ % Starred
  \edef\dref@argument{#2}
  \expandafter\dref@unexpandable\expandafter{\dref@argument}%
  \expandafter\gdef\expandafter\dref@dref@output\expandafter{\expandafter\dref@expandable\expandafter{\dref@argument}}%
  \dref@dref@output%
  \dref@mkannotate{#2}%
}
\def\drefvalueof#1{%
  \dref@expandable{#1}%
}
\def\drefref#1{%
  \dref@unexpandable{#1}%
}
\newcommand{\dref@help@match}[2]{%
  \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}%
  }%
}
\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%
}
\def\dref@let#1{%
  \def\@tmp##1=##2;{\pgfmathdeclarefunction*{##1}{0}{\pgfmathparse{##2}}}%
  \renewcommand*{\do}[1]{\@tmp##1;}%
  \ifstrempty{#1}{}{%
    \docsvlist{#1}%
  }%
}

\def\dreflet#1{%
  \dref@let{#1}%
}

\def\dref@calc@parser@d#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1d%
    \dref@calc@parser@a #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@a#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1a%
    \dref@calc@parser@t #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@t#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1t%
    \dref@calc@parser@A #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@A#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1a%
    \dref@calc@parser@P #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@P#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1(%
    \dref@calc@parser@Q #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@Q#1#2\@nnil{%
  \ifx&#2&#1\else%
    \if#1"%
     \dref@calc@parser@E #2\@nnil%
  \else%
    #1\dref@calc@parser@d #2\@nnil%
  \fi\fi
}

\def\dref@calc@parser@E#1")#2\@nnil{%
  (\drefvalueof{\dref@data@math@prefix#1})\ifx&#2&\else\dref@calc@parser@d #2\@nnil\fi%
}

\newcommand{\dref@calc}[1]{%
  \xdef\dref@calc@argA{#1}%
  \xdef\dref@calc@@argA{\expandafter\dref@calc@parser@d \dref@calc@argA\@nnil}%%
  % \typeout{>>>> \dref@calc@argA -> \dref@calc@@argA}%
  \pgfmathparse{\dref@calc@@argA}
}
\pgfset{/dref/let/.code={\dref@let{#1}}}
\def\drefresult{0}
\def\drefcalc{\@ifstar\@@drefcalc\@drefcalc}
\newcommand{\@drefcalc}[2][]{% Unstarred
  \begingroup%
  \pgfset{/pgf/number format/.cd, #1}%
  \dref@calc{#2}%
  \pgfmathprintnumberto[fixed,assume math mode=true,precision=10,1000 sep={}]{\pgfmathresult}{\drefresult}
  \xdef\drefresult{\drefresult}%
  \dref@format{\pgfmathresult}%
  \dref@mkannotate{#2}%
  \endgroup%
}
\newcommand{\@@drefcalc}[2][]{ % Starred
   \begingroup%
   \pgfset{/pgf/number format/.cd, #1}%
   \dref@calc{#2}%
   \pgfmathprintnumberto[fixed,assume math mode=true,precision=10,1000 sep={}]{\pgfmathresult}{\drefresult}
   \xdef\drefresult{\drefresult}%
   \endgroup%
}
\newcommand{\dref@format}[2][]{%
  \pgfmathprintnumber[#1]{#2}%
}
\newcommand{\drefformat}[2][]{\dref@format[#1]{#2}}

\gdef\dref@data@math@prefix{}
\pgfmathdeclarefunction{data}{1}{%
        \begingroup%
                \dref@unexpandable{\dref@data@math@prefix#1}%
                \pgfmathparse{\dref@expandable{\dref@data@math@prefix#1}}%
                \pgfmath@smuggleone\pgfmathresult%
        \endgroup%
}
\long\def\drefprojection#1#2#3{%
  \begingroup%
     \def\dref@data@math@prefix{#1}%
     \def\rename##1##2{\dref@unexpandable{#1/##1}\drefset{#2/##2}{\dref@expandable{#1/##1}}}%
     \def\id##1{\rename{##1}{##1}}%
     \def\calc##1##2{%
       \begingroup%
          \drefcalc{##1}%
          \xdef\dref@project@result{\drefresult}
       \endgroup%
       \drefset{#2/##2}{\dref@project@result}%
      }%
     #3%
     \endgroup%
}


\newtoks\dref@toks

\newcommand{\dref@makerow}[2]{%
  {\global\dref@toks={}%
    \@tempcnta=\z@%
    \def\inner##1##2{#2}%
    \renewcommand*{\do}[1]{%
      \advance\@tempcnta\@ne%
      \csdef{@cell\number\@tempcnta}{\inner{##1}{\number\@tempcntb}}%
    }%
    \expandafter\def\expandafter\arglist\expandafter{#1}%
    \expandafter\docsvlist\expandafter{\arglist}%
    \@tempcntb=\z@
        {\loop\ifnum\@tempcntb<\@tempcnta
          \advance\@tempcntb\@ne
          \edef\next{%
            \ifnum\@tempcntb=\@ne\else&\fi
            \csuse{@cell\number\@tempcntb}}%
          \global\dref@toks=\expandafter{\the\expandafter\dref@toks\next}%
          \repeat}%
  }%
  \the\dref@toks}
\long\def\drefrow{\@ifstar\@@drefrow\@drefrow}
\def\@drefrow#1#2{\dref@makerow{#1}{\drefvalueof{#2}}} % Unstarred
\def\@@drefrow#1#2{\dref@makerow{#1}{#2}} % Starred

\expandafter\ifstrequal\expandafter{\dref@annotate}{pdfcomment}{
  \RequirePackage{pdfcomment}
}

\newcommand{\dref@mkannotate}[1]{%
  \expandafter\ifstrequal\expandafter{\dref@annotate}{none}%
    {\relax}%
    {\expandafter\ifstrequal\expandafter{\dref@annotate}{footnote}%
      {\footnote{#1}}%
      {\expandafter\ifstrequal\expandafter{\dref@annotate}{pdfcomment}%
        {\pdfcomment[opacity=0.4,voffset=2ex]{#1}}%
        {\dref@error{Value for annotate not supported: '\dref@annotate'}%
          }}}}%

\newcommand{\drefannotate}[1]{%
  \renewcommand{\dref@annotate}{#1}%
}

%% Usagereport
\ifdref@usagereport
  \RequirePackage{longtable}
  \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\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%
}
\newcommand{\dref@usagereport@keyheader}[1]{%
  \textbf{\ifdef{\hypertarget}%
    {\hypertarget{#1}{\dref@usagereport@strippath{#1}}}%
    {\dref@usagereport@strippath{#1}}}%
  & \dref@usagereport@formatreferencelist{#1}%
  & \pgfkeysifdefined{#1}{\pgfkeysvalueof{#1}}{\textbf{\color{red}undefined}} \\%
}
\newcommand{\dref@usagereport@forhelp}[1]{%
  \begingroup%
  \noindent\csuse{dref@help@#1}
  \renewcommand{\do}[1]{%
    \dref@help@match{#1}{##1}{%
      \dref@usagereport@keyheader{##1}%
      \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
        \listcsgadd{dref@usagereport@matchedkeys}{##1}%
      }%
    }{}%
  }%
  \begin{longtable}{@{\extracolsep{\fill}}lll@{}}\toprule%
    & Page(s) & Value \\ \midrule
    \endhead
    \bottomrule%
    \endfoot
  \dolistcsloop{dref@usagereport@keys}%
  \end{longtable}%
  \endgroup%
}
\newcommand{\dref@usagereport@withouthelp}{%
  \renewcommand{\do}[1]{%
    \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
      \dref@usagereport@keyheader{##1}%
    }%
  }%
  \begin{longtable}{@{\extracolsep{\fill}}lll@{}}\toprule%
    Keys without Help  & Page(s) & Value \\\midrule
    \endhead
    \bottomrule
    \endfoot
    \dolistcsloop{dref@usagereport@keys}%
  \end{longtable}%
}
\newcommand{\drefusagereport}{%
  \ifdref@usagereport%
  \ifcsvoid{dref@usagereport@keys}{\typeout{EMPTY}}{%
  \begingroup%
  \setlength{\LTleft}{2em}%
  \setlength{\LTright}{0pt}%
  \renewcommand{\do}[1]{%
    \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{%
      \dref@usagereport@forhelp{##1}%
    }%
  }%
  \dolistcsloop{dref@helps} % For all help text
  \setlength{\LTleft}{0em}%
  \dref@usagereport@withouthelp\relax
  \endgroup%
  }% csempty @keys
  \fi%
}
\newcommand{\drefassert}[1]{%
  \begingroup%
    \drefcalc*{#1}%
    \expandafter\ifstrequal\expandafter{\drefresult}{1}{%
      \typeout{Assertion holds: #1}%
    }{%
      \ifdref@noassert%
        \typeout{Assertion failed: #1}%
      \else%
        \dref@error{Assertion failed: #1}%
      \fi%
   }%
  \endgroup%
}
\newif\if@dref@valuemustderef%
\newif\if@dref@basemustderef%
\newif\if@dref@increase%
\newif\if@dref@factor%
\newif\if@dref@delta%
\newif\if@dref@percent%
\newif\if@dref@abs%
\newif\if@dref@neg%
\pgfkeys{%
  \dref@datapath/.DUMMY/.initial=1
}
\pgfkeys{%
  /dref/.cd,%
  value/.initial = /.DUMMY,%
  base/.initial  = /.DUMMY,%
  divide/.initial = 1,%
  value plain/.is if=@dref@valuemustderef,%
  value plain/.default=false,%
  value plain=true,%
  base plain/.is if=@dref@basemustderef,%
  base plain/.default=false,%
  base plain=true,%
  factor/.is if=@dref@factor,%
  factor/.default=true,%
  factor=false,%
  delta/.is if=@dref@delta,%
  delta/.default=true,%
  delta=false,%
  increase/.is if=@dref@increase,%
  increase/.default=true,%
  increase=false,%
  overhead/.is if=@dref@increase,%
  overhead/.default=true,%
  overhead=false,%
  percent/.is if=@dref@percent,%
  percent/.default=true,%
  percent=false,%
  abs/.is if=@dref@abs,%
  abs/.default=true,%
  abs=false,%
  negate/.is if=@dref@neg,%
  negate/.default=true,%
  negate=false,%
}

\def\drefrel{\@ifstar\@@drefrel\@drefrel}

\newcommand{\@drefrel}[2][]{%
  \@@drefrel[#1]{#2}%
  \@@drefrel@result%
}

\newcommand{\@@drefrel}[2][]{%
  \begingroup%
  \pgfkeys{/pgf/fpu}%
  \pgfkeys{/dref/.cd,#1}%
  \pgfkeys{/dref/value=#2}%
  \if@dref@valuemustderef%
    \drefref{\pgfkeysvalueof{/dref/value}}%
    \edef\drefvalue{\drefvalueof{\pgfkeysvalueof{/dref/value}}}%
  \else%
    \def\drefvalue{\pgfkeysvalueof{/dref/value}}%
  \fi%
  \if@dref@basemustderef%
    \drefref{\pgfkeysvalueof{/dref/base}}%
    \def\drefbase{\drefvalueof{\pgfkeysvalueof{/dref/base}}}%
  \else%
    \def\drefbase{\pgfkeysvalueof{/dref/base}}%
  \fi%
  \xdef\drefresult{\drefvalue}%
  \if@dref@increase%
     \pgfmathparse{((\drefvalue) - (\drefbase)) / (\drefbase)}%
     \def\drefresult{\pgfmathresult}%
  \else%
     \if@dref@factor%
         \pgfmathparse{(\drefvalue) / (\drefbase)}%
         \def\drefresult{\pgfmathresult}%
     \else%
         \if@dref@delta%
             \pgfmathparse{(\drefvalue) - (\drefbase)}%
             \def\drefresult{\pgfmathresult}%
         \else%
             \def\drefresult{\drefvalue}%
         \fi%
     \fi%
  \fi%
  % Percent
  \if@dref@percent%
      \pgfmathparse{(\drefresult)*100.0}%
      \def\drefresult{\pgfmathresult}%
  \fi%
  % Absolute Value
  \if@dref@abs%
      \pgfmathparse{abs(\drefresult)}%
      \def\drefresult{\pgfmathresult}%
  \fi%
  % Negative Value
  \if@dref@neg%
      \pgfmathparse{-1.0*(\drefresult)}%
      \def\drefresult{\pgfmathresult}%
  \fi%
  \pgfmathparse{\drefresult/\pgfkeysvalueof{/dref/divide}}%
  \pgfmathprintnumberto[fixed,assume math mode=true,precision=10,1000 sep={}]{\pgfmathresult}{\drefresult}%
  \pgfmathprintnumberto{\pgfmathresult}{\@@drefrel@result}%
  \xdef\drefresult{\drefresult}%
  \xdef\@@drefrel@result{\@@drefrel@result}%
  \endgroup%
}

\endinput
%%
%% End of file `dataref.sty'.
