%%
%% 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{dref}
 [2013/12/06 v0.1 dref]
\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}
\RequirePackage{xparse}
\RequirePackage{etoolbox}
\RequirePackage{etextools}
\SetupKeyvalOptions{
  family=dref,
  prefix=dref@
}
\DeclareStringOption[/data]{datapath}
\DeclareStringOption[1]{defaultvalue}
\DeclareStringOption[none]{annotate}
\DeclareBoolOption{usagereport}
\DeclareBoolOption{ignoremissing}
\DeclareBoolOption{noassert}
\ProcessKeyvalOptions*
\newcommand{\dref@set}[2]{%
    \pgfkeys@temptoks{#2}%
    \expandafter\xdef\csname pgfk@\dref@datapath#1\endcsname{\the\pgfkeys@temptoks}%
}
\def\drefset#1#2{\dref@set{#1}{#2}}

\long\def\dref@expandable#1{%
  \pgfkeysifdefined{\dref@datapath#1}{%
    \pgfkeysvalueof{\dref@datapath#1}%
  }{%
    \dref@defaultvalue%
  }%
}
\long\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}}%
}
\DeclareDocumentCommand{\dref}{o m}{%
  \dref@unexpandable{#2}%
  \IfNoValueTF {#1}{%
    \gdef\dref@dref@output{\dref@expandable{#2}}%
  }{%
    \gdef\dref@dref@output{%
      \pgfmathparse{\dref@expandable{#2}}%
      \dref@format[#1]{\pgfmathresult}%
    }%
  }%
  \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}%
  }%
}
\long\def\dref@notfound#1#2{
  \ifdref@usagereport%
    \dref@usagereport@notfound{#1}{#2}%
  \else\relax\fi%
}
\long\def\dref@found#1#2{
  \ifdref@usagereport%
    \dref@usagereport@found{#1}{#2}%
  \else\relax\fi%
}
\long\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;}%
  \docsvlist{#1}%
}
\def\dreflet#1{%
  \dref@let{#1}%
}
\DeclareDocumentCommand{\dref@calc}{o m}{%
  \IfNoValueTF {#1}{}{%
    \dref@let{#1}%
  }%
  \pgfmathparse{#2}%
}
\def\drefresult{0.0}
\DeclareDocumentCommand{\drefcalc}{s O{} m O{}}{%
  \begingroup%
  \dref@calc[#2]{#3}%
  \xdef\drefresult{\pgfmathresult}%
  \IfBooleanTF {#1} {}% Wit star do not print anything
               {%
                 \dref@format[#4]{\pgfmathresult}%
                 \dref@mkannotate{#3}%
               }%
  \endgroup%
}
\newcommand{\dref@format}[2][]{%
  \pgfmathprintnumber[#1]{#2}%
}
\DeclareDocumentCommand{\drefformat}{O{} m}{%
  \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%
}
\DeclareDocumentCommand{\drefprojection}{m m m}{%
  \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%
          \dref@calc{##1}%
          \xdef\dref@project@result{\pgfmathresult}
       \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}
\DeclareDocumentCommand{\drefrow}{s m m}{%
  \IfBooleanTF {#1} {%
    \dref@makerow{#2}{#3}%
  }{% Wit star do not print anything
    \dref@makerow{#2}{\dref[]{#3}}%
  }%
}

\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{\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}{lll}\toprule%
    & Page(s) & Value \\ \midrule
  \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}{lll}\toprule%
    Keys without Help  & Page(s) & Value \\\midrule
    \endhead
    \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%
    \pgfmathsetmacro{\result}{(#1) ? 1 : 0}
    \expandafter\ifstrequal\expandafter{\result}{1.0}{%
      \typeout{Assertion holds: #1}%
    }{%
      \ifdref@noassert%
        \typeout{Assertion failed: #1}%
      \else%
        \dref@error{Assertion failed: #1}%
      \fi%
   }%
  \endgroup%
}
\endinput
%%
%% End of file `dataref.sty'.
