是否可以调整持续时间计算宏以在 foreach 循环中使用它?

是否可以调整持续时间计算宏以在 foreach 循环中使用它?

我想绘制时间轴来说明时间计算。当我放置此宏时定义在这里来自@egreg 我有这些错误:

!未定义的控制序列。\LaTeX3 错误:缺少插入 *。

这是我单独使用 foreach 循环(没有使用此宏)得到的结果。

\foreach \h/\min in {1/15,4/45,9/30}
    {\draw (\h,.15)--++(0,-.3)node[below]{\h\,h \min\,min};
    }

截屏

\documentclass{article}
\usepackage{tikz}
\usepackage[french]{babel}
\usetikzlibrary{babel}
% from https://tex.stackexchange.com/a/511874/138900
\usepackage{xparse}
\usepackage{siunitx}

\sisetup{locale=FR}

\ExplSyntaxOn

\NewDocumentCommand{\hms}{ o m }
 {
  \ensuremath
   {
    \IfNoValueTF { #1 }
     {
      \andrec_hms:Ve \l_andrec_hms_sep_str { \tl_to_str:n { #2 } }
     }
     {
      \andrec_hms:ee { \tl_to_str:n { #1 } } { \tl_to_str:n { #2 } }
     }
   }
 }
\NewDocumentCommand{\sethmssep}{m}
 {
  \str_set:Nn \l_andrec_hms_sep_str { #1 }
 }

\cs_new_protected:Nn \andrec_hms:nn
 {
  \group_begin:
  \seq_set_split:Nnn \l__andrec_hms_seq { #1 } { #2 }
  % normalize the sequence to have three (or more!) items
  \int_compare:nT { \seq_count:N \l__andrec_hms_seq = 1 }
   {
    \seq_put_right:Nn \l__andrec_hms_seq { 0 }
   }
  \int_compare:nT { \seq_count:N \l__andrec_hms_seq = 2 }
   {
    \seq_put_right:Nn \l__andrec_hms_seq { 0 }
   }
  % print
  \bool_set_false:N \l__andrec_hms_thinspace_bool
  \__andrec_hms_print:nn { 1 } { h }
  \__andrec_hms_print:nn { 2 } { m }
  \__andrec_hms_print:nn { 3 } { s }
  \group_end:
}
\cs_generate_variant:Nn \andrec_hms:nn { Ve,ee }

\cs_new_protected:Nn \__andrec_hms_print:nn
 {
  \fp_compare:nF { 0\seq_item:Nn \l__andrec_hms_seq { #1 } = 0 }
   {
    \bool_if:NT \l__andrec_hms_thinspace_bool { \, }
    \num{\fp_eval:n { 0\seq_item:Nn \l__andrec_hms_seq { #1 } }} \, \mathrm{#2}
    \bool_set_true:N \l__andrec_hms_thinspace_bool
   }
 }
\ExplSyntaxOff

\sethmssep{:}
\begin{document}
\begin{tikzpicture}
\draw[->] (-.5,0)--(10,0);
\foreach \h/\min in {1/15,4/45,9/30}
    {\draw (\h,.15)--++(0,-.3)%node{$\hms{\h:\min}$};%<- this dont work !
    node[below]{\h\,h \min\,min};
    }
\end{tikzpicture}
\end{document}

是否可以改进这个宏来编写六十进制持续时间,以便它可以在 foreach 循环中使用?

答案1

去掉\tl_to_str:n参数中的 —— 这可以防止参数的扩展,而这正是您所需要的。我只更改了代码中的两行,并用注释标记了它们。

\documentclass{article}
\usepackage{tikz}
\usepackage[french]{babel}
\usetikzlibrary{babel}
% from https://tex.stackexchange.com/a/511874/138900
\usepackage{xparse}
\usepackage{siunitx}

\sisetup{locale=FR}

\ExplSyntaxOn

\NewDocumentCommand{\hms}{ o m }
 {
  \ensuremath
   {
    \IfNoValueTF { #1 }
     {
      \andrec_hms:Ve \l_andrec_hms_sep_str { #2 } % Used to say \tl_to_str:n { #2 }
     }
     {
      \andrec_hms:ee { \tl_to_str:n { #1 } } { #2 } % Used to say \tl_to_str:n { #2 }
     }
   }
 }
\NewDocumentCommand{\sethmssep}{m}
 {
  \str_set:Nn \l_andrec_hms_sep_str { #1 }
 }

\cs_new_protected:Nn \andrec_hms:nn
 {
  \group_begin:
  \seq_set_split:Nnn \l__andrec_hms_seq { #1 } { #2 }
  % normalize the sequence to have three (or more!) items
  \int_compare:nT { \seq_count:N \l__andrec_hms_seq = 1 }
   {
    \seq_put_right:Nn \l__andrec_hms_seq { 0 }
   }
  \int_compare:nT { \seq_count:N \l__andrec_hms_seq = 2 }
   {
    \seq_put_right:Nn \l__andrec_hms_seq { 0 }
   }
  % print
  \bool_set_false:N \l__andrec_hms_thinspace_bool
  \__andrec_hms_print:nn { 1 } { h }
  \__andrec_hms_print:nn { 2 } { m }
  \__andrec_hms_print:nn { 3 } { s }
  \group_end:
}
\cs_generate_variant:Nn \andrec_hms:nn { Ve,ee }

\cs_new_protected:Nn \__andrec_hms_print:nn
 {
  \fp_compare:nF { 0\seq_item:Nn \l__andrec_hms_seq { #1 } = 0 }
   {
    \bool_if:NT \l__andrec_hms_thinspace_bool { \, }
    \num{\fp_eval:n { 0\seq_item:Nn \l__andrec_hms_seq { #1 } }} \, \mathrm{#2}
    \bool_set_true:N \l__andrec_hms_thinspace_bool
   }
 }
\ExplSyntaxOff

\sethmssep{:}
\begin{document}
\begin{tikzpicture}
\draw[->] (-.5,0)--(10,0);
\foreach \h/\min in {1/15,4/45,9/30}
    {
        \draw (\h,.15)--++(0,-.3) node{$\hms{\h:\min}$};
    }
\end{tikzpicture}
\end{document} 

相关内容