1 Support for formats based on plainTEX

The following code duplicates or emulates parts of L^{A}TEX 2ε that are needed for babel.

1 ⟨∗code⟩

 2 \ifx\adddialect\@undefined

When \adddialect is still undefined we are making a format. In that case only the first part of this file is needed.

 3 \def\@empty{}

We need to define \loadlocalcfg for plain users as the L^{A}TEX definition uses

\InputIfFileExists.
 4 \def\loadlocalcfg#1{%
 5  \openin0#1.cfg
 6  \ifeof0
 7  \closein0
 8  \else
 9  \closein0
10  {\immediate\write16{*************************************}%
11  \immediate\write16{* Local config file #1.cfg used}%
12  \immediate\write16{*}%

13 }

14  \input #1.cfg\relax
15  \fi

We have to execute \@endofldf in this case

16  \@endofldf

17 }

We want to add a message to the message L^{A}TEX 2.09 puts in the \everyjob register. This could be done by the following code:

    \let\orgeveryjob\everyjob
    \def\everyjob#1{%
      \orgeveryjob{#1}%
      \orgeveryjob\expandafter{\the\orgeveryjob\immediate\write16{%
          hyphenation patterns for \the\loaded@patterns loaded.}}%
      \let\everyjob\orgeveryjob\let\orgeveryjob\@undefined}

The code above redefines the control sequence \everyjob in order to be able to add something to the current contents of the register. This is necessary because the processing of hyphenation patterns happens long before L^{A}TEX fills the register. There are some problems with this approach though.

• When someone wants to use several hyphenation patterns with SLiTEX the above scheme won’t work. The reason is that SLiTEX overwrites the contents of the \everyjob register with its own message.

• Plain TEX does not use the \everyjob register so the message would not be displayed.

To circumvent this a ‘dirty trick’ can be used. As this code is only processed when creating a new format file there is one command that is sure to be used, \dump. Therefore the orginal \dump is saved in \org@dump and a new definition is supplied.

18 \let\orig@dump=\dump
19 \def\dump{%

To make sure that L^{A}TEX 2.09 executes the \@begindocumenthook we would want to alter \begin{document}, but as this done too often already, we add the new code at the front of \@preamblecmds. But we can only do that after it has been defined, so we add this peice of code to \dump.

20  \ifx\@ztryfc\@undefined
21  \else
22  \toks0=\expandafter{\@preamblecmds}
23  \edef\@preamblecmds{\noexpand\@begindocumenthook\the\toks0}
24  \def\@begindocumenthook{}
25  \fi

This new definition starts by adding an instruction to write a message on the terminal and in the transcript file to inform the user of the preloaded hyphenation patterns.

26  \everyjob\expandafter{\the\everyjob%
27  \immediate\write16{\the\toks8 loaded.}}%

Then everything is restored to the old situation and the format is dumped.

28  \let\dump\orig@dump\let\orig@dump\@undefined\dump}
29 \expandafter\endinput
30 \fi

The rest of this file is not processed by iniTEX but during the normal document run. A number of L^{A}TEX macro’s that are needed later on.

31 \long\def\@firstofone#1{#1}
32 \long\def\@firstoftwo#1#2{#1}
33 \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
34 \def\@star@or@long#1{%
35 \@ifstar
36 {\let\l@ngrel@x\relax#1}%
37 {\let\l@ngrel@x\long#1}}
38 \let\l@ngrel@x\relax
39 \def\@car#1#2\@nil{#1}
40 \def\@cdr#1#2\@nil{#2}
41 \let\@typeset@protect\relax
42 \long\def\@gobble#1{}
43 \edef\@backslashchar{\expandafter\@gobble\string\\}
44 \def\strip@prefix#1>{}
45 \def\g@addto@macro#1#2{{%
46  \toks@\expandafter{#1#2}%
47  \xdef#1{\the\toks@}}}
48 \def\@namedef#1{\expandafter\def\csname #1\endcsname}

L^{A}TEX 2ε has the command \@onlypreamble which adds commands to a list of commands that are no longer needed after \begin{document}.

49 \ifx\@preamblecmds\@undefined
50 \def\@preamblecmds{}
51 \fi
52 \def\@onlypreamble#1{%
53 \expandafter\gdef\expandafter\@preamblecmds\expandafter{%

54  \@preamblecmds\do#1}}
55 \@onlypreamble\@onlypreamble

Mimmick L^{A}TEX’s \AtBeginDocument; for this to work the user needs to add

\begindocument to his file.
56 \def\begindocument{%
57 \@begindocumenthook
58 \global\let\@begindocumenthook\@undefined
59 \def\do##1{\global\let ##1\@undefined}%
60 \@preamblecmds
61 \global\let\do\noexpand

62 }

63 \ifx\@begindocumenthook\@undefined
64 \def\@begindocumenthook{}
65 \fi
66 \@onlypreamble\@begindocumenthook
67 \def\AtBeginDocument{\g@addto@macro\@begindocumenthook}

We also have to mimick L^{A}TEX’s \AtEndOfPackage. Our replacement macro is much simpler; it stores its argument in \@endofldf.

68 \def\AtEndOfPackage#1{\g@addto@macro\@endofldf{#1}}
69 \@onlypreamble\AtEndOfPackage
70 \def\@endofldf{}
71 \@onlypreamble\@endofldf

L^{A}TEX needs to be able to switch off writing to its auxiliary files; plain doesn’t have them by default.

72 \let\if@filesw\iffalse

Mimick L^{A}TEX’s commands to define control sequences.

73 \def\newcommand{\@star@or@long\new@command}
74 \def\new@command#1{%
75 \@testopt{\@newcommand#1}0}
76 \def\@newcommand#1[#2]{%
77 \@ifnextchar [{\@xargdef#1[#2]}%
78  {\@argdef#1[#2]}}
79 \long\def\@argdef#1[#2]#3{%
80 \@yargdef#1\@ne{#2}{#3}}
81 \long\def\@xargdef#1[#2][#3]#4{%
82 \expandafter\def\expandafter#1\expandafter{%
83  \expandafter\@protected@testopt\expandafter #1%
84  \csname\string#1\expandafter\endcsname{#3}}%
85 \expandafter\@yargdef \csname\string#1\endcsname
86 \tw@{#2}{#4}}
87 \long\def\@yargdef#1#2#3{%
88 \@tempcnta#3\relax
89 \advance \@tempcnta \@ne
90 \let\@hash@\relax
91 \edef\reserved@a{\ifx#2\tw@ [\@hash@1]\fi}%
92 \@tempcntb #2%
93 \@whilenum\@tempcntb <\@tempcnta
94 \do{%
95  \edef\reserved@a{\reserved@a\@hash@\the\@tempcntb}%
96  \advance\@tempcntb \@ne}%
97 \let\@hash@##%

 98 \l@ngrel@x\expandafter\def\expandafter#1\reserved@a}
 99 \let\providecommand\newcommand

100

101 \def\DeclareRobustCommand{\@star@or@long\declare@robustcommand}
102 \def\declare@robustcommand#1{%
103 \edef\reserved@a{\string#1}%
104 \def\reserved@b{#1}%
105 \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}%
106 \edef#1{%
107  \ifx\reserved@a\reserved@b
108  \noexpand\x@protect
109  \noexpand#1%
110  \fi
111  \noexpand\protect
112  \expandafter\noexpand\csname
113  \expandafter\@gobble\string#1 \endcsname

114 }%

115 \expandafter\new@command\csname
116  \expandafter\@gobble\string#1 \endcsname

117 }

118 \def\x@protect#1{%
119 \ifx\protect\@typeset@protect\else
120  \@x@protect#1%
121 \fi

122 }

123 \def\@x@protect#1\fi#2#3{%
124 \fi\protect#1%

125 }

L^{A}TEX has a macro to check whether a certain package was loaded with specific options. The command has two extra arguments which are code to be executed in either the true or false case. This is used to detect whether the document needs one of the accents to be activated (activegrave and activeacute). For plain TEX we assume that the user wants them to be active by default. Therefore the only thing we do is execute the third argument (the code for the true case).

126 \def\@ifpackagewith#1#2#3#4{%
127 #3}

For the following code we need to make sure that the commands \newcommand and \providecommand exist with some sensible definition. They are not fully equivalent to their L^{A}TEX 2ε versions; just enough to make things work in plain TEXenvironments.

128 \ifx\@tempcnta\@undefined
129 \csname newcount\endcsname\@tempcnta\relax
130 \fi
131 \ifx\@tempcntb\@undefined
132 \csname newcount\endcsname\@tempcntb\relax
133 \fi

To prevent wasting two counters in L^{A}TEX 2.09 (because counters with the same name are allocated later by it) we reset the counter that holds the next free counter

 (\count10).
134 \ifx\bye\@undefined

135 \advance\count10 by -2\relax
136 \fi
137 \ifx\@ifnextchar\@undefined
138 \def\@ifnextchar#1#2#3{%
139  \let\reserved@d=#1%
140  \def\reserved@a{#2}\def\reserved@b{#3}%
141  \futurelet\@let@token\@ifnch}
142 \def\@ifnch{%
143  \ifx\@let@token\@sptoken
144  \let\reserved@c\@xifnch
145  \else
146  \ifx\@let@token\reserved@d
147  \let\reserved@c\reserved@a
148  \else
149  \let\reserved@c\reserved@b
150  \fi
151  \fi
152  \reserved@c}
153 \def\:{\let\@sptoken= } \:  % this makes \@sptoken a space token
154 \def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
155 \fi
156 \def\@testopt#1#2{%
157 \@ifnextchar[{#1}{#1[#2]}}
158 \def\@protected@testopt#1{%%
159 \ifx\protect\@typeset@protect
160  \expandafter\@testopt
161 \else
162  \@x@protect#1%
163 \fi}
164 \long\def\@whilenum#1\do #2{\ifnum #1\relax #2\relax\@iwhilenum{#1\relax
165  #2\relax}\fi}
166 \long\def\@iwhilenum#1{\ifnum #1\expandafter\@iwhilenum
167  \else\expandafter\@gobble\fi{#1}}

Code from ltoutenc.dtx, adapted for use in the plain TEX environment.

168 \def\DeclareTextCommand{%
169 \@dec@text@cmd\providecommand

170 }

171 \def\ProvideTextCommand{%
172 \@dec@text@cmd\providecommand

173 }

174 \def\DeclareTextSymbol#1#2#3{%
175 \@dec@text@cmd\chardef#1{#2}#3\relax

176 }

177 \def\@dec@text@cmd#1#2#3{%
178 \expandafter\def\expandafter#2%
179  \expandafter{%
180  \csname#3-cmd\expandafter\endcsname
181  \expandafter#2%
182  \csname#3\string#2\endcsname

183 }%

184 %   \let\@ifdefinable\@rc@ifdefinable
185 \expandafter#1\csname#3\string#2\endcsname

186 }

187 \def\@current@cmd#1{%

188 \ifx\protect\@typeset@protect\else
189  \noexpand#1\expandafter\@gobble
190 \fi

191 }

192 \def\@changed@cmd#1#2{%
193 \ifx\protect\@typeset@protect
194  \expandafter\ifx\csname\cf@encoding\string#1\endcsname\relax
195  \expandafter\ifx\csname ?\string#1\endcsname\relax
196  \expandafter\def\csname ?\string#1\endcsname{%
197  \@changed@x@err{#1}%

198 }%

199  \fi
200  \global\expandafter\let
201  \csname\cf@encoding \string#1\expandafter\endcsname
202  \csname ?\string#1\endcsname
203  \fi
204  \csname\cf@encoding\string#1%
205  \expandafter\endcsname
206 \else
207  \noexpand#1%
208 \fi

209 }

210 \def\@changed@x@err#1{%
211  \errhelp{Your command will be ignored, type <return> to proceed}%
212  \errmessage{Command \protect#1 undefined in encoding \cf@encoding}}
213 \def\DeclareTextCommandDefault#1{%
214 \DeclareTextCommand#1?%

215 }

216 \def\ProvideTextCommandDefault#1{%
217 \ProvideTextCommand#1?%

218 }

219 \expandafter\let\csname OT1-cmd\endcsname\@current@cmd
220 \expandafter\let\csname?-cmd\endcsname\@changed@cmd
221 \def\DeclareTextAccent#1#2#3{%
222 \DeclareTextCommand#1{#2}[1]{\accent#3 ##1}

223 }

224 \def\DeclareTextCompositeCommand#1#2#3#4{%
225 \expandafter\let\expandafter\reserved@a\csname#2\string#1\endcsname
226 \edef\reserved@b{\string##1}%
227 \edef\reserved@c{%
228  \expandafter\@strip@args\meaning\reserved@a:-\@strip@args}%
229 \ifx\reserved@b\reserved@c
230  \expandafter\expandafter\expandafter\ifx
231  \expandafter\@car\reserved@a\relax\relax\@nil
232  \@text@composite
233  \else
234  \edef\reserved@b##1{%
235  \def\expandafter\noexpand
236  \csname#2\string#1\endcsname####1{%
237  \noexpand\@text@composite
238  \expandafter\noexpand\csname#2\string#1\endcsname
239  ####1\noexpand\@empty\noexpand\@text@composite
240  {##1}%

241 }% 242 }%

243  \expandafter\reserved@b\expandafter{\reserved@a{##1}}%
244  \fi
245  \expandafter\def\csname\expandafter\string\csname
246  #2\endcsname\string#1-\string#3\endcsname{#4}
247 \else
248  \errhelp{Your command will be ignored, type <return> to proceed}%
249  \errmessage{\string\DeclareTextCompositeCommand\space used on
250  inappropriate command \protect#1}
251 \fi

252 }

253 \def\@text@composite#1#2#3\@text@composite{%
254 \expandafter\@text@composite@x
255  \csname\string#1-\string#2\endcsname

256 }

257 \def\@text@composite@x#1#2{%
258 \ifx#1\relax
259  #2%
260 \else
261  #1%
262 \fi

263 } 264 %

265 \def\@strip@args#1:#2-#3\@strip@args{#2}
266 \def\DeclareTextComposite#1#2#3#4{%
267 \def\reserved@a{\DeclareTextCompositeCommand#1{#2}{#3}}%
268 \bgroup
269  \lccode`\@=#4%
270  \lowercase{%
271 \egroup
272  \reserved@a @%

273 }% 274 } 275 %

276 \def\UseTextSymbol#1#2{%
277 %   \let\@curr@enc\cf@encoding
278 %   \@use@text@encoding{#1}%
279 #2%
280 %   \@use@text@encoding\@curr@enc

281 }

282 \def\UseTextAccent#1#2#3{%
283 %   \let\@curr@enc\cf@encoding
284 %   \@use@text@encoding{#1}%
285 %   #2{\@use@text@encoding\@curr@enc\selectfont#3}%
286 %   \@use@text@encoding\@curr@enc

287 }

288 \def\@use@text@encoding#1{%
289 %   \edef\f@encoding{#1}%
290 %   \xdef\font@name{%
291 %      \csname\curr@fontshape/\f@size\endcsname
292 %   }%
293 %   \pickup@font
294 %   \font@name
295 %   \@@enc@update

297 \def\DeclareTextSymbolDefault#1#2{%
298 \DeclareTextCommandDefault#1{\UseTextSymbol{#2}#1}%

299 }

300 \def\DeclareTextAccentDefault#1#2{%
301 \DeclareTextCommandDefault#1{\UseTextAccent{#2}#1}%

302 }

303 \def\cf@encoding{OT1}

Currently we only use the L^{A}TEX 2ε method for accents for those that are known to be made active in some language definition file.

304 \DeclareTextAccent{\"}{OT1}{127}
305 \DeclareTextAccent{\'}{OT1}{19}
306 \DeclareTextAccent{\^}{OT1}{94}
307 \DeclareTextAccent{\`}{OT1}{18}
308 \DeclareTextAccent{\~}{OT1}{126}

The following two control sequences are used in babel.def but are not defined for plain TEX.

309 \DeclareTextSymbol{\textquotedblright}{OT1}{`\"}
310 \DeclareTextSymbol{\textquoteright}{OT1}{`\'}
311 \DeclareTextSymbol{\i}{OT1}{16}
312 \DeclareTextSymbol{\ss}{OT1}{25}

For a couple of languages we need the L^{A}TEX-control sequence \scriptsize to be available. Because plain TEX doesn’t have such a sofisticated font mechanism as L^{A}TEX has, we just \let it to \sevenrm.

313 \ifx\scriptsize\@undefined
314 \let\scriptsize\sevenrm
315 \fi

316 ⟨/code⟩