我定义了一个以内容为中心并框住内容的环境。
\newsavebox{\tempbox} %Allows to use fbox in newenvironment
\newenvironment{result}[1][\textwidth]
{
\begin{center} %The box will be centered
\begin{lrbox}{\tempbox} %Allows to use fbox in newenvironment
\begin{varwidth}{#1} %Minipage that set its width to the text width it contains
\begin{center} %The text will be centered
}
{
\end{center}
\end{varwidth}
\end{lrbox}\fbox{\usebox{\tempbox}}
\end{center}
}
如果我\qedhere
在环境中使用该命令,它自然会将 qed 符号装箱。我的想法是找到一种方法来让环境检测它是否包含该\qedhere
命令。如果它确实包含该命令,那么它将执行给定的代码(在这种情况下,它将删除字符串,然后在 fbox 环境之外但在最后一个中心环境内重写它,以便将墓碑放在框的旁边)。如果它不包含它,那么它会执行另一个代码(在这种情况下它将是主体中的常规代码)。
梅威瑟:
\documentclass{article}
\usepackage{varwidth,amsthm}
\newsavebox{\tempbox} %Allows to use fbox in newenvironment
\newenvironment{result}[1][\textwidth]
{
\begin{center} %The box will be centered
\begin{lrbox}{\tempbox} %Allows to use fbox in newenvironment
\begin{varwidth}{#1} %Minipage that set its width to the text width it contains
\begin{center} %The text will be centered
}
{
\end{center}
\end{varwidth}
\end{lrbox}\fbox{\usebox{\tempbox}}
\end{center}
}
\DeclareRobustCommand{\qed}{%It redefines the qed command to delete the hfill
\ifmmode \mathqed
\else
\leavevmode\unskip\penalty9999 \hbox{}\nobreak
\, \hbox{\qedsymbol}%
\fi
}
\newenvironment{proof2}
{\begin{proof} \leavevmode \par \nobreak}
{\renewcommand\qedsymbol{$\triangleleft$} \end{proof}}
\begin{document}
\begin{proof2}
Hence, we have
\begin{result}
The result \qedhere
\end{result}
\end{proof2}
\end{document}
=================================================
回复 Peter Grill
我写了这个
\makeatletter
\NewEnviron{result}[1][\textwidth]{%
\StrPosition{\BODY}{\qedhere}[\@Position]%
\IfEq{\@Position}{0}{%
% Does not contain \qedhere
\begin{center}
\begin{lrbox}{\tempbox}
\begin{varwidth}{#1}
\begin{center}
\BODY
\end{center}
\end{varwidth}
\end{lrbox}\fbox{\usebox{\tempbox}}
\end{center}
}{%
%% Does contain \qedhere
\begin{center}
\begin{lrbox}{\tempbox}
\begin{varwidth}{#1}
\begin{center}
\BODY
\end{center}
\end{varwidth}
\end{lrbox}\fbox{\usebox{\tempbox}}
\qedhere
\end{center}
}%
}%
\makeatother
但它没有显示任何内容,所以我只是替换为,它就可以正常$\triangleleft$
工作。现在的问题是\qedhere
\BODY
答案1
一种方法是使用environ
包,通过该包您可以访问\BODY
包含环境主体的内容。然后您可以检查是否\BODY
包含\qedhere
,然后调用不同的环境。
下面我定义了两个环境{WithQedHere}
和{WithoutQedHere}
。{result}
环境用于\StrPosition
确定的位置\qedhere
。如果\@Position
是0
,则字符串不在中\BODY
,否则\BODY
包含出现\qedhere
:
如果此方法存在问题,则另一种方法是进行修改,\qedhere
将布尔标志设置为 true。将内容排版\BODY
到框中,然后检查布尔标志的值并进行适当的切换。不过,这可能需要对内容进行两次排版。
代码:
\documentclass{article}
\usepackage{amsthm}
\usepackage{environ}
\usepackage{xstring}
\newenvironment{WithQedHere}{%
\par Using \textbf{WithQedHere} environment\par%
}{%
}%
\newenvironment{WithoutQedHere}{%
\par Using \textbf{WithoutQedHere} environment\par%
}{%
}%
\makeatletter
\NewEnviron{result}{%
\StrPosition{\BODY}{\qedhere}[\@Position]%
\IfEq{\@Position}{0}{%
%% Does not contain \qedhere
\begin{WithoutQedHere}
\BODY
\end{WithoutQedHere}
}{%
%% Does contain \qedhere
\begin{WithQedHere}
\BODY
\end{WithQedHere}
}%
}%
\makeatother
\newenvironment{proof2}
{\begin{proof} \leavevmode \par \nobreak}
{\renewcommand\qedsymbol{$\triangleleft$} \end{proof}}
\begin{document}
\begin{proof2}
Hence, we have
\begin{result}
The result \qedhere
\end{result}
\end{proof2}
\begin{proof2}
Hence, we have
\begin{result}
The result.
\end{result}
\end{proof2}
\end{document}
答案2
我不会使用xstring
,因为它可能会做出令人讨厌的事情(它会尝试完全扩展参数)。
我宁愿使用它\NewDocumentEnvironment
来获取环境的内容,在本地使其\qedhere
成为无操作,并将其添加到\fbox
主体中的 if present 之后。
请注意,我将 移至正确的位置\renewcommand
以更改 QED 符号。我还使用[b]
以varwidth
将 QED 符号置于底部。
\documentclass{article}
\usepackage{varwidth,amsthm}
\newsavebox{\tempbox} %Allows to use fbox in newenvironment
\ExplSyntaxOn
\NewDocumentEnvironment{result}{O{\textwidth}+b}
{
\begin{center} %The box will be centered
\begin{lrbox}{\tempbox} %Allows to use fbox in newenvironment
\begin{varwidth}[b]{#1} %Minipage that set its width to the text width it contains
\centering %The text will be centered
% make \qedhere a noop
\cs_set_eq:NN \qedhere \prg_do_nothing:
#2
\end{varwidth}
\end{lrbox}\fbox{\usebox{\tempbox}}
% add \qedhere if present in the body
\regex_match:nnT { \c{qedhere} } { #2 } { \qedhere }
\end{center}
}{}
\ExplSyntaxOff
\DeclareRobustCommand{\qed}{%It redefines the qed command to delete the hfill
\ifmmode \mathqed
\else
\leavevmode\unskip\penalty9999 \hbox{}\nobreak
\, \hbox{\qedsymbol}%
\fi
}
\newenvironment{proof2}
{%
\begin{proof}
\renewcommand\qedsymbol{$\triangleleft$}%
\leavevmode\par\nobreak\noindent\ignorespaces
}
{\end{proof}}
\begin{document}
\begin{proof2}
Hence, we have
\begin{result}
The result \qedhere
\end{result}
\end{proof2}
\begin{proof2}
Hence, we have
\begin{result}
The result \\
on several \\
lines\qedhere
\end{result}
\end{proof2}
\begin{proof2}
Hence, we have
\begin{result}
The result
\end{result}
with some more words.
\end{proof2}
\end{document}