![如何重新定义我的自定义环境中的符号?](https://linux22.com/image/455705/%E5%A6%82%E4%BD%95%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89%E6%88%91%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E7%8E%AF%E5%A2%83%E4%B8%AD%E7%9A%84%E7%AC%A6%E5%8F%B7%EF%BC%9F.png)
我正在尝试创建自己的foo
环境,其使用方式如下:
\documentclass{article}
\begin{document}
\begin{foo}
a -> b [
c => d ]
\end{foo}
\end{document}
我期望它呈现为:
\begin{equation}
\begin{split}
& a \mapsto b \llbracket \\[1pt]
& \quad c \to d \rrbracket
\end{split}
\end{equation}
这有可能吗?我需要以某种方式告诉 TeX ->
,、换行符、前导空格、、=>
和[
一些其他符号及其组合必须“映射”到其他东西。
答案1
这是一种使用filecontentsdef
包将环境的内容存储在宏中,以便我们可以修改它:
\documentclass{article}
\usepackage{filecontentsdef}
\usepackage{amsmath}
\usepackage{stmaryrd} % Provides \llbracket and \rrbracket.
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_replace_all:Nnn {Nx}
\NewDocumentEnvironment {foo} {} {
% Use filecontentsdef to store everything until "\endfilecontentsdefmacro"
% into a macro named "\l__envcontents_tmp_tl".
\filecontentsdefmacro \l__envcontents_tmp_tl
} {
\endfilecontentsdefmacro
\str_set:NV \l__envcontents_tmp_tl \l__envcontents_tmp_tl
% Drop the last newline (^^M) character
\str_set:Nx \l__envcontents_tmp_tl {\str_range:Nnn \l__envcontents_tmp_tl {1} {-2}}
%%%% Do Replacements %%%%
\tl_replace_all:Nxn \l__envcontents_tmp_tl {\tl_to_str:n{->}} {\mapsto}
\tl_replace_all:Nxn \l__envcontents_tmp_tl {\tl_to_str:n{=>}} {\to}
\tl_replace_all:Nxn \l__envcontents_tmp_tl {[} {\llbracket}
\tl_replace_all:Nxn \l__envcontents_tmp_tl {]} {\rrbracket}
% Replace "(newline)(space)(space)" with "\\[1pt] & \quad". This must be done after
% the replacement of "[" and "]", above, otherwise "[1pt]" gets replaced by "\llbracket 1pt \rrbracket".
\tl_replace_all:Nxn \l__envcontents_tmp_tl {\cs_to_str:N \^^M \c_space_tl \c_space_tl} {\\[1pt] & \quad}
% Replace "(newline)" with "\\[1pt] &".
% This must be done after the replacement of "(newline)(space)(space)"
\tl_replace_all:Nxn \l__envcontents_tmp_tl {\cs_to_str:N \^^M} {\\[1pt] &}
% Wrap contents in "equation" and "split" environment.
\tl_put_left:Nn \l__envcontents_tmp_tl {\begin{equation} \begin{split} &}
\tl_put_right:Nn \l__envcontents_tmp_tl {\end{split} \end{equation}}
% Typeset the result.
\l__envcontents_tmp_tl
}
\ExplSyntaxOff
\begin{document}
Example, using custom environment:
\begin{foo}
a -> b [
c => d ]
\end{foo}
Example, entered explicitly:
\begin{equation}
\begin{split}
& a \mapsto b \llbracket \\[1pt]
& \quad c \to d \rrbracket
\end{split}
\end{equation}
\end{document}
您没有明确指定何时需要\quad
,因此这只是一个猜测。
严格来说,有些\tl_to_str:n
是不需要的,但我还是把它放在那里以防万一。
所需替换的顺序有一些微妙之处;请参阅代码中的注释。
变量根据expl3
命名约定命名。如果您愿意,可以进行编辑。
filecontentsdef
如果您想在环境中使用文字制表符,则还有一些额外的微妙之处。