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.

\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    \\
    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   \\

  name   = (name),
  street = (123 Main St.),
  city   = (city),
  state  = (state),
  zip    = (zip),
  phone  = (phone),


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?

  • 1
    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.

| improve this answer | |
  • 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
  • 1
    @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

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.