I am trying to automate the generation of a text version of my resume. I'd like to incorporate a note to any potential human readers (most plain text resumes are, to my understanding, simply scanned by data mining programs). However, doing this within expl3 itself is tedious—there's only so many times you can see \c_space_tl before it loses its individuality and personal character.

I'd like to simple set up a means to grab the entire contents of an external file by path and shove it into the stream I'm writing. What is the most straightforward way to do this?

I've a setup that looks like so:


\tl_const:Nn \g_resume_preamble_path_tl { preamble.txt }
\tl_const:Nn \g_resume_textout_path_tl { resume.out.txt }

\ior_new:N \g_resume_preamble_ior
\ior_open:Nn \g_resume_preamble_ior { \g_resume_preamble_path_tl }
\iow_new:N \g_resume_textout_iow
\iow_open:Nn \g_resume_textout_iow { \g_resume_textout_path_tl }

  • 1
    Isn't cp preamble.txt resume.out.txt simpler? – egreg Jan 17 '14 at 11:02
  • @egreg Sure it would be, but (as far as I'm aware) iow overwrites the file at the destination at every run. I would be doing this manually every time I compile for submission. – Sean Allred Jan 17 '14 at 17:05
  • 1
    Tell arara to do it! – egreg Jan 17 '14 at 17:06
  • 1
    @egreg but but but but build tools frighten me :( I'll look into it as an option. – Sean Allred Jan 17 '14 at 17:12

If all you are looking to do is read a file line by line and 'do stuff' with the input, then the (experimental) \ior_str_map_inline:Nn seems to be what you are after:

\ior_str_map_inline:Nn \g_resume_preamble_ior
  { \iow_now:Nn \g_resume_textout_iow {#1} }

(We don't have a 'catchfile` equivalent pre-built, although clearly you can manage more-or-less that idea with a mapping.)

  • I've used a string mapping as the way the question is phrased suggests a verbatim copy: I assume in the real case there is a bit more to this. – Joseph Wright Jan 17 '14 at 7:18
  • Actually there isn't—a verbatim copy is all that's required :) – Sean Allred Jan 17 '14 at 17:05
  • @SeanAllred In that case I'd go with egreg's solution! – Joseph Wright Jan 17 '14 at 17:11
  • This solution works like a charm :-) – Sean Allred Jan 17 '14 at 17:20


egreg suggested the use of arara, so I'll provide a rule to, well, copy a file. :) I might include some file handling rules in the next version in order to ease these tasks.

Without further ado, here's the rule, named copy.yaml:

identifier: copy
name: Copy
command: <arara> @{isTrue(isNotEmpty(source) && isNotEmpty(target), copy.concat(' "').concat(source).concat('" "').concat(target).concat('"'))}
- identifier: copy
  default: <arara> @{isWindows('cmd /c copy', 'cp')}
- identifier: source
  flag: <arara> @{parameters.source}
- identifier: target
  flag: <arara> @{parameters.target}

The idea behind this rule is to copy source to target or do nothing when either of the two is missing. The isWindows function helps us to prevent unknown commands when switching from one OS to another. A sample usage is, in your .tex file:

% arara: copy: { source: preamble.txt, target: resume.out.txt }
% arara: pdflatex
% ...

And we are done. :)

  • I appreciate the warning. That was close. Perhaps this is a good time to finally try arara after all… – Sean Allred Jan 17 '14 at 17:54
  • @Sean: don't worry, I can name some friends that use arara way more than I do. :) – Paulo Cereda Jan 17 '14 at 17:56
  • @SeanAllred you won't regret it! I can't image the TeXworld before arara any more (mychemistry.eu/tag/arara) – cgnieder Jan 17 '14 at 19: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.