As I am now accessing values from tables via a macro to make dynamic references in the text (see here) and make calculations with it, I need a way to make the resulting variables under which the values are stored more user friendly. Because of LaTeX' limitation of not allowing numbers or any separator in a macro name (and I have many macros), I use the "\csname\dots\endcsname
" approach from the TeX FAQ to create more meaningful names.
This results in the following complication, illustrated in the MWE below: I use siunitx
to print numbers via \num
or \SI
. As these commands accept only numbers, I can't make calculations within those. I use l3fp
to make the calculations and store the the result under a (temporary) name. This results in two lines of code for every single variable:
\calc{\Numtest}{500/2}% store result
\DefineRemark{num:test}{\Numtest}% label result
And within the text the result would be called as \num{\Remark{num:test}}
. I want to combine the two commands into one that would be something like \newcalc{<varname>}{<calculation>}
. The following does not work because \temp
does not get overwritten. I would require a new random name for every single instance of \newcalc
.
\newcommand{\newcalc}[2]{%
\calc{\temp}{#2}
\DefineRemark{#1}{\temp}
}
What is a way to solve this issue? On another note in the MWE I created two new commands based on \num
and \SI
that incorporates the \Remark
macro. Is it a good idea to create these commands by copying the original definition completely?
\documentclass{scrartcl}
\usepackage{siunitx,xparse,expl3}
% simple calculation command that stores the result
\ExplSyntaxOn
\NewDocumentCommand {\calc} { m m } {
\tl_set:Nx #1 { \fp_to_tl:n {#2} }
}
\ExplSyntaxOff
% Workaround for non-letters in macro names
\newcommand{\DefineRemark}[2]{%
\expandafter\newcommand\csname rmk-#1\endcsname{#2}%
}
\newcommand{\Remark}[1]{\csname rmk-#1\endcsname}
% Create \Num and \NUM based on siunitx' \num and \SI to incorporate the above directly
% (so \Num is \num{\remark{.}}). Not sure if it as a good idea to do it that way
\ExplSyntaxOn
\NewDocumentCommand \Num { o m } {
\leavevmode
\group_begin:
\IfNoValueF {#1}
{ \keys_set:nn { siunitx } {#1} }
\__siunitx_number_output:n {\Remark{#2}}
\group_end:
}
\NewDocumentCommand \NUM { o m o m } {
\leavevmode
\group_begin:
\IfNoValueTF {#1}
{ \__siunitx_combined:nnnn { } {\Remark{#2}} {#3} {#4} }
{
\keys_set:nn { siunitx } {#1}
\__siunitx_combined:nnnn {#1} {\Remark{#2}} {#3} {#4}
}
\group_end:
}
\ExplSyntaxOff
% Test if \Num and \NUM Works
\calc{\Numtest}{500/2}
\DefineRemark{num:test}{\Numtest}
% Trying to combine \calc and \DefineRemark
% This does not work :( Would need to create a new "\temp" each time
\newcommand{\newcalc}[2]{%
\calc{\temp}{#2}
\DefineRemark{#1}{\temp}
}
\newcalc{new:calc1}{250/2}
\newcalc{new:calc2}{125/2}
\begin{document}
Test Num and NUM Macros: \Num{num:test} and \NUM{num:test}{\percent}
\vspace{2ex}
Test the combination of calc and DefineRemark. The two values should be
different: \Num{new:calc1} and \Num{new:calc2}
\end{document}
fp.sty
would do what you want..\FPdiv\myresult{250}{2}
will store 125 in \myresult. \FPclip is also necessary to remove leading and trailing zeros. But this approach integrates well withsiunitx
l3fp
is expandable, why not just do the calculation within the argument of\num
?\calc{\myresult}{250 / 2}
is equivalent to\FPdiv\myresult{250}{2}
(up to how leading/trailing zeros are treated, perhaps).