2

Question

Is it possible to perform text replacement during the first pass of a document by DocTeX ? Specifically, how can I replace ^^J with ^^J%% in a \edef'd macro ?

Background

I had recently noticed that I was repeating the copyright notice no less then three times in my DocTeX files, which is not especially DRY. I've managed to reduce this to one \edef'd preamble, \metadata.

\edef\metadata{================================================================^^J
               \jobname\space(Version\space\fileversion\space-\space\filedate)}^^J
               ================================================================^^J}

I can expand this into a \declarepreamble\metatext...\endpreamble block by wrapping the \declarepreamble into another definition and delaying it's expansion as follows :

\def\expandamble{\declarepreamble\metatext}
\expandafter\expandamble\metadata
\endpreamble

Which DocTex expands into the following in the output files. This triggers errors in other documents that use the generated style/class files since ==== is no macro definition.

%%==================================
PACKAGE (Version 0.0 - 2019/01/15)
==================================

Ideally \MetaPrefix, that is %%, should be prepended to each line as follows.

%%==================================
%%PACKAGE (Version 0.0 - 2019/01/15)
%%==================================

Clearly it is only prepended to the first line as the expansion I'm performing unpacks \metadata as a single line of text and not as 3 lines. I'm not sure how to handle this expansion properly and was hoping for some help.

Homework

David Carlisle provides the following snippet in this answer

\def\replace#1#2#3{%
 \def\tmp##1#2{##1#3\tmp}%
   \tmp#1\stopreplace#2\stopreplace}
\def\stopreplace#1\stopreplace{}

It seems however that one may not pop \metadata in as the first argument. That is calling the macro

\replace{\metadata}{^^J}{^^J\MetaPrefix} % This result should be assigned to a new macro/preamble \metatext

produces the following error, complaining that I'm not in a document environment just yet, nor will I ever be as this is during the first pass by DocTeX.

! LaTeX Error : Missing \begin{document}.

Update

Incorporating the comment from Phelype Oleinik I get the following code

\def\expandamble{\declarepreamble\metatext}
\expandafter\expandamble\expandafter\replace\expandafter{\metadata}{^^J}{^^J\MetaPrefix}
\endpreamble

and the following error

! Illegal parameter number in definition of \metatext. 
  <to be read again> 
                     1

Note

This is related to another question I have open at the moment. I'm trying to solve it by breaking it down into it's component issues.

  • I haven't tried your code, but it looks like that David's \replace command replaces without expansion, so it can't find any occurrence of ^^J in the single token \metadata. I think you'd have to expand \metadata first: \expandafter\replace\expandafter{\metadata}{^^J}{^^J\MetaPrefix}. – Phelype Oleinik Jan 15 at 12:05
  • @PhelypeOleinik thanks for the input, I tried it and updated the question to reflect the output. I'll try play around with the \expandafters if I have any luck I'll report back. – Carel Jan 15 at 12:52
1

You get terminal output of

================================================================
bb280 (Version v1.2 - yesterday) 
================================================================

%%================================================================
%%bb280 (Version v1.2 - yesterday) 
%%================================================================
%%

from

\makeatletter
\def\fileversion{v1.2}
\def\filedate{yesterday}

\def\metadata{================================================================\newline
              \jobname\space(Version\space\fileversion\space-\space\filedate) \newline
              ================================================================\newline}

{\def\newline{^^J}\xdef\metadataA{\metadata}}
{\def\newline{^^J\@percentchar\@percentchar}\xdef\metadataB{\@percentchar\@percentchar\metadata}}

\typeout{\metadataA}

\typeout{\metadataB}


\stop

There is no need to put in ^^J originally if you want to replace it, use something easier to redefine and define that to be ^^J when you need it.

  • Oh that is quite elegant, I hadn't though of substituting, rather then replacing, the new lines. Thanks once again for the help. (P.S. I can't recall If I replied the other day but I did read your responses to my questions about where you work, thanks. I think I tried keeping the responses to a minimum in case the thread got permanently stored on Stack Exchanges chat). – Carel Jan 15 at 18:30

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.