I have a revision string automatically saved to a file VERSION (it is the output of git describe and usually looks like v2.2-19-g0a51c27), and define a command


However, each time the command is used, the file is read once. So if I put the command on every page, VERSION will be read many times (= number of pages).

Currently I use savebox to avoid this problem but unfortunately this can not pick up the surrounding formatting style, for example, if surrounding text is in footnotesize, the savebox still uses normal size.

I also tried \edef\fileversion{\input{VERSION}} but somehow TeX gave me 'stack limit' error.

So my question is how to define a command that expands to the contents of VERSION and not \input{VERSION}.

  • We probably need some detail on the nature of the VERSION file – Joseph Wright Aug 14 '10 at 13:35
  • Added. It is from git describe. – Leo Liu Aug 14 '10 at 13:57

A solution in plain tex could be like this (assuming a one-line file)

\immediate\openin\versionread = VERSION
\immediate\read\versionread to \fileversion

A (much) sneakier definition of \fileversion is also possible if you are using the etex extensions (which is probably true these days):

{\everyeof{\noexpand}\xdef\fileversion{\@@input VERSION }}
  • \read's are always \immediate, no? – Joseph Wright Aug 14 '10 at 14:08
  • Thanks for this. Another workaround that I have in mind is to output '\gdef\fileversion{xxxxxxx}' to VERSION so that I can use \input{VERSION} directly. – Leo Liu Aug 14 '10 at 14:09
  • I was assuming that VERSION is 'externally generated' and so we should try to work with it 'as is'. – Joseph Wright Aug 14 '10 at 14:10
  • yeah, that would be my preference too. – Leo Liu Aug 14 '10 at 14:12
  • 2
    At the end of a reading a file you get an EOF (end of file) marker. If you try the example without e-TeX then this will lead to errors during the \xdef. The \everyeof command inserts the \noexpand primitive, which prevents an error. \@@input is the raw TeX \input primitive renamed by LaTeX2e. – Joseph Wright Aug 14 '10 at 14:56

Expanding on what Taco has just posted, I'd go for

  \read\myread to \fileversion

as this will automatically redefine itself and print the version on first use.

  • But the first time you call this macro, it is not expandable, and that gave me trouble in my test file ;) – Taco Hoekwater Aug 14 '10 at 14:14
  • why is the last \fileversion needed? – Leo Liu Aug 14 '10 at 14:21
  • I see. That makes sure the first time also outputs something. – Leo Liu Aug 14 '10 at 14:24
  • Taco, I'd also be worrying about that (LaTeX3 'clear declaration of expandable functions' and everything). Not sure there is a solution unless you read the file in the preamble. – Joseph Wright Aug 14 '10 at 14:32

I am pretty sure you're using LuaTeX :)

    local f = io.open('VERSION')
  • use tex.sprint() then, to get rid of the trailing endline character :) – Taco Hoekwater Aug 14 '10 at 17:47
  • Not yet. I am running tl 2009 and I think luatex is a bit dated. – Leo Liu Aug 14 '10 at 19:02
  • @Taco: I can't see a difference between tex.print and tex.sprint (both don't have a space). The manual states, that the last tex.print() does not have an \endlinechar inserted. As there is only one, it is also the last one. (Actually I always used tex.sprint and wonder why I didn't do so here.) – topskip Aug 14 '10 at 19:31
  • 1
    you are right. must be me getting old, I actually wrote that code ... – Taco Hoekwater Aug 14 '10 at 20:25

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.