Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

\newcommand*\fileversion{\input{VERSION}}

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}.

share|improve this question
    
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
add comment

3 Answers

up vote 7 down vote accepted

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

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

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

\makeatletter
{\everyeof{\noexpand}\xdef\fileversion{\@@input VERSION }}
\makeatother
share|improve this answer
    
\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
show 2 more comments

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

\newcommand*\fileversion{%
  \newread\myread
  \openin\myread=VERSION 
  \read\myread to \fileversion
  \closein\myread
  \fileversion
}

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

share|improve this answer
    
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
add comment

I am pretty sure you're using LuaTeX :)

\edef\fileversion{%
  \directlua{
    local f = io.open('VERSION')
    tex.print(f:read())
    f:close()
}}
share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.