删除定义的变量或在组内分配

删除定义的变量或在组内分配

这是对 Egregs 在这个问题中的回答的后续可扩展数学, 代码作为 MWE 包含在这里。

如果我能以某种方式删除所有先前定义的变量,或者仅在一个组内分配它们,那将是一个很大的帮助。另一种可能性是简单地允许重新分配具有相同名称的变量。到目前为止,尝试这样做时会出现错误。

编辑:我在底部的 MWE 添加了几行,它尝试设置组内的变量(但仍使它们成为全局变量),尝试重新定义一个变量,这在尝试打印时会出现错误。

错误提示:

./root.tex:122: 缺少插入的 \endcsname。\cs_set_nopar:Npx l.122 }

\documentclass{article}
\usepackage{xparse,l3regex,siunitx,xcolor}

\ExplSyntaxOn

\seq_new:N \g_runart_variables_seq
\prop_new:N \l__runart_variables_temp_prop
\tl_new:N \l__runart_variables_matte_tl
\tl_new:N \l__runart_variables_item_tl

\NewDocumentCommand{\definevariable}{mm}
 { % #1 is the name, #2 is the key-value set
  \seq_gput_right:Nn \g_runart_variables_seq { #1 }
  \prop_clear:N \l__runart_variables_temp_prop
  \keys_set:nn { runart/variables } { #2 }
  \prop_gclear_new:c { g_runart_var_#1_prop }
  \prop_gset_eq:cN { g_runart_var_#1_prop } \l__runart_variables_temp_prop
 }

% syntactic sugar
\cs_new_protected:Nn \__runart_gput:nn
 {
  \prop_gput:Nnn \l__runart_variables_temp_prop { #1 } { #2 }
 }

% keys
\keys_define:nn { runart/variables }
 {
  value .code:n = \__runart_gput:nn { value } { #1 },
  value .value_required:n = true,
  unit .code:n = \__runart_gput:nn { unit } { #1 },
  unit .value_required:n = true,
  name .code:n = \__runart_gput:nn { name } { #1 },
  name .value_required:n = true,
  sisetup .code:n = \__runart_gput:nn { sisetup } { #1 },
 }

\NewDocumentCommand{\matte}{m}
 { % #1 is the expression to output
  \tl_set:Nn \l__runart_variables_matte_tl { #1 }
  \seq_map_inline:Nn \g_runart_variables_seq
   {
    \regex_replace_all:nnN
     { ##1 }
     { \c{runart_variable_use_matte:n} \cB\{ ##1 \cE\} }
     \l__runart_variables_matte_tl
   }
  \tl_use:N \l__runart_variables_matte_tl
 }

\NewDocumentCommand{\formal}{m}
 {
  \tl_set:Nn \l__runart_variables_matte_tl { #1 }
  \seq_map_inline:Nn \g_runart_variables_seq
   {
    \regex_replace_all:nnN
     { ##1 }
     { \c{runart_variable_use_formal:n} \cB\{ ##1 \cE\} }
     \l__runart_variables_matte_tl
   }
  \tl_use:N \l__runart_variables_matte_tl
 }


\cs_new_protected:Nn \runart_variable_use_matte:n
 {
  \use:x % it's necessary to expand the optional argument
   {
    \SI
     [\prop_item:cn { g_runart_var_#1_prop } {sisetup}]
     {\prop_item:cn { g_runart_var_#1_prop } {value}}
     {\prop_item:cn { g_runart_var_#1_prop } {unit}}
   }
 }

\cs_new_protected:Nn \runart_variable_use_formal:n
 {
  \prop_item:cn { g_runart_var_#1_prop } { name }
 }
\ExplSyntaxOff
\begin{document}
{
\definevariable{a_car}
 {
  name=a_{\mathrm{car}},
  value=20,
  unit=\metre\per\second,
 }
\definevariable{v_car}
 {
  name=v_{\mathrm{car}},
  value=40,
  unit=\metre,
 }
\definevariable{t_car}
 {
  name=t_{\mathrm{car}},
  value=2,
  unit=\second,
  sisetup={color=red},
 }



\[
\matte{
  a_car=\frac{v_car}{t_car}
}
\]
}
Trying to redefine a variable:
\definevariable{t_car}
 {
  name=t_{\mathrm{car}},
  value=2,
  unit=\second,
  sisetup={color=red},
 }
\[
\matte{
  t_car
}
\]
\end{document}

答案1

重新定义变量应该是可能的;这是一个完善的版本,带有错误检查的提示。

\documentclass{article}
\usepackage{xparse,l3regex,siunitx,xcolor}

\ExplSyntaxOn

\seq_new:N \g_runart_variables_seq
\prop_new:N \l__runart_variables_temp_prop
\tl_new:N \l__runart_variables_matte_tl
\tl_new:N \l__runart_variables_item_tl

\NewDocumentCommand{\definevariable}{mm}
 { % #1 is the name, #2 is the key-value set
  \seq_if_in:NnF \g_runart_variables_seq { #1 }
   {
    \seq_gput_right:Nn \g_runart_variables_seq { #1 }
   }
  \prop_clear:N \l__runart_variables_temp_prop
  \keys_set:nn { runart/variables } { #2 }
  \prop_gclear_new:c { g_runart_var_#1_prop }
  \prop_gset_eq:cN { g_runart_var_#1_prop } \l__runart_variables_temp_prop
 }

% syntactic sugar
\cs_new_protected:Nn \__runart_put:nn
 {
  \prop_put:Nnn \l__runart_variables_temp_prop { #1 } { #2 }
 }

% keys
\keys_define:nn { runart/variables }
 {
  value .code:n = \__runart_put:nn { value } { #1 },
  value .value_required:n = true,
  unit .code:n = \__runart_put:nn { unit } { #1 },
  unit .value_required:n = true,
  name .code:n = \__runart_put:nn { name } { #1 },
  name .value_required:n = true,
  sisetup .code:n = \__runart_put:nn { sisetup } { #1 },
 }

\NewDocumentCommand{\matte}{m}
 { % #1 is the expression to output
  \__runart_matte_or_formal:nn { runart_variable_use_matte:n } { #1 }
 }
\NewDocumentCommand{\formal}{m}
 {
  \__runart_matte_or_formal:nn { runart_variable_use_formal:n } { #1 }
 }

\cs_new_protected:Nn \__runart_matte_or_formal:nn
 {
  \tl_set:Nn \l__runart_variables_matte_tl { #2 }
  \seq_map_inline:Nn \g_runart_variables_seq
   {
    \regex_replace_all:nnN
     { ##1 }
     { \c{#1} \cB\{ ##1 \cE\} }
     \l__runart_variables_matte_tl
   }
  \tl_use:N \l__runart_variables_matte_tl
 }

\cs_new:Nn \__runart_use_prop:nn
 {
  \prop_if_in:cnTF { g_runart_var_#1_prop } { #2 }
   {
    \prop_item:cn { g_runart_var_#1_prop } { #2 }
   }
   {
    \str_case:nn { #2 }
     {
      {value}{999999}
      {unit}{\metre}
      {name}{undefined}
     }
   }
 }
\cs_generate_variant:Nn \tl_if_empty:nTF { f }

\cs_new_protected:Nn \runart_variable_use_matte:n
 {
  \use:x % it's necessary to expand the optional argument
   {
    \SI
     [\__runart_use_prop:nn { #1 } {sisetup}]
     {\__runart_use_prop:nn { #1 } {value}}
     {\__runart_use_prop:nn { #1 } {unit}}
   }
 }

\cs_new_protected:Nn \runart_variable_use_formal:n
 {
  \__runart_use_prop:nn { #1 } { name }
 }
\ExplSyntaxOff

\begin{document}

\definevariable{a_car}
 {
  name=a_{\mathrm{car}},
  value=20,
  unit=\metre\per\second,
 }
\definevariable{v_car}
 {
  name=v_{\mathrm{car}},
  value=40,
  unit=\metre,
 }
\definevariable{t_car}
 {
  name=t_{\mathrm{car}},
  value=2,
  unit=\second,
  sisetup={color=red},
 }
\[
\matte{
  a_car=\frac{v_car}{t_car}
}
\]
\[
\formal{
  a_car=\frac{v_car}{t_car}
}
\]
\[
\matte{
  a_car=\frac{v_car}{t_car}
}
\]
Trying to redefine a variable:
\definevariable{t_car}
 {
  name=t_{\mathrm{car}},
  value=2,
  unit=\second,
  sisetup={color=blue},
 }
\[
\matte{
  t_car
}
\]
Trying to redefine a variable, but forgetting the value:
\definevariable{t_car}
 {
  name=t_{\mathrm{car}},
  unit=\second,
  sisetup={color=blue},
 }
\[
\matte{
  t_car
}
\]
\end{document}

如果忘记了某个值,则可以使用后备值(并且可能添加更合理的错误消息)。

在此处输入图片描述

使用局部分配似乎不是最好的方法;例如,您可以在环境(或其变体)\definevariable中使用,但不能在中使用,因为对齐的每个单元都形成一个组。equationalign

相关内容