3

In my previous question I asked about templates. I got quite a cool answer, thanks!

There is code like

\long\def\FourierIntroduction{Content}

In say the file Fourier.tex. What I would like is that if I include Fourier.tex that my template (which I made beforehand) takes these comments (if they exist) as data to produce the required document.

Hence, say I do \include{Fourier} in my main document (of course, perhaps include needs to be modified), then this document is opened and searched for commands like \FourierIntroduction and such (I would name the first part after the file itself to avoid collisions, or could this not happen?). If found, the template should execute:

\section{Introduction}
\FourierIntroduction

In such a way that I can modify the order of my template, rerun my document and get excellent result. Any suggestions how to approach this puzzle?

Edit: I have looked around on this website and have found a suggestion to use filehook by one of our moderators. I wonder if this is a good way to go:

\usepackage{filehook}
\usepackage{currfile}

\def\Introduction{Introduction}

\AtEndOfEveryFile{%
  \section{\currfilebase}%
  \subsection{Introduction}%
  \csname \currfilebase \Introduction \endcsname%
}

Edit #2: I have tried to implement "environment" and as suspected: I failed. I have the follow minimal-non-working-example:

\documentclass[11pt]{article}

\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{filehook}
\usepackage{currfile}
\usepackage{environ}
\usepackage{comment}

\def\Introduction{Introduction}
\def\Methods{Methods}

\NewEnviron{introduction}{%
  \long\def{\csname \currfilebase \Introduction \endcsname}{\BODY}%
}%

\AtEndOfEveryFile{%
  \section{\currfilebase}%
  \subsection{Introduction}%
  \csname \currfilebase \Introduction \endcsname%
  \subsection{Methods}%
  \csname \currfilebase \Methods \endcsname%
}%


\begin{document}

\include{Fourier}

\end{document}

And Fourier.tex contains stuff like:

\begin{introduction}
  <TEST>
\end{introduction}

\long\def\FourierMethods{Test TWO}

I hope that the "example" is making clear what my goal is.

Edit #3: Thanks to canaaerus I now know that I should "expand". So, I should replace

\NewEnviron{introduction}{%
      \long\def{\csname \currfilebase \Introduction \endcsname}{\BODY}%
    }%

With

\NewEnviron{introduction}{%
  \expandafter\long\expandafter\xdef\csname \currfilebase \Introduction \endcsname{\BODY}%
}%

But apparently that messes up amsmath and amsthm environments. For example if I have the file Fourier.tex and I \include{Fourier} I get an error when I have this in my Fourier.tex:

\begin{introduction}
  \begin{theorem}
    Test: $f$.
  \end{theorem}
  More.
\end{introduction}

How can I fix this?

5
  • Where the \FourierIntroduction command should be executed?
    – egreg
    Commented Jul 14, 2012 at 23:08
  • 1
    Have a look at Automating error message references. I am using that method for a very similar problem to what you seem to require, so that should be adaptable to your needs. Commented Jul 14, 2012 at 23:08
  • @egreg: Exactly.
    – Jonas T
    Commented Jul 14, 2012 at 23:19
  • @JonasTeuwen Exactly? Is that an answer to "where"?
    – egreg
    Commented Jul 14, 2012 at 23:26
  • @egreg My apologies, it contains Content, and is written in the first code line: \long\def\FourierIntroduction{Content}. Of course, I put more complex things in there...
    – Jonas T
    Commented Jul 14, 2012 at 23:48

1 Answer 1

3

This looks pretty nice already. There are two things you missed. First you need to expand \csname before \def. So take \expandafter and leave away the braces. Next the new command has to be available outside the current scope and also \BODY is only knowing at define time and thus has to be expanded there. So you have to use \xdef which is short for \global\edef instead of \def. All in all this means:

\NewEnviron{introduction}{%
  \expandafter\long\expandafter\xdef\csname \currfilebase \Introduction \endcsname{\BODY}%
}%

will do what you need.

More general solution:

As the above version will make problems when \BODY is not fully expandable here is another try. It took me some effort, but I think the following will expand \BODY exactly one time and thus give you the correct result:

\NewEnviron{introduction}{%
    \expandafter\long\expandafter\xdef\csname \currfilebase \Introduction \endcsname{\expandafter\unexpanded\expandafter{\BODY}}%
}%

A bit of explanation about the expansion:

Let's assume that \BODY contains only Some \textbf{text} for simplicity, which would also trigger the problem in the first try. So now we have

\expandafter\long\expandafter\xdef\csname \currfilebase \Introduction \endcsname{\expandafter\unexpanded\expandafter{\BODY}}

The first two \expandafter make TeX step forward to the \csname-\endcsname construction and expand that, so that we get

\long\xdef{FourierIntroduction}{\expandafter\unexpanded\expandafter{\BODY}}

Now \xdef tries to expand the whole second argument and is here only inhibited by \unexpanded. Those remaining two \expandafter mean TeX jumps over \unexpanded and { to first expand \BODY (one time) and leave

\long\xdef{FourierIntroduction}{\unexpanded{Some \textbf{text}}}

So this is the point at which \xdef eats the \unexpanded and does not expand the argument of \unexpanded (the content of \BODY) any further; leaving something like

\long\global\def{FourierIntroduction}{Some \textbf{text}}
3
  • Excellent! This works. My savior on my birthday :-). However, when I try to put some environment inside the introduction environment like something of amsthm. I get the error: ! Incomplete \iffalse; all text was ignored after line 6. Would you know what causes this? Line 6 is after the \usepackage{environ}.
    – Jonas T
    Commented Jul 15, 2012 at 9:57
  • I have added this to the original message. Thanks! :-).
    – Jonas T
    Commented Jul 15, 2012 at 10:09
  • Perfect. This works splendidly! :-). Now I should try to understand how this expansion works in TeX... Seems to be quite peculiar.
    – Jonas T
    Commented Jul 15, 2012 at 11:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .