From b8159c6a75c91906de45a470a0b30b80a854d7e4 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 6 Jan 2017 22:25:07 +0000 Subject: dataref (6jan17) git-svn-id: svn://tug.org/texlive/trunk@42883 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/dataref/dataref.sty | 872 ++++++++++++++++-------- 1 file changed, 589 insertions(+), 283 deletions(-) (limited to 'Master/texmf-dist/tex/latex/dataref') diff --git a/Master/texmf-dist/tex/latex/dataref/dataref.sty b/Master/texmf-dist/tex/latex/dataref/dataref.sty index 381d57469af..bb6f013032a 100644 --- a/Master/texmf-dist/tex/latex/dataref/dataref.sty +++ b/Master/texmf-dist/tex/latex/dataref/dataref.sty @@ -1,13 +1,5 @@ +%% Copyright 2013-2017 Christian Dietrich %% -%% 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. @@ -15,33 +7,32 @@ %% 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} - [2015/09/17 v0.5 dataref] +\ProvidesPackage{dataref}[2017/01/06 v0.6 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 + +\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} -\usepgflibrary{fpu} -\usepackage{etoolbox} -\RequirePackage{xcolor} +\RequirePackage{etoolbox} \SetupKeyvalOptions{ family=dref, @@ -55,72 +46,297 @@ \DeclareBoolOption{ignoremissing} \DeclareBoolOption{noassert} \ProcessKeyvalOptions* -\def\dref@set#1#2{% - \edef\dref@set@tmp{#2}% - \expandafter\pgfkeys@temptoks\expandafter{\dref@set@tmp}% - \expandafter\xdef\csname - pgfk@\dref@datapath#1\endcsname{\the\pgfkeys@temptoks}% + +% 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@datapath#1}{0} - \expandafter\dref@referenced\expandafter{\dref@datapath#1}{0}% + \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\drefset#1#2{\dref@set{#1}{#2}} -\def\dref@expandable#1{% - \pgfkeysifdefined{\dref@datapath\csuse{dref@prefix}#1}{% - \pgfkeysvalueof{\dref@datapath\csuse{dref@prefix}#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{}% + }% }{% - \ifdref@ignoremissing% - \dref@defaultvalue% - \else% - \typeout{Dref error: undefined key `#1'}\QUIT% - \fi% + \edef#2{\dref@defaultvalue}% + \def#3{}% }% } -\def\dref@unexpandable#1{% - \def\drefcurrentkey{\dref@datapath\csuse{dref@prefix}#1}% - \pgfkeysifdefined{\drefcurrentkey}{% - \edef\dref@thepage{\arabic{page}}% - \immediate\write\@auxout{\noexpand\dref@found{\drefcurrentkey}{\dref@thepage}}% + +\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}% }{% - \immediate\write\@auxout{\noexpand\dref@notfound{\drefcurrentkey}{\dref@thepage}}% + \dref@set{#1}{#2}{#3}% }% - \immediate\write\@auxout{\noexpand\dref@referenced{\drefcurrentkey}{\dref@thepage}}% -} -\newcommand{\drefifdefined}[3]{ - \def\drefcurrentkey{\dref@datapath\csuse{dref@prefix}#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{\textbackslash dref\{#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{\textbackslash dref*\{#2\}}% } -\def\drefvalueof#1{% - \dref@expandable{#1}% + +\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% } -\def\drefref#1{% - \dref@unexpandable{#1}% + +\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 + \let\dref@strmatch\pdfmatch \fi \ifLuaTeX% -\newcommand{\dref@strmatch}[2]{% + \newcommand{\dref@strmatch}[2]{% \directlua{% local match = string.find("\luaescapestring{#2}", "\luaescapestring{#1}");% if match then @@ -160,6 +376,20 @@ \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}% @@ -175,18 +405,9 @@ \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}% -} +% The data("") || d() Parser \def\dref@parser#1#2{% \edef\@tempa{#1}% \csdef{dref@parser@result}{}% @@ -221,77 +442,67 @@ \csdef{dref@parser@d@(}{\dref@parser@tillparen} \def\dref@parser@tillquote#1")#2\@nnil{% - \drefref{\dref@data@math@prefix #1}% - \csxdef{dref@parser@result}{\csuse{dref@parser@result}(\drefvalueof{\dref@data@math@prefix #1})}% + \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{% - \drefref{\dref@data@math@prefix #1}% - \csxdef{dref@parser@result}{\csuse{dref@parser@result}(\drefvalueof{\dref@data@math@prefix #1})}% + \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@@}{\typeout{end}\dref@parser@end} - -\newcommand{\dref@calc}[1]{% - %\typeout{Before: '#1'}% - \dref@parser{#1}{\dref@calc@@argA}% - %\typeout{After: \dref@calc@@argA}% - \pgfmathparse{\dref@calc@@argA}% +\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}% + } + } } -\pgfset{/dref/let/.code={\dref@let{#1}}} -\pgfset{/dref/prefix/.code={\csdef{dref@prefix}{#1}}} -\def\drefprefix#1{\csdef{dref@prefix}{#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{\textbackslash drefcalc\{#2\}}% - \endgroup% +\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}[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{\drefcalc@starred}[2][]{ % Starred + \drefkeys{@[,@init, @calc pgf={#2}, #1, @calc, @set,% + @annotate={\textbackslash \drefcalc*[#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% +\newcommand{\drefformat}[2][]{% + \drefkeys{@[,@init, print=default, value={#2}, #1, @calc, @print, @]}% } + \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% + \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% } @@ -313,8 +524,8 @@ }% \expandafter\def\expandafter\arglist\expandafter{#1}% \expandafter\docsvlist\expandafter{\arglist}% - \@tempcntb=0\relax - {\loop\ifnum\@tempcntb<\drefcellcount + \@tempcntb=0\relax% + {\loop\ifnum\@tempcntb<\drefcellcount% \advance\@tempcntb by 1\relax% \ifnum \@tempcntb = 1% \edef\@@next{\csuse{@cell\the\@tempcntb}}% @@ -330,31 +541,25 @@ \@@next}% \repeat}% }% - \typeout{LINE: \the\dref@toks}% - \expandafter\scantokens\expandafter{\the\dref@toks}} + \expandafter\scantokens\expandafter{\the\dref@toks}% +} -\long\def\drefrow{\@ifstar\@@drefrow\@drefrow} -\def\@drefrow#1#2{\dref@makerow{#1}{\dref{#2}}} % Unstarred -\def\@@drefrow#1#2{\dref@makerow{#1}{#2}} % Starred +\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} } -\def\dref@mkannotate@none#1{\relax} -\def\dref@mkannotate@footnote#1{\footnote{\texttt{#1}}} -\def\dref@mkannotate@pdfcomment#1{\pdfcomment[opacity=0.4,voffset=2ex]{#1}} -\newcommand{\dref@mkannotate}[1]{% - \ifcsdef{dref@mkannotate@\dref@annotate}{% - \csuse{dref@mkannotate@\dref@annotate}{#1}% - }{% - \dref@error{Value for annotate not supported: '\dref@annotate'}% - }% -} - -\newcommand{\drefannotate}[1]{% - \renewcommand{\dref@annotate}{#1}% +\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 @@ -379,7 +584,7 @@ \expandafter\def\expandafter\dref@usagereport@strippath@\dref@datapath#1\blanktest{#1} \newcommand{\dref@usagereport@strippath}[1]{% - \expandafter\dref@ifstrmatch\expandafter{\expandafter^\dref@datapath.*$}{#1}% + \expandafter\dref@ifstrmatch\expandafter{\expandafter^\dref@datapath.*$}{#1}%$ {\dref@usagereport@strippath@#1\blanktest}% {#1}% } @@ -402,7 +607,7 @@ {\hypertarget{#1}{\dref@usagereport@strippath{#1}}}% {\dref@usagereport@strippath{#1}}}% & \dref@usagereport@formatreferencelist{#1}% - & \pgfkeysifdefined{#1}{\pgfkeysvalueof{#1}}{\textbf{\color{red}undefined}}% + & \drefifdefined{#1}{\dref*[@reference key/.code={}]{#1}}{\textbf{undefined}}% } \def\drefusagereportaftergroup{} @@ -492,7 +697,7 @@ } \newcommand{\drefusagereport}{% \ifdref@usagereport% - \ifcsvoid{dref@usagereport@keys}{\typeout{EMPTY}}{% + \ifcsvoid{dref@usagereport@keys}{}{% \begingroup% \renewcommand{\do}[1]{% \ifinlistcs{##1}{dref@usagereport@matchedkeys}{}{% @@ -505,142 +710,243 @@ }% csempty @keys \fi% } +\drefkeys{ + noassert/.is if=dref@noassert +} \newcommand{\drefassert}[1]{% \begingroup% \drefcalc*{#1}% - \expandafter\ifstrequal\expandafter{\drefresult}{1}{% - \typeout{Assertion holds: #1}% - }{% + \ifdim\drefresult pt = 0pt% \ifdref@noassert% - \typeout{Assertion failed: #1}% + \dref@warning{Assertion failed: #1}% \else% \dref@error{Assertion failed: #1}% - \fi% - }% + \fi% + \else + \dref@warning{Assertion holds: #1}% + \fi% \endgroup% } -\newif\if@dref@valuemustderef% -\newif\if@dref@basemustderef% -\newif\if@dref@increase% -\newif\if@dref@product% -\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,% - scale/.is if=@dref@product,% - scale/.default=true,% - scale=false,% - product/.is if=@dref@product,% - product/.default=true,% - product=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% - \dref@mkannotate{\textbackslash{}drefrel[#1]\{#2\}}% -} - -\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% - \if@dref@product% - \pgfmathparse{(\drefvalue) * (\drefbase)}% - \def\drefresult{\pgfmathresult}% - \else - \def\drefresult{\drefvalue}% - \fi +\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% - % 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% + \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