我尝试在 LaTex 文件中使用“Switch Case”宏。但我想在“Switch Case”宏中输入月份而不是数字。不幸的是,输出结果为 nada 而不是 31.01.22。
来源:实现 switch 案例
\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\newcommand*{\dothis}[1]{%
\stringcases
{#1}%
{%
{1}{31.01.\the\year}
{2}{28.02.\the\year}
{3}{31.03.\the\year}
{4}{30.04.\the\year}
{5}{31.05.\the\year}
{6}{30.06.\the\year}
{7}{31.07.\the\year}
{8}{31.08.\the\year}
{9}{30.09.\the\year}
{10}{31.10.\the\year}
{11}{30.11.\the\year}
{12}{31.12.\the\year}
}%
{[nada]}%
}
\newcommand{\stringcases}[3]{%
\romannumeral
\str@case{#1}#2{#1}{#3}\q@stop
}
\newcommand{\str@case}[3]{%
\ifnum\pdf@strcmp{\unexpanded{#1}}{\unexpanded{#2}}=\z@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\str@case@end{#3}}
{\str@case{#1}}%
}
\newcommand{\str@case@end}{}
\long\def\str@case@end#1#2\q@stop{\z@#1}
\makeatother
\begin{document}
\dothis{\the\month}
\dothis{2}
\dothis{3}
\dothis{4}
\end{document}
答案1
我不会重新发明轮子……
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dothis}{m}
{
\str_case_e:nnF {#1}
{
{1}{31.01.\the\year}
{2}{28.02.\the\year}
{3}{31.03.\the\year}
{4}{30.04.\the\year}
{5}{31.05.\the\year}
{6}{30.06.\the\year}
{7}{31.07.\the\year}
{8}{31.08.\the\year}
{9}{30.09.\the\year}
{10}{31.10.\the\year}
{11}{30.11.\the\year}
{12}{31.12.\the\year}
}
{[nada]}%
}
\ExplSyntaxOff
\begin{document}
\dothis{\the\month}
\dothis{2}
\dothis{3}
\dothis{4}
\dothis{15}
\end{document}
扩展版本展示了 的潜力expl3
。
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dothis}{om}
{
\ihpro_dothis:ee
{
\int_eval:n { \IfNoValueTF { #1 } { \c_sys_year_int } { #1 } }
}
{ \int_eval:n { #2 } }
}
\cs_new:Nn \ihpro_dothis:nn
{
\str_case_e:nnF {#2}
{
{1}{31.01.#1}
{2}{28.02.#1}
{3}{31.03.#1}
{4}{30.04.#1}
{5}{31.05.#1}
{6}{30.06.#1}
{7}{31.07.#1}
{8}{31.08.#1}
{9}{30.09.#1}
{10}{31.10.#1}
{11}{30.11.#1}
{12}{31.12.#1}
}
{[nada]}%
}
\cs_generate_variant:Nn \ihpro_dothis:nn { ee }
\ExplSyntaxOff
\begin{document}
\dothis{\month}
\dothis{2}
\dothis{3}
\dothis{4}
\dothis{15}
\dothis[2010]{8}
\end{document}
这是闰年的扩展代码。
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dothis}{om}
{
\ihpro_dothis:ee
{
\int_eval:n { \IfNoValueTF { #1 } { \c_sys_year_int } { #1 } }
}
{ \int_eval:n { #2 } }
}
\cs_new:Nn \ihpro_dothis:nn
{
\str_case_e:nnF {#2}
{
{1}{31.01.#1}
{2}{\ihpro_if_leap:nTF{#1}{29}{28}.02.#1}
{3}{31.03.#1}
{4}{30.04.#1}
{5}{31.05.#1}
{6}{30.06.#1}
{7}{31.07.#1}
{8}{31.08.#1}
{9}{30.09.#1}
{10}{31.10.#1}
{11}{30.11.#1}
{12}{31.12.#1}
}
{[nada]}%
}
\cs_generate_variant:Nn \ihpro_dothis:nn { ee }
\prg_new_conditional:Nnn \ihpro_if_leap:n { T, F, TF, p }
{
\int_compare:nTF { \int_mod:nn { #1 } { 400 } == 0 }
{
\prg_return_true:
}
{
\bool_lazy_and:nnTF
{ \int_compare_p:n { \int_mod:nn { #1 } { 4 } == 0} } % divisible by 4
{ !\int_compare_p:n { \int_mod:nn { #1 } { 100 } == 0 } } % but not by 100
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\ExplSyntaxOff
\begin{document}
\dothis{\month}
\dothis{2}
\dothis{3}
\dothis{4}
\dothis{15}
\dothis[2010]{8}
\dothis[2010]{2}
\dothis[2020]{2}
\dothis[2000]{2}
\dothis[1900]{2}
\end{document}
答案2
您可以省略\unexpanded
,为了减少复杂性,请添加检测\the\year
当月份为 2/二月时是否表示闰年:
\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\@ifdefinable\stopromannumeral{\chardef\stopromannumeral=`\^^00}%
\newcommand*{\dothis}[1]{%
\romannumeral\str@case{#1}%
{1}{31.01.\the\year}%
{2}{.02.\the\year}%
{3}{31.03.\the\year}%
{4}{30.04.\the\year}%
{5}{31.05.\the\year}%
{6}{30.06.\the\year}%
{7}{31.07.\the\year}%
{8}{31.08.\the\year}%
{9}{30.09.\the\year}%
{10}{31.10.\the\year}%
{11}{30.11.\the\year}%
{12}{31.12.\the\year}%
{#1}{[nada]}%
\str@case@end
}%
\newcommand{\str@case}[3]{%
\ifnum\pdf@strcmp{#1}{#2}=0
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\str@case@end{#2}{#3}}{\str@case{#1}}%
}%
\@ifdefinable\str@case@end{%
\long\def\str@case@end#1#2#3\str@case@end{%
\ifnum\pdf@strcmp{#1}{2}=0 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\ifnum\the\numexpr((\the\numexpr\the\year\relax)/4)*4\relax=\@firstofone{\the\numexpr\the\year\relax} %
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\ifnum\the\numexpr((\the\numexpr\the\year\relax)/25)*25\relax=\@firstofone{\the\numexpr\the\year\relax} %
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\ifnum\the\numexpr((\the\numexpr\the\year\relax)/400)*400\relax=\@firstofone{\the\numexpr\the\year\relax} %
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}{\@firstoftwo}%
}{\@secondoftwo}%
{\stopromannumeral29}{\stopromannumeral28}%
}%
{\stopromannumeral}%
#2%
}%
}%
\makeatother
\begin{document}
\begingroup
\newcount\tempcnt
\let\year=\tempcnt
\year=1983
\dothis{2}\par
\year=1984
\dothis{2}\par
\year=1700
\dothis{2}\par
\year=1800
\dothis{2}\par
\year=1900
\dothis{2}\par
\year=2000
\dothis{2}\par
\year=2100
\dothis{2}\par
\endgroup
\dothis{\the\month}\par
\dothis{2}\par
\dothis{3}\par
\dothis{4}\par
\end{document}
答案3
以下灵感来自egreg 的回答:
如果不需要闰年条件,那么您可以将闰年计算合并到用于计算和显示二月最后一天的代码中 - 以下代码是\int_eval:n
(整数)和\fp_eval:n
(浮点数)的混合 -\fp_eval:n
您可以评估比较运算符(如=
/ )!=
和布尔运算符(如&&
/ )||
:
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dothis}{om}
{
\ihpro_dothis:ee
{
\int_eval:n { \IfNoValueTF { #1 } { \c_sys_year_int } { #1 } }
}
{ \int_eval:n { #2 } }
}
\cs_new:Nn \ihpro_dothis:nn
{
\str_case_e:nnF {#2}
{
{1}{31.01.#1}
{2}{
\int_eval:n{
% the \fp_eval-expression yields 1 for leap-years, 0 otherwise.
\fp_eval:n { ( \int_mod:nn {#1}{4}=0 && \int_mod:nn{#1}{100}!=0 )
|| \int_mod:nn {#1}{400}=0 } + 28
}.02.#1
}
{3}{31.03.#1}
{4}{30.04.#1}
{5}{31.05.#1}
{6}{30.06.#1}
{7}{31.07.#1}
{8}{31.08.#1}
{9}{30.09.#1}
{10}{31.10.#1}
{11}{30.11.#1}
{12}{31.12.#1}
}
{[nada]}%
}
\cs_generate_variant:Nn \ihpro_dothis:nn { ee }
\ExplSyntaxOff
\begin{document}
\dothis{\month}
\dothis{\the\month}
\dothis{2}
\dothis{3}
\dothis{4}
\dothis{15}
\dothis[2010]{8}
\dothis[2000]{2}
\dothis[1900]{2}
\dothis[1984]{2}
\dothis[1700]{2}
\dothis[1800]{2}
\dothis[1900]{2}
\dothis[2000]{2}
\dothis[2010]{2}
\dothis[2020]{2}
\dothis[2100]{2}
% This yields an error-message
% ! Missing number, treated as zero :
% \dothis{no number}
\end{document}