5

I thought \group_insert_after:N was for 'exporting' the content of a local variable outside the group where it is set. Apparently,not. What is it for?

\tl_set:Nn \l_foo_tl{W}

\group_begin:
    \tl_set:Nn \l_bar_tl{X}
    \tl_set:Nn \l_foo_tl{X}
    \group_insert_after:N \l_foo_tl
\group_end: % W

%\group_begin:
%   \tl_set:Nn \l_baz_tl{Y}
%   \group_insert_after:N \l_baz_tl
%\group_end: % ! Undefined control sequence. <recently read> \l_baz_tl 
8

If you look at the source of expl3 you'll find that \group_insert_after:N is just defined as the \aftergroup primitive:

\tex_let:D \group_insert_after:N \tex_aftergroup:D

The TeXbook has more information on that (emphasis is mine)

\aftergroup<token>. The <token> is saved on TeX's stack; it will be inserted back into the input just after the current group has been completed and its local assignments have been undone. If several \aftergroup commands occur in the same group, the corresponding commands will be scanned in the same order; for example, ‘{\aftergroup\a\aftergroup\b}’ yields ‘\a\b’.

At the same time the regular grouping rules stay active as well, i.e. stuff you define inside the group will not be available outside. That means that if you want to generate tokens to be inserted after the current group, you have to make those assignments global. This also applies to your example:

\documentclass{article}
\usepackage{expl3}

\begin{document}

\ExplSyntaxOn

% always define your variables to identify name clashes early and save
% time debugging
\tl_new:N \l_bar_tl
\tl_new:N \l_foo_tl

\tl_set:Nn \l_foo_tl{W}

\group_begin:
    \tl_set:Nn \l_bar_tl{X}
    \tl_gset:Nn \l_foo_tl{X} % global assignment!
    \group_insert_after:N \l_foo_tl
\group_end:

\ExplSyntaxOff

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.