3

I have a Latex document where a lot of the text and figures is generated automatically by a program. In a minimal example, the final document is like this:

\documentclass{memoir}

%% This file is generated automatically, and is full of
%% \newcommand definitions
\input{variables}

\begin{document}
  \input{text} % makes heavy use of commands defined in variables.tex
\end{document}

The program that generates the variables.tex file has multiple options which change the return value of the Latex commands it defines. This means that I can always use the same document as structure but control the actual content from variables.tex.

Now I want to have text.tex twice in the same document, each time using a variables-X.tex file built with different options. However, they both define different commands with the same name.

I would go about doing this? In my mind would be something like:

\documentclass{memoir}
\begin{document}

  \input{variables-1}
  \input{text}

  \input{variables-2}
  \input{text}

\end{document}

But that fails with "Command \SequencesDate already defined." (this is one of the commands defined inside variables.tex). If instead of \newcommand I use \renewcommand, I get a "\SequencesDate undefined" error.

My actual case is a bit more complicated. I hope this doesn't add extra noise to the question but I guess it may have some impact on what can be done. The commands defined in the variables.tex are mainly numeric with a grey background. But these commands are still used in operations involving the fp package and that is done by redefining the command that controls the background. Like this:

File variables.tex

\newcommand{\Foo}{\ScriptValue{5.3}}
\newcommand{\Bar}{\ScriptValue{5.6}}

File text.tex

\FPmin{\MinFooBar}{\Foo}{\Bar}
The smallest foobar is \MinFooBar

File document.tex

\documentclass{memoir}
\usepackage{color}
\usepackage{fp}

\input{variables}

%% Color automatic values with grey background
\newcommand{\ScriptValue}[1]{\setlength{\fboxsep}{0pt}\colorbox[gray]{0.8}{\strut #1}}

%% We also want to make operations with those values in LaTeX
%% using FPeval but FPeval fails because ScriptValue gets expanded into
%% something non-numeric.  So we use the following trick: we store the
%% original ScriptValue and FPeval macros, and then replace FPeval with
%% something that temporarily disables ScriptValue while we call the
%% original FPeval.
%% See https://tex.stackexchange.com/questions/159155/identify-pieces-of-text-automatically-generated-from-input-and-new-command
%% and https://tex.stackexchange.com/questions/283655/overloading-functions-of-the-fp-package

\let\RealScriptValue\ScriptValue

\let\RealFPmin\FPmin
\renewcommand{\FPmin}[3]{%
  \renewcommand{\ScriptValue}[1]{##1}%
  \RealFPmin{\UnmarkedResult}{#2}{#3}%
  \edef#1{\noexpand\ScriptValue{\UnmarkedResult}}%
  \renewcommand{\ScriptValue}{\RealScriptValue}%
}


\begin{document}
  \input{text}
\end{document}
  • 1
    Well... this depends on the way you have defined you commands, I would say. If they are all \def , a {\input...} group would be sufficient – user31729 Feb 9 '17 at 19:33
  • well if you do what you suggest did it work? If it did, what is the question? If it did not, what error did you get? – David Carlisle Feb 9 '17 at 19:35
  • Assuming you have \newcommand statements, say for \foo and \foobar you could use \let\foo\relax and \let\foobar\relax at the top of your variables.tex file. Since you're generating this file automatically, it should be easy to let your generator do this for you – user31729 Feb 9 '17 at 19:38
  • The new commands are defined with \newcommand. – carandraug Feb 9 '17 at 19:39
  • @DavidCarlisle I added the actual error message as well as more details on my actual case. – carandraug Feb 9 '17 at 20:12
2

Let your 'variables.tex' - generator do a loop and say for each of the defined commands \foo etc. \let\foo\relax etc.

This way it is undefined at the top of each input of the variables.tex Another way: Use \undef{\foo} or \csundef{foo} from etoolbox package.

variables.tex

\let\foo\relax
\let\foobar\relax
\newcommand{\foo}{Foo}
\newcommand{\foobar}{Foobar}

Driver

\documentclass{memoir}

%% This file is generated automatically, and is full of
%% \newcommand definitions

\begin{document}

  \input{variables}

  \input{text} % makes heavy use of commands defined in variables.tex


  \input{variables}% It will do here too with the same file 

  \input{text} % makes heavy use of commands defined in variables.tex

\end{document}

text.tex

\foo\ and \foobar\ are nice commands

Update

Another approach without tedious \let\foo\relax statements:

Use

\begingroup
\input{variables-1}
\input{text}
\endgroup

for each of the relevant cases. In this case, there must not be any occurence of \input{variables} etc. before!

\input

  • My real case was a bit more convoluted with delayed macro expansions all over the place. Your answer seems to still do the job. Thank you. – carandraug Feb 9 '17 at 20:35
  • @carandraug: See the possible easier way at the end of my answer – user31729 Feb 9 '17 at 21:09
  • I have tried the alternative (groups) and seems to work fine as well. – carandraug Feb 10 '17 at 16:23

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.