创建一个环境名称大写的定理版本

创建一个环境名称大写的定理版本

我想编写一个\createTheorem创建两个环境的宏:一个普通环境和一个“大写”环境。

例如,\createTheorem{defi}{Definition}将创建:

  • 一个环境\begin{defi}...\end{defi}
  • 和一个环境\begin{Defi}...\end{Defi}

你会怎么做?我想知道为什么我的代码不起作用。

我的代码

这是我尝试过的。它不起作用,错误是

缺少 \endcsname 插入。\protect l.13 \documentclass{article}

\usepackage{amsmath}

\newtheorem{theoremForCounter}{theoremForCounter}

\newcommand{\createTheorem}[2]
{ 
 \def\nameNewTheoremCapitalized{\MakeUppercase{#1}}
 \newtheorem{#1}[theoremForCounter]{#2}
 \newtheorem{\nameNewTheoremCapitalized}[theoremForCounter]{#2}
}

\createTheorem{defi}{Definition}

\begin{document}

\begin{defi}
This is a test.
\end{defi}

\begin{Defi}
This is a test.
\end{Defi}

\end{document}

答案1

我不确定这样做有什么用:拥有两个环境defi并且Defi做完全相同的事情是没用的,而且可能会造成混淆。

无论如何,您都可以使用\text_titlecase:n(使用 2020 年 3 月之后发布的 LaTeX)。

\documentclass{article}
\usepackage{amsthm} % probably you wanted this one

\newcounter{counterForTheorem}

\ExplSyntaxOn
\cs_new:Npn \uppercasefirst #1
 {
  \str_uppercase:f { \tl_head:n { #1 } }
  \tl_tail:n { #1 }
 }
\ExplSyntaxOff

\newcommand{\createTheorem}[2]{%
  \newtheorem{#1}[counterForTheorem]{#2}%
  \newtheorem{\uppercasefirst{#1}}[counterForTheorem]{#2}%
}

\createTheorem{defi}{Definition}

\begin{document}

\begin{defi}
This is a test.
\end{defi}

\begin{Defi}
This is a test.
\end{Defi}

\end{document}

替代实施方案:

\documentclass{article}
\usepackage{amsthm} % probably you wanted this one

\newcounter{counterForTheorem}

\makeatletter
\newcommand{\createTheorem}[2]{%
  \newtheorem{#1}[counterForTheorem]{#2}%
  \begingroup
  \edef\temp@a{\@car#1\@nil}%
  \edef\temp@b{\@cdr#1\@nil}%
  \begingroup\edef\x{\endgroup\uppercase{\def\noexpand\temp@a{\temp@a}}}\x
  \edef\temp@a{\temp@a\temp@b}%
  \expandafter\endgroup\expandafter\newtheorem\expandafter{\temp@a}[counterForTheorem]{#2}%
}
\makeatother

\createTheorem{defi}{Definition}

\begin{document}

\begin{defi}
This is a test.
\end{defi}

\begin{Defi}
This is a test.
\end{Defi}

\end{document}

答案2

如上所述,MakeUppercase不可扩展。您可以改用str_uppercase:f可扩展的 expl3 函数:

%! TEX program = lualatex
\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn
\newcommand{\createTheorem}[2]
{ 
 \def\nameNewTheoremCapitalized{\str_uppercase:f{\tl_head:n{#1}}\tl_tail:n{#1}}
 \newtheorem{#1}{#2}
 \exp_args:Nx\newtheorem{\nameNewTheoremCapitalized}{#2}
}
\ExplSyntaxOff

\createTheorem{defi}{Definition}

\begin{document}

\begin{defi}
This is a test.
\end{defi}

\begin{Defi}
This is a test.
\end{Defi}

\end{document}

评论:

  • 在 pdflatex 中将\tl_head采用名称的第一个字节而不是第一个字符,所以我不知道如果第一个字符不是简单的 ASCII 字符会发生什么。
  • 如果第一个字符不是小写字符,newtheorem则会引发错误,因为两个名称相同。
  • 你的宏定义有虚假空间. 并非如此\ExplSyntaxOn
  • 在这种情况下,实现newtheorem恰好已经扩展了内部的参数,因此在传递给它之前无需扩展参数……尽管如此,我不确定这种行为是否能保证……所以我\exp_args:Nx以防万一添加。

答案3

您可以直接使用 TeX 原语\uppercase,但这仍然不可扩展,因此我们必须使用一些技巧。\createTheorem@a用于获取第一个字符,并\createTheorem@b在第一个字符已经大写后调用,并将名称重新组合在一起。

\documentclass{article}

\usepackage{amsmath}

\makeatletter
\long\def\createTheorem@a#1#2\end
  {\uppercase{\createTheorem@b{#1}}{#2}}
\newcommand\createTheorem@b[2]{\newtheorem{#1#2}}
\newcommand{\createTheorem}[2]
{% 
  \newtheorem{#1}{#2}%
  \createTheorem@a#1\end{#2}%
}
\makeatother

\createTheorem{defi}{Definition}

\begin{document}

\begin{defi}
This is a test.
\end{defi}

\begin{Defi}
This is a test.
\end{Defi}

\end{document}

相关内容