[texhax] Low-level TeX question: string substitution macro

Toby Cubitt tsc25 at cantab.net
Wed Apr 22 15:44:20 CEST 2009

Uwe Lück wrote:
> At 10:39 22.04.09, Toby Cubitt wrote:
>> Once you've processed the document the requisite number of times to get
>> the cross-references right, you can then run the original source file
>> through the sed script to produce a new LaTeX source file, from which all
>> the cleveref commands have been stripped out and replaced by equivalent
>> standard LaTeX, suitable for submitting to a journal (or sending to a
>> colleague) who doesn't have cleveref installed.
> The last thing is quite important, I think, so "poorman" is almost
> inevitable.

Not necessarily. As with any LaTeX package, you can easily just send
cleveref.sty along with the document. If it's saved in the same directory
as the LaTeX document, TeX will process the document just fine. I've
submitted articles to the arXiv preprint server (which automatically
produces postscript and PDF versions) in this way.

The problem is mainly with publishers who don't actually use TeX to
produce the final type-set version from the LaTeX source, but instead
transform the LaTeX into their own in-house mark-up language before
sending to press. Such publishers place restrictions on which (if any)
LaTeX packages can be used, since they likely won't work unless supported
explicitly by their transformation scripts.

> I understand all of this to the effect that cleveref does the clever thing,
> not sed, so cleveref determines an expansion <plain> of a \cref term
> <clever>.


[Well, not quite exactly :) Cleveref doesn't need to expand \cref etc. in
terms of \ref when the document is simply being processed by TeX (it
by-passes \ref altogether), but it does generate an expansion in this way
for the purposes of writing the sed script when the "poorman" option is
supplied. But this isn't particularly relevant to this discussion.]

> When cleveref finds *one* <clever> in "poorman" mode, it tells an external
> program to replace *all* occurrences of <clever> by <plain>.

> To replace sed by TeX, I propose writing to <out>=\jobname.ffd as follows:
>     {\let\ref\relax \let\cref\relax
>      \immediate\write<out>{\string\AddReplacement{<clever>}{<plain>}}}
> (Is cleveref clever enough not to do this twice for *one* <clever>?)

Nope. It's not that clever :) It just writes out one substitution rule for
each cross-reference, whether or not that happens to be identical to a
previous one. At least for sed, it doesn't matter, because applying the
first matching rule will always produce the correct results.

In the latest cleveref version (not yet on CTAN), I also use sed addresses
to cope with babel language changes. I don't know how easy that would be
to replicate with fifinddo.

> fifinddo is in my view better suited for reworking TeX files than those
> other mere string handling packages.

Could be. But cleveref only needs very simple substitutions, so sed is
more than sufficient. The only advantage I see in using fifinddo is that
some (especially Windows) users might not have sed installed, whereas if
they're using cleveref they must have TeX installed. On the other hand,
they'll have to install fifinddo (or whatever other TeX string
substitution package), and it's not completely clear that's any easier...

> Hope this will happen -- Uwe.

If someone sends me a working patch against cleveref.dtx, I'd be happy to
consider including it. I'm unlikely to implement it myself.


More information about the texhax mailing list