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.stywould 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– Brandon Kuczenski Dec 01 '12 at 21:52l3fpis expandable, why not just do the calculation within the argument of\num? – Joseph Wright Dec 01 '12 at 21:55\calc{\myresult}{250 / 2}is equivalent to\FPdiv\myresult{250}{2}(up to how leading/trailing zeros are treated, perhaps). – Bruno Le Floch Dec 02 '12 at 09:49