summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/prefixed.opm
blob: ff6dffa20a34291a4dbbb6cb8e2c30e5cc211b71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \public {Prefixing and code syntax <2020-02-14>} % preloaded in format

   \_doc ---------
   All \TeX/ primitives have alternative control sequence `\_hbox` `\_string`, ...
   \_cod ---------

\let\_directlua = \directlua
\_directlua {
    % enable all TeX primitives with _ prefix
    tex.enableprimitives('_', tex.extraprimitives('tex'))
    % enable all primitives without prefixing
    tex.enableprimitives('', tex.extraprimitives())
    % enable all primitives with _ prefix
    tex.enableprimitives('_', tex.extraprimitives())
}

   \_doc ------------------
   \`\ea` is useful shortcut for `\expandafter`. We recommend to use always the
   private form of \`\_ea`
   because there is high probability that `\ea` will be redefined by the user.
   \nl
   \`\public` `<sequence> <sequence> ... ;` does
   `\let \<sequence> = \_<sequence>` for all sequences.
   \nl
   \`\private` `<sequence> <sequence> ...;` does
   `\let \_<sequence> = \<sequence>` for all sequences.
   \nl
   \`\xargs` `<what> <sequence> <sequence> ... ;`
   does `<what><sequence>` for each sequences.
   \_cod -----------------

\_let\_ea =\_expandafter  % usefull shortcut

\_long\_def \_xargs #1#2{\_ifx #2;\_else \_ea#1\_ea#2\_ea\_xargs \_ea #1\_fi}

\_def \_pkglabel{}
\_def \_public {\_xargs \_publicA}
\_def \_publicA #1{\_ea\_let \_ea#1\_csname  _\_csstring #1\_endcsname}

\_def \_private {\_xargs \_privateA}
\_def \_privateA #1{\_ea\_let \_csname  _\_csstring #1\_endcsname =#1}

\_public \public \private \xargs \ea ;

   \_doc -----------------------
   Each macro file should begin with \`\_codedecl` `\macro {<info>}`.
   If the `\macro` is defined already then the `\endpinput` protects to read
   such file more than once. Else the <info> is printed to the terminal
   and the file is read.\nl
   The {\`\_endcode`} is defined as `\endinput` in the `optex.ini` file.
   \`\wterm` `{<text>}` prints `<text>`
   to the terminal and to the `.log` file (as in plain \TeX/).
   \_cod -----------------------

\_def \_codedecl #1#2{%
   \_ifx #1\_undefined \_wterm{#2}%
   \_else \_expandafter \_endinput \_fi
}
\_def \_wterm {\_immediate \_write16 }

\_public \wterm ;

   \_doc ------------------------
   The `\optexversion` and `\fmtname` are defined in the `optex.ini` file.
   Maybe, somebody will need a private version of these macros.
   \_cod ------------------------

\_private \optexversion \fmtname ;

   \_doc -----------------------------
   The `\_mathsbon` and `\_mathsboff` are defined in `math-macros.opm` file.
   Now, we define the macros
   \`\_namespace` `{<pkg label>}`,  \`\_resetnamespace` `{<pkg label>}`, \`\_endnamespace`,
   \`\_nspublic` and \`\_nsprivate`
   for package writers, see section~\ref[pkg-namespace].{\hbadness=2200\par}
   \_cod -----------------------------

\_def \_pkglabel{}
\_def\_namespace #1{%
   \_ifcsname namesp:#1\_endcsname \_errmessage
      {The name space "#1" is used already, it cannot be used twice}%
      \_endinput
   \_else \_resetnamespace{#1}\_fi
}
\_def\_resetnamespace #1{%
   \_ea \_gdef \_csname namesp:#1\_endcsname {}%
   \_gdef \_pkglabel{_#1}%
   \_directlua{
      callback.add_to_callback("process_input_buffer",
        function (str)
           return string.gsub(str, "\_nbb[.]([a-zA-Z])", "\_nbb _#1_\_pcent 1")
        end, "_namespace")
   }%
}
\_def\_endnamespace {%
   \_directlua{ callback.remove_from_callback("process_input_buffer", "_namespace") }%
   \_gdef \_pkglabel{}%
}

\_def \_nspublic {\_xargs \_nspublicA}
\_def \_nspublicA #1{%
   \_unless\_ifx #1\_undefined
      \_opwarning{\_ea\_ignoreit\_pkglabel\_space redefines the meaning of \_string#1}\_fi
   \_ea\_let \_ea#1\_csname \_pkglabel _\_csstring #1\_endcsname}

\_def \_nsprivate {\_xargs \_nsprivateA}
\_def \_nsprivateA #1{\_ea\_let \_csname \_pkglabel _\_csstring #1\_endcsname =#1}


\_endcode %----------------------------------------------------


\sec[prefixed] Concept of namespaces of control sequences

\secc Prefixing internal control sequences

All control sequences used in \OpTeX/ are used and defined with `_` prefix.
The user can be sure that when he/she does `\def\foo` then internal macros of
\OpTeX/ nor \TeX/ primitives will be not damaged. For example
`\def\if{...}` will not damage macros because \OpTeX/'s macros
are using `\_if` instead of `\if`.

All \TeX/ primitives are initialized with two representative control
sequences: `\word` and `\_word`, for example `\hbox` and `\_hbox`.
The first alternative is reserved for users or such control sequences
can be re-defined by a user.

\OpTeX/ sets the character `_` as the letter, so it can be used in
control sequences. When a control sequence begins with this character
then it means that it is a primitive or it is used in \OpTeX/ macros as
internal. User can redefine such prefixed control sequence only
if he/she explicitly know what happens.

We never change catcode of `_`, so internal macros can be
redefined by user without problems if it is desired. We need not
something like `\makealetter` from \LaTeX/.

\OpTeX/ defines all new macros as prefixed. For public usage of such macros,
we need to set non-prefixed version. This is done by

\begtt \catcode`\<=13
\public <list of control sequences> ;
\endtt

For example \^`\public`` \foo \bar ;` does `\let\foo=\_foo`, `\let\bar=\_bar`.

At the end of each code segment in \OpTeX/, the `\_public` macro is used. You
can see, what macros are defined for public usage in this code segment.

The macro \^`\private` does a reverse job to `\public` with the same syntax.
For example `\private \foo \bar ;` does `\let\_foo=\foo`, `\let\_bar=\bar`.
This should be used when an unprefixed variant of a control sequence is declared
already but we need the prefixed variant too.

In this documentation: if both variants of a control sequence are declared
(prefixed and unprefixed), then the accompanying text mentions only
the unprefixed variant. The code typically defines the prefixed variant
and then the \^`\public` (or `\_public`) macro is used.

\secc Namespace of control sequences for users

Users can define or declare any control sequence with a name without any `_`.
This does not make any problem. Only one exception is the reserved control
sequence `\par`. It is generated by tokenizer (at empty lines)
and used as internal in \TeX/.

User can define or declare control sequences with `_` character, for
example `\my_control_sequence`, but with the following exceptions:

\begitems
* Control sequences which begin with `_` are reserved for \TeX/ primitives,
  \OpTeX/ internal macros and packages internal macros.
* Control sequences (terminated by non-letter) in the form
  `\<word>_` or `\<word>_<one-letter>`, where
  <word> is a sequence of letters, are inaccessible, because they
  are interpreted as `\<word>` followed by `_` or as `\<word>` followed by
  `_<one-letter>`. This is important for writing math, for example:
\begtt  \adef-{_}
  \int-a^b    ... is interpreted as \int _a^b
  \max-M      ... is interpreted as \max _M
  \alpha-{ij} ... is interpreted as \alpha _{ij}
\endtt
  This feature is implemented using lua code at input processor level, see
  the section~\ref[math-macros] for more details. You can deactivate this feature by
  \^`\mathsboff`. After this, you can still write
  `$`$\int$`_a^b$` (Unicode) or `$\int _a^b$` % $∫_a^b$ (Unicode) or $\int _a^b$
  without problems but `\int``_a^b` yields to undefined control sequence
  `\int``_a`. You can activate this feature again by \^`\mathsbon`. The
  effect will take shape from next line read from input file.
* Control sequences in the form `\_<pkg>_<word>` is intended for package
  writers as internal macros for a package with `<pkg>` identifier,
  see section~\ref[pkg-namespace].
\enditems

The single-letter control sequences like `\%`, `\$`, `\^` etc. are not used
in internal macros. Users can redefine them, but (of course) some classical
features can be lost (printing percent character by `\%` for example).

\secc Macro files syntax

Each segment of \OpTeX/ macros is stored in one file with `.opm` extension
(means OPtex Macros). Your local macros should be in a normal `*.tex` file.

The code in macro files starts by \^`\_codedecl` and ends by \^`\_endcode`.
The \^`\_endcode` is equivalent for `\endinput`, so documentation can follow.
The \^`\_codedecl` has syntax:

\begtt
\_codedecl \sequence {Name <version>}
\endtt

If the mentioned `\sequence` is defined, then \^`\_codedecl` does the same as
`\endinput`: this protects from reading the file twice. We suppose, that
`\sequence` is defined in the macro file.

It is possible to use the \^`\_doc` ... \^`\_cod` pair between the macro lines.
The documentation text should be here. It is ignored when macros are read
but it can be printed using `doc.opm` macros like in this documentation.


\secc[pkg-namespace] Name spaces for package writers

Package writer should use internal names in the form `\_<pgk>_<sequence>`,
where `<pkg>` is a package label. For example:
`\_qr_utfstring` from `qrcode.opm` package.

The package writer needs not to write repeatedly `\_pkg_foo` `\_pkg_bar`
etc.\ again and again in the macro file.\fnote
{We have not adopted the idea from expl3 language:)}
When the \^`\_namespace` `{<pkg>}`
is declared at the beginning of the macro file then all occurrences of
`\.foo` will be replaced by `\_<pkg>_foo` at the input processor level.
The macro writer can write (and backward can read his/her code) simply with
`\.foo`, `\.bar` control sequences and `\_<pkg>_foo`, `\_<pkg>_bar`
control sequences are processed internally.
The scope of the \^`\_namespace` command ends at the \^`\_endnamespace` command
or when another \^`\_namespace` is used. This command checks
if the same package label is not declared by the \^`\_namespace` twice.

The \^`\_nspublic` macro does `\let\foo = \_<pkg>_foo` when
\^`\_namespace{<pkg>}` is declared. Moreover, it prints a warning if `\foo` is
defined already. The \^`\_nsprivate` macro does reverse
operation to it without warnings. Example: you can define `\def\.macro{...}` and then
set it to the user name space by `\_nspublic \macro;`.

Don't load other packages (which are using their own namespace) inside your
namespace. Do load them before your \^`\_namespace`~`{<pkg>}` is
initialized. Or close your namespace by \^`\_endnamespace` and open it again
(after other packages are loaded) by \^`\_resetnamespace`~`{<pkg>}`.

If the package writer needs to declare a control
sequence by \^`\newif`, then there is an exception of the rule described above. Use
\^`\_newifi\_if<pkg>_bar`, for example `\_newifi\_ifqr_incorner`.
Then the control sequences `\_qr_incornertrue` and
`\_qr_incornerfalse` can be used (or the sequences `\.incornertrue`
and `\.incornerfalse` when `\_namespace{qr}` is used).


\secc Summary about rules for external macro files published for \OpTeX/

If you are writing a macro file that is intended to be published for
\OpTeX/, then you are greatly welcome. You should follow these rules:

\begitems
* Don't use control sequences from the user namespace in the macro
  bodies if there is not explicit and documented reason to do this.
* Don't declare control sequences in the user namespace if there are not
  explicit and documented reasons to do this.
* Use control sequences from \OpTeX/ and primitive namespace
  in read-only mode, if there is not an explicit and documented reason to
  redefine them.
* Use `\_<pkg>_<name>` for your internal macros or `\.<name>` if the
  \^`\_namespace{<pkg>}` is declared. See section~\ref[pkg-namespace].
* Use \^`\load` (or better: `\_load`) for loading more external macros
  if you need them. Don't use `\_input` explicitly in such cases.
  The reason is: the external macro file is not loaded
  twice if another macro or the user needs it explicitly too.
* Use \^`\_codedecl` as your first command in the macro file and
  \^`\_endcode` to close the text of macros.
* Use \^`\_doc` ... \^`\_cod` pairs for documenting the code pieces and/or write
  more documentation after the \^`\_endcode` command.
\enditems

If the macro file accepts these recommendations then it should be
named by `<filename>.opm` where `<filename>` differs from file names
used directly in \OpTeX/ and from other published macros.
This extension `opm` has precedence before `.tex` when
the \^`\load` macro is used.

The `qrcode.opm` is the first example of how an external macro file for \OpTeX/
can look like.