3

I'm trying to create my own foo environment, which would be used like this:

\documentclass{article}
\begin{document}
\begin{foo}
a -> b [
  c => d ]
\end{foo}
\end{document}

I'm expecting it to render as:

\begin{equation}
\begin{split}
& a \mapsto b \llbracket \\[1pt]
& \quad c \to d \rrbracket
\end{split}
\end{equation}

Is it at all possible? I need to tell TeX somehow that ->, new line, leading spaces, =>, [, and some other symbols and their combinations must be "mapped" to something else.

yegor256
  • 12,021

1 Answers1

3

Here's an approach that uses the filecontentsdef package to store the contents of the environment in a macro so that we can modify it:

\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}

Screenshot of Compiled Document

You did not specify explicitly when you need a \quad exactly, so it's just a guess.

Strictly speaking, some \tl_to_str:n is not needed, but I put it there just in case.

There's some subtlety in the order of replacement needed; see the comments in the code.

Variables are named according to expl3 naming convention. Edit if you prefer.

There's some additional subtlety with filecontentsdef if you want to use a literal tab character in the environment.

user202729
  • 7,143