使用日期或其他数字实现 Switch Case

使用日期或其他数字实现 Switch Case

我尝试在 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}

在此处输入图片描述

相关内容