现在我想将组织成两个数组的数据放在一个表中。该过程可行,但我必须为 x 值编写并调用一次,为 y 值编写并调用一次。是否有一个 NewDocumentCommand 可以同时用于两者?非常感谢您的任何建议。
这里是代码:
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx,booktabs}
%
%
\ExplSyntaxOn
%
\fparray_new:Nn \g_x {6}
\fparray_gset:Nnn \g_x {1}{0.907}
\fparray_gset:Nnn \g_x {2}{0.875}
\fparray_gset:Nnn \g_x {3}{0.845}
\fparray_gset:Nnn \g_x {4}{0.817}
\fparray_gset:Nnn \g_x {5}{0.701}
\fparray_gset:Nnn \g_x {6}{0.613}
%
\fparray_new:Nn \g_y {6}
\fparray_gset:Nnn \g_y {1}{27}
\fparray_gset:Nnn \g_y {2}{28}
\fparray_gset:Nnn \g_y {3}{29}
\fparray_gset:Nnn \g_y {4}{30}
\fparray_gset:Nnn \g_y {5}{35}
\fparray_gset:Nnn \g_y {6}{40}
%
\NewDocumentCommand{\calcnumd}{o m}
{\IfValueTF{#1}
{\num[round-mode = figures, round-precision = #1, round-integer-to-decimal]{\fp_to_decimal:n{#2}}}
{\num{\fp_to_decimal:n{#2}}}
}
%
\NewDocumentCommand{\calcx}{o m}
{
\fp_set:Nn \indice {\fparray_item:Nn \g_x {#2}}
\calcnumd[#1]{\indice}
}
%
\NewDocumentCommand{\calcy}{o m}
{
\fp_set:Nn \indice {\fparray_item:Nn \g_y {#2}}
\calcnumd[#1]{\indice}
}
%
\ExplSyntaxOff
%
%
\begin{document}
The experimental data are:
\begin{tabular}{l|llllll}
\toprule
$P/\si{\bar}$ & \calcx[4]{1} & \calcx[4]{2} & \calcx[4]{3} & \calcx[4]{4} & \calcx[4]{5} & \calcx[4]{6} \\
$V/\si{\liter}$ & \calcy{1} & \calcy{2} & \calcy{3} & \calcy{4} & \calcy{5} & \calcy{6} \\
\bottomrule
\end{tabular}
\end{document}
答案1
您可以将\calcx
和\calcy
函数组合成一个函数,只需将其替换\fparray_item:Nn
为\fparray_item:cn
并将x
或y
作为新函数的参数即可:
\NewDocumentCommand{\calc}{omm}
{
\fp_set:Nn \g_indice_fp {\fparray_item:cn {g_#2} {#3}}
\calcnumd[#1]{\g_indice_fp}
}
\indice
请注意,我还用 expl3 fp 变量替换了OP 中的\g_indice_fp
。这称为\calc[4]{x}{4}
或\calc{y}{5}
。
完成这些后,我们自然会更进一步,用一个函数来代替多个调用\calcy{1}
,...。为此,我们只需在前面的定义中添加一个 & 符号:\calcy{6}
\Calc{y}{1}{6}
\int_step_inline:nnn
\NewDocumentCommand{\Calc}{ommm}
{
\int_step_inline:nnn {#3} {#4}
{
\fp_gset:Nn \g_indice_fp {\fparray_item:cn {g_#2} {##1}}
& \calcnumd[#1]{\g_indice_fp}
}
}
\calc
以下是第一个表使用和第二个表使用的输出\Calc
:
完整代码如下:
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx,booktabs}
%
%
\ExplSyntaxOn
%
\fparray_new:Nn \g_x {6}
\fparray_gset:Nnn \g_x {1}{0.907}
\fparray_gset:Nnn \g_x {2}{0.875}
\fparray_gset:Nnn \g_x {3}{0.845}
\fparray_gset:Nnn \g_x {4}{0.817}
\fparray_gset:Nnn \g_x {5}{0.701}
\fparray_gset:Nnn \g_x {6}{0.613}
%
\fparray_new:Nn \g_y {6}
\fparray_gset:Nnn \g_y {1}{27}
\fparray_gset:Nnn \g_y {2}{28}
\fparray_gset:Nnn \g_y {3}{29}
\fparray_gset:Nnn \g_y {4}{30}
\fparray_gset:Nnn \g_y {5}{35}
\fparray_gset:Nnn \g_y {6}{40}
%
\NewDocumentCommand{\calcnumd}{o m}
{\IfValueTF{#1}
{\num[round-mode = figures, round-precision = #1, round-integer-to-decimal]{\fp_to_decimal:n{#2}}}
{\num{\fp_to_decimal:n{#2}}}
}
%
\fp_new:N \g_indice_fp
\NewDocumentCommand{\calc}{omm}
{
\fp_set:Nn \g_indice_fp {\fparray_item:cn {g_#2} {#3}}
\calcnumd[#1]{\g_indice_fp}
}
\cs_generate_variant:Nn \fparray_item:Nn {cn}
% \Calc[offset]{x/y}{start}{finish}
\NewDocumentCommand{\Calc}{ommm}
{
\int_step_inline:nnn {#3} {#4}
{
\fp_gset:Nn \g_indice_fp {\fparray_item:cn {g_#2} {##1}}
& \calcnumd[#1]{\g_indice_fp}
}
}
\cs_generate_variant:Nn \fp_set:Nn {Nx}
\cs_generate_variant:Nn \fparray_item:Nn {cn}
\ExplSyntaxOff
%
%
\begin{document}
The experimental data are:
\begin{tabular}{l|llllll}
\toprule
$P/\si{\bar}$ & \calc[4]{x}{1} & \calc[4]{x}{2} & \calc[4]{x}{3} & \calc[4]{x}{4} & \calc[4]{x}{5} & \calc[4]{x}{6} \\
$V/\si{\liter}$ & \calc{y}{1} & \calc{y}{2} & \calc{y}{3} & \calc{y}{4} & \calc{y}{5} & \calc{y}{6} \\
\bottomrule
\end{tabular}
\bigskip
\begin{tabular}{l|llllll}
\toprule
$P/\si{\bar}$ \Calc[4]{x}{1}{6}\\
$V/\si{\liter}$ \Calc{y}{1}{6} \\
\bottomrule
\end{tabular}
\end{document}
最后,这是第三个版本,其中我用遵循标准约定的名称替换了数组名称\g_x
和,并定义了一个新命令来设置这些数组:\g_y
\ArraySet
\ArraySet{x}{0.907, 0.875, 0.845, 0.817, 0.701, 0.613}
\ArraySet{y}{27, 28, 29, 30, 35, 40}
输出与之前相同。以下是更新后的代码:
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx,booktabs}
%
%
\ExplSyntaxOn
%
\fparray_new:Nn \g_stalks_x_fparray {6}
\fparray_new:Nn \g_stalks_y_fparray {6}
\int_new:N \l_array_index_int
\NewDocumentCommand\ArraySet{mm}
{
\clist_set:Nn \l_tmpa_clist {#2}
\int_zero:N \l_array_index_int
\clist_map_inline:Nn \l_tmpa_clist
{
\int_incr:N \l_array_index_int
\fparray_gset:cVo {g_stalks_#1_fparray} \l_array_index_int {##1}
}
}
%
\NewDocumentCommand{\calcnumd}{o m}
{\IfValueTF{#1}
{\num[round-mode = figures, round-precision = #1, round-integer-to-decimal]{\fp_to_decimal:n{#2}}}
{\num{\fp_to_decimal:n{#2}}}
}
%
\fp_new:N \g_indice_fp
\NewDocumentCommand{\calc}{omm}
{
\fp_set:Nn \g_indice_fp {\fparray_item:cn {g_stalks_#2_fparray} {#3}}
\calcnumd[#1]{\g_indice_fp}
}
\cs_generate_variant:Nn \fparray_item:Nn {cn}
% \Calc[offset]{x/y}{start}{finish}
\NewDocumentCommand{\Calc}{ommm}
{
\int_step_inline:nnn {#3} {#4}
{
\fp_gset:Nn \g_indice_fp {\fparray_item:cn {g_stalks_#2_fparray} {##1}}
& \calcnumd[#1]{\g_indice_fp}
}
}
\cs_generate_variant:Nn \fp_set:Nn {Nx}
\cs_generate_variant:Nn \fparray_item:Nn {cn}
\cs_generate_variant:Nn \fparray_gset:Nnn {cVo}
\ExplSyntaxOff
%
\ArraySet{x}{0.907, 0.875, 0.845, 0.817, 0.701, 0.613}
\ArraySet{y}{27, 28, 29, 30, 35, 40}
\begin{document}
The experimental data are:
\begin{tabular}{l|llllll}
\toprule
$P/\si{\bar}$ & \calc[4]{x}{1} & \calc[4]{x}{2} & \calc[4]{x}{3} & \calc[4]{x}{4} & \calc[4]{x}{5} & \calc[4]{x}{6} \\
$V/\si{\liter}$ & \calc{y}{1} & \calc{y}{2} & \calc{y}{3} & \calc{y}{4} & \calc{y}{5} & \calc{y}{6} \\
\bottomrule
\end{tabular}
\bigskip
\begin{tabular}{l|llllll}
\toprule
$P/\si{\bar}$ \Calc[4]{x}{1}{6}\\
$V/\si{\liter}$ \Calc{y}{1}{6} \\
\bottomrule
\end{tabular}
\end{document}
答案2
请避免使用以下名称\g_x
。名称应类似于
\g_albystalks_x_fparray
目前 LaTeX 的一个问题是软件包内部宏使用的名称存在冲突。统一的命名方法可以避免此类问题。
现在,让我们来解决您的问题。
没有必要使用\indice
(另一个坏名字):\fp_to_decimal:n
将负责扩展其论点。
采用不同的方法象征性名称可以避免该问题\g_x
并保持输入简单。
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx,booktabs}
\ExplSyntaxOn
%%% user level commands
\NewDocumentCommand{\calcnumd}{o m}
{
\IfValueTF{#1}
{
\num
[
round-mode = figures,
round-precision = #1,
round-integer-to-decimal
]
{ \fp_to_decimal:n {#2} }
}
{ \num{ \fp_to_decimal:n {#2} } }
}
\NewDocumentCommand{\definearray}{mm}
{
\albystalks_array_define:nn { #1 } { #2 }
}
\NewDocumentCommand{\usearray}{mmm}
{% #1 = array symbolic name
% #2 = template
% #3 = separator
\albystalks_array_use:nnn { #1 } { #2 } { #3 }
}
\NewExpandableDocumentCommand{\arraycount}{m}
{
\albystalks_array_count:n { #1 }
}
\NewExpandableDocumentCommand{\arrayitem}{mm}
{
\albystalks_array_item:nn { #1 } { #2 }
}
%%% variables and scratch functions
\seq_new:N \l__albystalks_array_seq
\cs_new:Nn \__albystalks_array:n {}
%%% internal functions
\cs_new_protected:Nn \albystalks_array_define:nn
{
\fparray_new:cn { g_albystalks_#1_fparray } { \clist_count:n { #2 } }
\int_step_inline:nn { \clist_count:n { #2 } }
{
\fparray_gset:cnn { g_albystalks_#1_fparray } { ##1 } { \clist_item:nn { #2 } { ##1 } }
}
}
\cs_new_protected:Nn\albystalks_array_use:nnn
{
\seq_clear:N \l__albystalks_array_seq
\cs_gset_protected:Nn \__albystalks_array:n { #2 }
\int_step_inline:nn { \fparray_count:c { g_albystalks_#1_fparray } }
{
\seq_put_right:Nx \l__albystalks_array_seq
{
\__albystalks_array:n
{
\fparray_item:cn { g_albystalks_#1_fparray } { ##1 }
}
}
}
\seq_use:Nn \l__albystalks_array_seq { #3 }
}
\cs_new:Nn \albystalks_array_item:nn
{
\fparray_item:cn { g_albystalks_#1_fparray } { #2 }
}
\cs_new:Nn \albystalks_array_count:n
{
\fparray_count:c { g_albystalks_#1_fparray }
}
\ExplSyntaxOff
\definearray{x}{0.907,0.875,0.845,0.817,0.701,0.613}
\definearray{y}{27,28,29,30,35,40}
\begin{document}
The experimental data are:
\begin{tabular}{
l % header
*{\arraycount{x}}{l} % as many cols as the x array
}
\toprule
$P$ (\si{\bar}) & \usearray{x}{\calcnumd[4]{#1}}{&} \\
$V$ (\si{\liter}) & \usearray{y}{\calcnumd{#1}}{&} \\
\bottomrule
\end{tabular}
\end{document}
使用c
参数说明符,TeX 被指示从参数中的(变量)数据形成控制序列。
包括用于填充数组和从定义的数组中提取项目或其数量的更简单的策略。
这个看似复杂的\usearray
宏,第一个参数是定义数组的符号名称;第二个参数是一个模板,其中#1
代表当前项,因为项将逐个存储然后传递;第三个参数是项之间的分隔符。
另一个用法示例:
The third item in the ``x'' array is
\begin{enumerate}
\item \arrayitem{x}{3} (raw)
\item \num{\arrayitem{x}{3}} (with \texttt{\string\num})
\item \calcnumd{\arrayitem{x}{3}}
\item \calcnumd[2]{\arrayitem{x}{3}}
\end{enumerate}