# [tex-eplain] [geolsoft@sdf.lonestar.org: Problem with Eplain (with solution)]

Karl Berry karl at freefriends.org
Tue Jul 1 17:07:55 CEST 2003

George - Thanks.

Dorai - are you still working on eplain?  This looks like a
straightforward fix.

Thanks,
karl

Date: Tue, 1 Jul 2003 19:39:01 +0000 (UTC)
From: George Katsitadze <geolsoft at sdf.lonestar.org>
To: karl at cs.umb.edu
Subject: Problem with Eplain (with solution)

First of all, thanks for the great Eplain package.  It helped me a lot in my
work, and was a pleasure to work with.

I have a minor problem related to interfacing Eplain with another package.

--------------------------
Description of the problem
--------------------------

I stumbled upon this problem when I tried to use Eplain with CyrPlain package.
To reproduce the problem you can run the command

\$ tex -fmt cyrtex problem.tex

granted you have generated and installed cyrtex.fmt' format of CyrPlain package
(CyrPlain is shipped with teTeX 1.0 distribution).  Contents of problem.tex':

\input eplain

\def\sectionword{Section}
\definexref{sec-intro}{3.1}{section}
\definexref{sec-next}{3.2}{section}
See \refs{sec-intro} and \refn{sec-next}...

\bye

According to Expanded Plain TeX for version 2.7, this code should produce

See Sections 3.1 and 3.2...

and it does unless I load cyrtex.fmt' format.  With cyrtex.fmt' I get instead

See 3.1 and 3.2...

I have tracked down the problem and provide a solution below.

-----------------------
What caused the problem
-----------------------

CyrPlain package allows to make russified Plain TeX and other Plain TeX based
formats.''  To achieve this, CyrPlain redifines some Plain TeX commands so that
it is able to read and interpret accordingly some LaTeX files (see
plainenc.tex' shipped with CyrPlain).  After these redefinitions, \edef command
expands to something like

\let \@@protect \protect \let \protect \@unexpandable at protect
\afterassignment \let \protect \@@protect \@edef

For Eplain this means the following.  When .aux file is loaded, cross-reference
labels are defined by \@definelabel macro (see xeplain.tex).  This macro calls
\setproperty, prepending it with \global.  The first token produced by expansion
of \setproperty is \edef, which is no longer a primitive command but a macro
with the above expansion.  Therefore \global has no effect and we get a local
definition of the label's class property instead of global, which gets discarded
after the end of current group.  Of course, at the time I reference this label,
\getproperty does not find its class' property (thus Section' is omitted from
the output).

-----------------
Proposed solution
-----------------

To work around this problem, one could use something like this within problem.tex':

\input eplain

\def\sectionword{Section}
\UNPROTECT
\definexref{sec-intro}{3.1}{section}
\definexref{sec-next}{3.2}{section}
\PROTECT
See \refs{sec-intro} and \refn{sec-next}...

\UNPROTECT macro of plainenc.tex' (from CyrPlain) redefines \edef to be again
the native' TeX's primitive.  The problem with this though is that it also
redefines \uppercase and \lowercase, so these commands will not work with
Russian text if they sneak in between \UNPROTECT and \PROTECT.  Not to mention
the ugliness of this solution.

There is a better solution, but it requires modification of xeplain.tex'.  I
added \setpropertyglobal macro as follows (note use of \xdef instead of \edef):

\def\setpropertyglobal#1#2#3{\ece\xdef{#1 at p#2}{#3}}

and called it within \@definelabel instead of \setproperty:

\def\@definelabel#1#2#3{%
\expandafter\gdef\csname\xrlabel{#1}\endcsname{#2}%
\setpropertyglobal{\xrlabel{#1}}{class}{#3}%
}%

See the patch for xeplain.tex' at the end of this file.

I imagine that this problem is not limited to CyrPlain---it could arise with any
package for Plain TeX which borrows code from LaTeX, or even with standalone
packages which make weird redefinitions of \edef.  So IMHO, it is worth

Thanks for your time.  Best wishes,

-------------------- xeplain.tex.patch --------------------
--- xeplain.tex.orig	2003-07-01 14:08:34.000000000 +0300
+++ xeplain.tex	2003-07-01 14:09:38.000000000 +0300
@@ -283,6 +283,7 @@
% atom'' ATOM to have VALUE.
%
\def\setproperty#1#2#3{\ece\edef{#1 at p#2}{#3}}%
+\def\setpropertyglobal#1#2#3{\ece\xdef{#1 at p#2}{#3}}%
%
%
% \getproperty{ATOM}{PROPNAME} expands to the value of the property
@@ -1426,7 +1427,8 @@
\expandafter\gdef\csname\xrlabel{#1}\endcsname{#2}%
%
% Remember what kind of label this is, so \ref will know what to do.
-  \global\setproperty{\xrlabel{#1}}{class}{#3}%
+%  \global\setproperty{\xrlabel{#1}}{class}{#3}%
+  \setpropertyglobal{\xrlabel{#1}}{class}{#3}%
}%
%
%

`