Replace a string inside an environment

Assuming Steven B. Segletes' interpretation is correct, you could do something like this.

\documentclass {article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{environ}
\usepackage{etoolbox}

\newcommand{\testone}{Test one.}
\NewEnviron{test}{%
\newcommand\patch{\patchcmd{\BODY}{t1}{\testone}{\patch}{}}
\patch\BODY}

\begin{document}
\begin{test}
    t1 abc t1 def
\end{test}
\end{document}

The environ package allows us to create environments which 'scoop' their contents into the \BODY command. The etoolbox package provides \patchcmd, which is used to replace t1 with \testone. By default, only the first instance is replaced, but the fourth argument of \patchcmd is executed on success (and the fifth on failure). This mechanism is used to recursively call the \patch command until all instances of t1 are replaced.

Of course you need to be careful with spaces following instances of t1; exactly what you need to do depends on your actual usage case.


The most flexible way would be to use regular expressions.

\documentclass{article}
%\usepackage{xparse} % uncomment if using LaTeX prior to release 2020-10-01

\ExplSyntaxOn

\tl_new:N \l__blackened_test_tl

\NewDocumentEnvironment{test}{+b}
 {
  \tl_set:Nn \l__blackened_test_tl { #1 }
  \regex_replace_all:nnN { \,? (\ )? t1 } { \1 \c{testone} } \l__blackened_test_tl
  \tl_use:N \l__blackened_test_tl
 }
 {}

\ExplSyntaxOff

\newcommand{\testone}{test one}

\begin{document}

\begin{test}
First t1 without a comma.

Then, t1 with a comma.
\end{test}

\end{document}

test

The search regular expression means "a possible comma, followed by a possible space, followed by t1; the replacement expression is “if there was a space, reinsert it, then insert \testone”.


An approach with listofitems. See SUPPLEMENT for a version that removes trailing commas (OP had mentioned that in a comment).

\documentclass {article}
\usepackage{environ,listofitems}

\newcommand{\testone}{Test one.}
\NewEnviron{test}{%
  \setsepchar{t1}%
  \readlist\myenv{\BODY}%
  \foreachitem\z\in\myenv[]{%
    \z
    \ifnum\zcnt<\listlen\myenv[]\relax\testone\fi
  }%
}

\begin{document}

\begin{test}
    Here is t1 and t1 again.

    Multi paragraph t1 OK!
\end{test}

\end{document}

SUPPLEMENT

\documentclass {article}
\usepackage{environ,listofitems}

\newcommand{\testone}{Test One}
\makeatletter
\NewEnviron{test}{%
  \setsepchar{t1/,}%
  \readlist\myenv{\BODY}%
  \foreachitem\z\in\myenv[]{%
    \if\relax\myenv[\zcnt,1]\relax\expandafter\@gobble\z\else\z\fi
    \ifnum\zcnt<\listlen\myenv[]\relax\testone\fi
  }%
}
\makeatother

\begin{document}

\begin{test}
    Here is t1 and t1, again.

    Multi paragraph t1 OK!
\end{test}

\end{document}

enter image description here

Tags:

Environments