4

This is what I'm trying to do:

\documentclass{article}
\begin{document}
\start
Hello, world!
\stop
\print % here!
\end{document}

I'm expecting Hello, world! to be printed twice. The second time by the \print command. I want \start to start listening to everything that is being printed, and \stop to stop it and put everything into the variable/command \print.

yegor256
  • 12,021
  • 2
    your question is not very clear you could save the original tokens in a macro, lor you could make a box with the typeset tokens (with no page breaking or figures etc) or you could access hooks in the output routine and save the page box (but then you would not want any end marker in the main document as it would depend were the page break happened. You should not use \stop as that is a satndard latex command and will stop latex – David Carlisle Sep 04 '21 at 21:34
  • 1
    The environ package would put everything between \begin{foo} and \end{foo} (for example) into \BODY, although \BODY is only accessible inside the environment. – John Kormylo Sep 05 '21 at 15:47
  • For verbatim content https://tex.stackexchange.com/a/513810/250119 should work – user202729 Nov 01 '21 at 14:23

3 Answers3

8

tokcycle does this with alternate syntax. If you need to digest #-style arguments, more is required.

In this case, the variable into which the environment is stored is the token list \cytoks.

\documentclass{article}
\usepackage{tokcycle}
\begin{document}
\tokencyclexpress
Hello, world!
\endtokencyclexpress
\the\cytoks % here!
\end{document}

enter image description here

If you wanted the exact syntax described in the OP's question and wanted to digest #-style arguments, then this extended-tokcycle environment can make a go of it.

Further, this MWE shows that the environment does not merely stored the result of executing the environment, but actually stores the tokens making it up. We see this in that changing the value of \ifmymode changes the output of \print.

\documentclass{article}
\usepackage{tokcycle}
\xtokcycleenvironment\start
  {\whennotprocessingparameter##1{\addcytoks{##1}}}
  {\processtoks{##1}}
  {\addcytoks{##1}}
  {\addcytoks{##1}}
  {\let\stop\endstart}
  {\tcafterenv{\def\print{\the\cytoks}}}
\newif\ifmymode
\begin{document}
\mymodefalse
\start
\newcommand\z[1]{\ifmymode This is it: #1\else Fuggedaboutit!\fi}
Testing ``\z{Hi Mom}''
\stop

\mymodetrue \print % here! \end{document}

enter image description here

Of course, the real power in tokcycle isn't just collecting the tokens, but in providing the ability to manipulate them in the input stream. For example, the environment can be set up to change all i tokens to I (assuming that such a change will not break any macros), in addition to all the prior stuff:

\documentclass{article}
\usepackage{tokcycle}
\xtokcycleenvironment\start
  {\whennotprocessingparameter##1{\ifx i##1\addcytoks{I}\else
    \addcytoks{##1}\fi}}
  {\processtoks{##1}}
  {\addcytoks{##1}}
  {\addcytoks{##1}}
  {\let\stop\endstart}
  {\tcafterenv{\def\print{\the\cytoks}}}
\newif\ifmymode
\begin{document}
\mymodefalse
\start
\newcommand\z[1]{\ifmymode This is it: #1\else Fuggedaboutit!\fi}
Testing ``\z{Hi Mom}''
\stop

\mymodetrue \print % here! \end{document}

enter image description here

yegor256
  • 12,021
  • thanks a lot for your package, maybe you can help me with this too: https://tex.stackexchange.com/questions/614211/how-to-add-cytoks-to-tokencyclexpress – yegor256 Sep 05 '21 at 16:26
  • @yegor256 \cytoks is reset upon entry into the token cycle, but I'll see if I can save it somewhere and accomplish your desire. – Steven B. Segletes Sep 05 '21 at 16:34
4

Not sure what this should be for, but you can do

\documentclass{article}

\newcommand{\start}{}% just for safety \newcommand{\print}{}% just for safety \long\def\start#1\stop{\def\print{#1}\print}

\begin{document}

\start Hello, world! \stop

\print

\end{document}

enter image description here

egreg
  • 1,121,712
0

Listening is what environments are already actually doing to the input stream.

If we define an environment to store everything it has into a global variable (and the environment also prints everything it has), then we can reprint as many times as desired from the global variable.

listening

The \begin{listen} and \end{listen} could be replaced by wrapper commands like \startlistening and \stoplistening.

tokcycles is designed for manipulating the input stream, if that is required, and therefore much more powerful than mere copying.

MWE

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

%===== \tl_new:N \l_mytemp_tl %===== \NewDocumentCommand { \clearlisten } { } { \tl_clear:N \l_mytemp_tl } \NewDocumentCommand { \printlisten } { } { % \tl_show:N \l_mytemp_tl \tl_use:N \l_mytemp_tl } \NewDocumentEnvironment { listen } { +b } { \tl_gset:Nn \l_mytemp_tl { #1 } \tl_use:N \l_mytemp_tl

} { }

\ExplSyntaxOff

\begin{document} \begin{listen} Hello, world!

The cat sat on the mat. \begin{tabular}[b]{||c||}\hline\hline fox\\hline\hline dog\\hline\hline \end{tabular}.

\end{listen}

\printlisten \printlisten \end{document}

Cicada
  • 10,129