这个问题与我去年提出的关于带有 xkeyval、fp 和 newcommand 的库现在图书馆已经变得相当大,添加新内容已经变得非常繁琐,而且越来越容易出错。
我现在想扩展并简化此代码,以使我的生活更轻松,并且不会破坏 fp 计算。例如,目前我只是复制粘贴代码,然后更改名称以区分各个系列(例如 RESFamilyOne、RESFamilyTwo、RESFamilyThree 等)。
\documentclass{article}
\usepackage{fp}% http://ctan.org/pkg/fp
\usepackage{xkeyval}% http://ctan.org/pkg/xkeyval
\usepackage{siunitx} %Adding SI-prefixes
\sisetup{
exponent-to-prefix = true,
round-mode = figures,
round-precision = 3,
scientific-notation = engineering
}%
%
%
\newcommand \Family[1]{\setkeys{RESFamily}{#1}}%
\makeatletter
%
\define@key{RESFamily}{Name}{ \newcommand \RESFamilyName{#1} }%
\define@key{RESFamily}{Value}{ \newcommand \RESFamilyValue{#1} }%
%
\makeatother
%
\AtBeginDocument{
%##################################################################################################
\Family{%
Name = Some text here,%
Value = ,%Value is added in the LIBRARY components
}%
%
\newcommand \defRES[3]{%START of \defRES
\expandafter\newcommand\csname #1Name\endcsname{\csname RES#2Name\endcsname}%
\expandafter\newcommand\csname #1Value\endcsname{#3}% 1 %
\FPeval{#1Max}{round( \csname #1Value\endcsname * (1+20/100) :4 )}%
\ignorespaces}%END of \defRES
%
%
%LIBRARY
\defRES{Rone}{Family}{10}%
%
}%
%
\begin{document}
test = \RoneName\\
test = \RoneValue\\
\FPeval{\resultTwo}{round( 2*2 :2)}
test2 = 2 * 2 =\resultTwo\\
\FPeval{\resultThree}{round( \RoneValue * \RoneValue :2)}
test3 = \RoneValue * \RoneValue = \resultThree\\
test3a = \RoneValue * \RoneValue = \num{\resultThree}\\
%until now everything OK
test3a = \num[parse-numbers=false]{\RoneMax}\\% this offcourse works
%now NOK
test3a = \num{\RoneMax}
\FPeval{\resultFour}{round( \RoneMax * \RoneMax :2)}
test3 = \resultFour \\
test3a = \num{\resultFour}
\end{document}
问题是我可以有多个系列和键(每个最多可以有 15 个或更多),然后我需要手动指定和扩展\newcommand \RESFamilyName{#1}
以模仿差异\newcommand \RESFamily**One**Name{#1}
。
我一直在网上搜索类似的东西,但到目前为止还没有找到,或者很可能错过了,因为我对这些“核心”内容的 Latex 知识还很陌生。
感谢您的时间和帮助。
编辑(不起作用):
\newcommand \csnshrt[2]{\csname #1#2\endcsname}%shorter \csname \endcsname
%
\newcommand \defkeyshrt{%START DEFINE@KEY-SHORT MACRO
\foreach \n in {%
Name,
Address,
City,
Parameter,
Whatever,
XXX,
YYY,
ZZZ,
etc,
}{ \define@key{#1}{\n}{ \csnshrt{#1}{\n}{How To Add Value Here??} }}%\define@key{RESFamily}{Name}{ \newcommand \RESFamilyName{#1} }%
}%END DEFINE@KEY-SHORT MACRO
%USAGE
\defkeyshrt{RESFamily}%
\defkeyshrt{RESFamilyOne}%
\defkeyshrt{RESFamilyETC}%
这样define@key
就会自动更改,我会在之前的位置执行一次,\defkeyshrt{RESFamily}
然后我需要手动更改\define@key{RESFamily}{Name}{ \newcommand \RESFamilyName{#1} }
以反映\define@key{RESFamilyETC}{Name}{ \newcommand \RESFamilyETCName{#1} }
每个参数(地址、城市、无论什么、YYY,...)。
答案1
我想你想要这样的东西:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\keys_define:nn { maag/variables }
{
unknown .code:n = \maag_defvar:Vn \l_keys_key_tl { #1 }
}
\NewDocumentCommand{\newfamily}{mm}
{
\prop_clear:N \l_maag_family_prop
\keys_set:nn { maag/variables } { #2 }
\prop_new:c { g_maag_family_#1_prop }
\prop_gset_eq:cN { g_maag_family_#1_prop } \l_maag_family_prop
}
\prop_new:N \l_maag_family_prop
\cs_new_protected:Nn \maag_defvar:nn
{
\prop_put:Nnn \l_maag_family_prop { #1 } { #2 }
}
\cs_generate_variant:Nn \maag_defvar:nn { V }
\DeclareExpandableDocumentCommand{\usevar}{mm}
{
\prop_item:cn { g_maag_family_#1_prop } { #2 }
}
\ExplSyntaxOff
\newfamily{FamilyOne}
{
Name = Gaius Iulius Caesar,
Address = Palatinus,
City = Roma,
Parameter = Dictator,
Whatever = Idae Martii,
}
\newfamily{FamilyTwo}
{
Name = Iunius Brutus,
Address = incognitum,
City = Roma,
Parameter = Conspirator,
Whatever = ?,
}
\begin{document}
\usevar{FamilyOne}{Name} was a famous guy.
\end{document}
如您所见,定义基础设施后,您只需提供新的家庭名称和家庭成员的键值对列表。
我认为,与其为每个系列中的每个键定义一个宏,不如使用一个带有两个参数的通用命令。