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.

2
  • 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}. Jan 15, 2019 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, 2019 at 12:52

1 Answer 1

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.

1
  • 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, 2019 at 18:30

You must log in to answer this question.

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