# How can I do unvbox when define macro?

This is another approach to solve the problem in question "How can I write to file part of text between two flags?".

I try to "remember" parts of text to use them later. So, I do

\newbox\@tmpbox
\def\startsync{\setbox\@tmpbox\vbox\bgroup}
\def\esync{\egroup\writepart}
\def\syncpoint{\esync\startsync}
\newcount\p@rts
\p@rts0
\long\def\writepart{
\@roman\p@rts\par
\expandafter\xdef\csname apart\@roman\p@rts\endcsname{\unvbox\@tmpbox}
}
\def\insrt#1{\csname apart\@roman #1\endcsname}


but TeX don't do what I want: \xdef defines macro like \aparti with unexpanded \unvbox\@tmpbox, so, when I call \insrt{1}, I see contents of latest text portion instead of first!

How can I define this macro so, that every \apartXXX would be expanded into corresponding text portion?

• the contents of a box are not tokens, you can not store them in a macro. Feb 16, 2016 at 15:07
• Perhaps you could just save the text in a regular macro. \def\partI{Text} Feb 16, 2016 at 18:32
• @AndrewCashner, I want to simplify, not to write something like \addblock{a lot of paragraphs}. I will try also some variants. Feb 16, 2016 at 19:32
• But you intend to write \startsync A lot of paragraphs...\esync, don’t you? As D.C. says, you need to capture your content as tokens, not as a (digested) vertical list! You might want to consider the environ package, that lets you capture the contents of an environment in a macro called \BODY, that you can subsequently copy to another control sequence (keep in mind, however, that this is only syntactic sugar for something that remains essentially equivalent to \def\BODY{...}).
– GuM
Feb 16, 2016 at 20:16

I think you want something like this; note that you can't store boxes in macros, but you can store tokens.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_eddyem_sync_items_seq
\int_new:N \g_eddyem_sync_part_int

\cs_new_protected:Npn \startsync #1 \endsync
{
\seq_set_split:Nnn \l_eddyem_sync_items_seq { \syncpoint } { #1 }
\seq_map_inline:Nn \l_eddyem_sync_items_seq
{
\int_gincr:N \g_eddyem_sync_part_int
\tl_new:c { g_eddyem_sync_part \int_to_roman:n { \g_eddyem_sync_part_int} _tl }
\tl_gset:cn { g_eddyem_sync_part \int_to_roman:n { \g_eddyem_sync_part_int} _tl } { ##1 }
\int_to_roman:n \g_eddyem_sync_part_int\par
}
}

\NewDocumentCommand{\insrt}{m}
{
\tl_use:c { g_eddyem_sync_part \int_to_roman:n { #1 } _tl }
}
\ExplSyntaxOff

\begin{document}

\startsync
This is the first part
\syncpoint
This is the second part
\syncpoint
This is the third part
\endsync

Some text in between

\startsync
This is the fourth part
\endsync

Some text before printing the parts

\insrt{1}

\insrt{2}

\insrt{4}

\insrt{3}

\end{document}


How does this work? First we collect all tokens between \startsync and \endsync, then split items at \syncpoint (if it appears, which is optional).

After the splitting, each item is saved in a token list variable, indexed by an integer variable that's incremented at each found item.

The macro \insrt just takes its argument and delivers the contents of the appropriate variable.

• That's great! Thanks! If I have anything figured ... Are you sure that it cannot be done with simple tex commands, not that strange macros? Feb 16, 2016 at 20:31
• @Eddy_Em Of course it can be done; but why doing the hard work when you have predefined functions that do it for you? Would you program a browser in Assembler? Feb 16, 2016 at 20:32
• I try to use external packages as small as possible. Don't like to read weird documentation to packages. The macros you write absolutely unclear for me. That's like a lots of \expandafter in Knuths book ☺ Feb 16, 2016 at 20:35