# How can I expand macros and write the expansion to an external file?

I'm trying to do a bit of single-sourcing with my resume, and would like to write given information to an external text file.

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\keys_define:nn { resume/contact } {
street   .tl_set:N  = \l_resume_contact_street_tl,
street   .initial:n = {default ~ street},
city     .tl_set:N  = \l_resume_contact_city_tl,
city     .initial:n = {default ~ city},
state    .tl_set:N  = \l_resume_contact_state_tl,
state    .initial:n = {default ~ state},
zip      .tl_set:N  = \l_resume_contact_zip_tl,
zip      .initial:n = {default ~ zip},
name     .tl_set:N  = \l_resume_contact_name_tl,
name     .initial:n = {default ~ name},
phone    .tl_set:N  = \l_resume_contact_phone_tl,
phone    .initial:n = {default ~ phone},
}

\iow_new:N \bcv_iow
\NewDocumentCommand \ContactInformation { m }
{
\keys_set:nn { resume / contact } { #1 }

\iow_open:Nn \bcv_iow { \jobname.bcv.txt }
\iow_now:Nn  \bcv_iow
{
~~~~~~~ ~~~Name:~ \tl_use:N \l_resume_contact_name_tl    \\
~~~~~~~ ~~~~~~~:~ \tl_use:N \l_resume_contact_city_tl    ,~
\tl_use:N \l_resume_contact_state_tl   ,~
\tl_use:N \l_resume_contact_zip_tl     \\
~~~~~~~ ~~Phone:~ \tl_use:N \l_resume_contact_phone_tl   \\
}
}
\ExplSyntaxOff

\ContactInformation{
name   = (name),
street = (123 Main St.),
city   = (city),
state  = (state),
zip    = (zip),
phone  = (phone),
}

\begin{document}
hello
\end{document}


which produces the following in *.bcv.txt:

Name: \tl_use:N \l_resume_contact_name_tl \\Street Address: \tl_use:N \l_resume_contact_street_tl \\: \tl_use:N \l_resume_contact_city_tl , \tl_use:N \l_resume_contact_state_tl , \tl_use:N \l_resume_contact_zip_tl \\Phone: \tl_use:N \l_resume_contact_phone_tl \\


where I would expect something like:

          Name: (name)
Street Address: (123 Main St.), (city), (state), (zip)
Phone: (phone)


Obviously, the macros set by l3keys are not being expanded in the file write. How achieve the desired result?

• You should also use a group around your replacement text of \ContactInformation or the initial values will be wept out at the first call of \keys_set:nn. – egreg Jan 13 '14 at 7:55
• @egreg that is more or less intended behavior. I know that this is normally done, but I couldn't think of a case where I'd want to return to the defaults. Am I missing an entire category of functionality? – Sean Allred Jan 13 '14 at 15:55
• Then you don't need .initial, but rather a test that the value has been given. – egreg Jan 13 '14 at 16:01

The behaviour of \iow_now:Nn is detailed in the expl3 documentation:

This functions writes ⟨tokens⟩ to the specified ⟨stream⟩ immediately

Thus what you see is entirely as expected: you are writing the tokens themselves. Thus if you wish to write the expansion of the tokens you should be using normal expl3 expansion variants: \iow_now:Nx (defined as standard).

As well as expansion, you also need to be careful about the material inside the write operation. The LaTeX \\ command creates a new line in typeset output: it does not create a new line in a written file (at least in general). Instead, you should either use \iow_newline: or carry out separate write operations for each line. (We do allow \\ to be used with \iow_wrap:Nnnn: the behaviour here may need some minor improvements.)

As TeX ignores spaces at the start of lines, all of your ~ are ineffective and you will need to use \c_space_tl to make 'pretty' alignments.

• Maybe \exp_not:V instead of \tl_use:N? – egreg Jan 13 '14 at 8:24
• @egreg Probably most sensible as we are inside an x-type expansion, yes – Joseph Wright Jan 13 '14 at 8:27
• Thanks a ton! I think I'm finally starting to understand expl3's expansion control. I had been using the x variant, but my use of \\ (indeed suggested by \iow_wrap:…) was probably causing it to trip up (something about \reserved@? undefined). Thanks again! – Sean Allred Jan 13 '14 at 16:30
• @SeanAllred The LaTeX2e definition of \\ isn't protected, so inside an x-type expansion 'explodes'. As I said, perhaps we need to look at this again (it is a useful shortcut): I'll raise with the team. – Joseph Wright Jan 13 '14 at 16:31