检测是否包含给定命令/字符串的环境

检测是否包含给定命令/字符串的环境

我定义了一个以内容为中心并框住内容的环境。

\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。如果\@Position0,则字符串不在中\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}

在此处输入图片描述

相关内容