英文日期是字符串,如1 January 2016
。为了将它们翻译成中文,我使用以下方法,借助日期计算。
\usepackage{advdate,xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\StrMonthToNum}{ m }
{
\str_case:nnF { #1 } {
{ January } { 1 }
{ February } { 2 }
{ March } { 3 }
{ April } { 4 }
{ May } { 5 }
{ June } { 6 }
{ July } { 7 }
{ August } { 8 }
{ September } { 9 }
{ October } { 10 }
{ November } { 11 }
{ December } { 12 }
} { 12 } % Wrong month, defaults to December/12
}
\ExplSyntaxOff
\begin{document}
\begin{CJK}{UTF8}{gbsn}
\def\cndate #1 #2 #3 {%
#3年% Set year
\StrMonthToNum{#2}月% Set month
#1日% Set day
}
\cndate 1 January 2016
\end{CJK}
\end{document}
输出结果如下:
但是,日期存储在命令中,例如\newcommand{\ENGLISHDATE}{1 January 2016}
。如果要像这样执行,有什么方法可以获取它吗:\cndate{\ENGLISHDATE{}}
?
答案1
我手头没有CJK
——我用其他符号替换了环境和中文符号。
该\cndate
宏明确要求 3 个参数,以空格分隔。这不是由\mydate
或等简单宏提供的\ENGLISHDATE
。
我建议重命名\cndate
为\cndateinternal
并定义\cndate
为
\def\cndate#1{%
\expandafter\cndateinternal#1%
}
这将首先扩展参数 #1,并因此“准备”输入\cndateinternal
。
\documentclass{article}
\usepackage{advdate,xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\StrMonthToNum}{+m }
{
\str_case:nnF { #1 } {
{ January } { 1 }
{ February } { 2 }
{ March } { 3 }
{ April } { 4 }
{ May } { 5 }
{ June } { 6 }
{ July } { 7 }
{ August } { 8 }
{ September } { 9 }
{ October } { 10 }
{ November } { 11 }
{ December } { 12 }
} { 12 } % Wrong month, defaults to December/12
}
\ExplSyntaxOff
\newcommand{\mydate}{29 February 2016}
\begin{document}
\def\cndate#1{%
\expandafter\cndateinternal#1%
}
\def\cndateinternal#1 #2 #3 {%
#3$\dagger$% Set year
\StrMonthToNum{#2}$\sum$% Set month
#1$\pi$% Set day
}
\cndateinternal 1 January 2016 %
\cndate 5 March 2017 %
\cndate{\mydate} % Braces needed
\end{document}
更新
这是一个带有包装器的版本,它负责处理最终的外括号等。
\documentclass{article}
\usepackage{advdate}
\usepackage{xparse}
\usepackage{l3regex}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\StrMonthToNum}{+m }
{
\str_case_x:nnF { #1 } {
{ January } { 1 }
{ February } { 2 }
{ March } { 3 }
{ April } { 4 }
{ May } { 5 }
{ June } { 6 }
{ July } { 7 }
{ August } { 8 }
{ September } { 9 }
{ October } { 10 }
{ November } { 11 }
{ December } { 12 }
} { 12 } % Wrong month, defaults to December/12
}
\NewDocumentCommand{\CnDate}{+m}{%
\tl_set:Nx \l_tmpa_tl {#1} % Expand the date string to a token list
\tl_trim_spaces:N \l_tmpa_tl % Remove spaces tail and head
\regex_replace_all:nnN {\s} {;} \l_tmpa_tl % Replace space '\s` with `;`
\seq_set_split:NnV \l_tmpa_seq {;} {\l_tmpa_tl} % Split the sequence
\DisplayCnDate{\seq_item:Nn \l_tmpa_seq {1}}{\seq_item:Nn \l_tmpa_seq {2}}{\seq_item:Nn \l_tmpa_seq {3}} % Display the date
}
\ExplSyntaxOff
\NewDocumentCommand{\DisplayCnDate}{mmm}{%
#3$\dagger$% Set year
\StrMonthToNum{#2}$\sum$% Set month
#1$\pi$% Set day
}
\newcommand{\mydate}{29 February 2016}
\begin{document}
\CnDate{\mydate} %works
\CnDate \mydate %works
\CnDate 15 January 2016 % Does not work
\DisplayCnDate 15 January 2016 % Does not work too
\CnDate{ 15 January 2016 } % works
(\CnDate{ 15 January 2016 }) % works
\end{document}