![简单的基于 LaTeX3 的解决方案](https://linux22.com/image/393887/%E7%AE%80%E5%8D%95%E7%9A%84%E5%9F%BA%E4%BA%8E%20LaTeX3%20%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88.png)
我正在尝试手动编写一个小脚本,让我在最后添加证明,重述定理...但我在重述时遇到了一些麻烦,因为所有定理都有相同的名称,所以当我想在最后重述它们时,它们都有相同的名称。事实上,我在一个函数中写道:
\edef\namerestate{prAtEndRestate\roman{counterAllProofEnd}}
\begin{restatable}{#2}{\namerestate}\label{thm:prAtEnd\thecounterAllProofEnd}
#4
\end{restatable}
在我的代码中:
\prAtEndRestatei*
\prAtEndRestateii*
但展示出来的两个定理却是一模一样的(最后写的定理)!
知道发生什么问题了吗?
梅威瑟:
\documentclass{article}
\usepackage{mathtools}
\usepackage{amssymb, amsthm, amsmath, thm-restate}
\usepackage{thmtools} %%
\usepackage{hyperref}
\usepackage{etoolbox}
\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}
\newtheorem{corollary}[thm]{Corollary}
\providecommand*\corollaryautorefname{Corollary}
\newtheorem{lemma}[thm]{Lemma}
\providecommand*\lemmaautorefname{Lemma}
\begin{document}
\section{Manual theorems}
\edef\namerestate{manualtheoremi}
\begin{restatable}{thm}{\namerestate}
My first manual theorem
\end{restatable}
\edef\namerestate{manualtheoremii}
\begin{restatable}{thm}{\namerestate}
My second manual theorem
\end{restatable}
Restitution:
\manualtheoremi*
\manualtheoremii*
\end{document}
编辑:这似乎有效,但如果有更好的方法,请告诉我,特别是如果 xparse/latex3e 提出了更好的解决方案:如何扩展一个环境中的几个参数?
答案1
简单的基于 LaTeX3 的解决方案
这是一个使用 LaTeX3 的简单解决方案:
\documentclass{article}
\usepackage{thm-restate}
\usepackage{hyperref}
\usepackage{expl3}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}
\ExplSyntaxOn
\int_new:N \g_tobias_thm_counter_int
\cs_new_protected:Npn \tobias_declare_thm_label:nn #1#2
{
\label { thm #1 prAtEnd #2 }
}
\cs_generate_variant:Nn \tobias_declare_thm_label:nn { xn }
% #1: theorem type
% #2: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_start_proclaim_thm:nn #1#2
{
% Start 'restatable' environment
\restatable {#1} { restatableThm #2 }
% Write the \label command with the appropriate label based on #2
\tobias_declare_thm_label:xn
{ \char_generate:nn { `\: } { 12 } } % colon with catcode 12 (other)
{#2}
}
\cs_generate_variant:Nn \tobias_start_proclaim_thm:nn { nx }
\NewDocumentEnvironment { proclaimRestatable } { m }
{
\int_gincr:N \g_tobias_thm_counter_int % increment the counter
% Start 'restatable' environment
\tobias_start_proclaim_thm:nx
{#1}
{ \int_to_roman:n \g_tobias_thm_counter_int }
}
{ \endrestatable }
\ExplSyntaxOff
\begin{document}
\section{Some section}
\begin{proclaimRestatable}{thm}
My first theorem
\end{proclaimRestatable}
\begin{proclaimRestatable}{thm}
My second theorem
\end{proclaimRestatable}
Restitution:
\restatableThmi*
\restatableThmii*
Reference to \autoref{thm:prAtEndi}.\par
Reference to \autoref{thm:prAtEndii}.
\end{document}
至此,我找到的基于 LaTeX3 的更简单的解决方案就结束了。下面是我想到的第一个解决方案。它有点复杂;我把它留在这里,以防你觉得这个技术和解释有用。
其他(更复杂的)基于 LaTeX3 的解决方案
对于我来说,第一个解决方案中最棘手的部分是使用正确的类别代码生成所需的定理标签,因为在 LaTeX3 语法中(指定后\ExplSyntaxOn
),冒号的类别代码:
是信(11),而在 LaTeX2e 语法中(特别是在文档主体中),其他(12)。a为了做到这一点,我使用了一个标记列表变量() ,该变量使用和\l__tobias_thm_label_tl
逐位组装,并将其作为\tl_put_right:Nx
\tl_put_right:Nn
价值论证( ) 扩展为(V
的宏被替换为\label {#1}
#1
价值标记列表变量)。
\label{thm:prAtEnd...}
实际上,用:
类别代码 11编写(信)似乎也有效——但例如,对于类别代码 10 或 13 则无效。我想这是因为将:
类别代码 11 或 12写入.aux
文件会产生相同的结果(摘自我的.aux
文件):
\newlabel{thm:prAtEndi}{{1.1}{1}{Some section}{thm.1.1}{}}
因此,当读回文件时,标签中的字符标记是使用类别代码 11 还是 12 传递的.aux
都没有区别。不过,我认为保持传递参数的逻辑与之后写入的类别代码完全相同会更清晰。:
\label
\label
\label
\begin{document}
\documentclass{article}
\usepackage{thm-restate}
\usepackage{hyperref}
\usepackage{expl3}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[section]
\providecommand*\thmautorefname{Theorem}
\ExplSyntaxOn
\int_new:N \g_tobias_thm_counter_int
\tl_new:N \l__tobias_thm_label_tl
% #1: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_make_thm_label_name:n #1
{
% Start of label: three tokens
\tl_set:Nn \l__tobias_thm_label_tl { thm }
% Append a colon of category 12 (other)
% [unlike normal colons under \ExplSyntaxOn regime]
\tl_put_right:Nx \l__tobias_thm_label_tl { \char_generate:nn { `\: } { 12 } }
% End of label
\tl_put_right:Nn \l__tobias_thm_label_tl { prAtEnd #1 }
}
\cs_new_protected:Npn \tobias_declare_thm_label:n #1
{
\label {#1}
}
\cs_generate_variant:Nn \tobias_declare_thm_label:n { V }
% #1: theorem type
% #2: unique suffix for theorem (e.g., counter representation as roman numerals)
\cs_new_protected:Npn \tobias_start_proclaim_thm:nn #1#2
{
% Assemble and store the label name with correct category codes inside
% token list variable \l__tobias_thm_label_tl.
\tobias_make_thm_label_name:n {#2}
% Start 'restatable' environment
\restatable {#1} { restatableThm #2 }
% Write the \label command with the appropriate label based on #2
\tobias_declare_thm_label:V \l__tobias_thm_label_tl
}
\cs_generate_variant:Nn \tobias_start_proclaim_thm:nn { nx }
\NewDocumentEnvironment { proclaimRestatable } { m }
{
\int_gincr:N \g_tobias_thm_counter_int % increment the counter
% Start 'restatable' environment
\tobias_start_proclaim_thm:nx
{#1}
{ \int_to_roman:n \g_tobias_thm_counter_int }
}
{ \endrestatable }
\ExplSyntaxOff
\begin{document}
\section{Some section}
\begin{proclaimRestatable}{thm}
My first theorem
\end{proclaimRestatable}
\begin{proclaimRestatable}{thm}
My second theorem
\end{proclaimRestatable}
Restitution:
\restatableThmi*
\restatableThmii*
Reference to \autoref{thm:prAtEndi}.\par
Reference to \autoref{thm:prAtEndii}.
\end{document}
脚注
a. 请注意,在法语文档中,冒号的:
类别代码通常为 13(积极的)以产生所需的间距。因此,我通常不在标签中使用它(避免潜在的问题……)。