diff options
Diffstat (limited to 'Master/texmf-dist/tex/optex/base/prefixed.opm')
-rw-r--r-- | Master/texmf-dist/tex/optex/base/prefixed.opm | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/optex/base/prefixed.opm b/Master/texmf-dist/tex/optex/base/prefixed.opm new file mode 100644 index 00000000000..61df791ddb0 --- /dev/null +++ b/Master/texmf-dist/tex/optex/base/prefixed.opm @@ -0,0 +1,298 @@ +%% 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 \_ea \_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. + +\endinput + +2021-02-15 \_expandafter -> \_ea in \_codedecl +2020-02-14 released |