summaryrefslogtreecommitdiff
path: root/macros/optex/base/math-unicode.opm
blob: 22db1d095e1e4233a33119b022e15d30dfa46763 (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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \loadmath {Unicode Math fonts <2022-07-22>} % preloaded in format

   \_doc -----------------------------
   \`\loadmath` `{<Unicode-math font>}` loads the given font. It does:
   \begitems
   * define \`\_unimathfont` as `<Unicode-math font>`,
   * redefine `\normalmath` and `\boldmath` macros to their Unicode counterparts,
   * load the `\_unimathfont` by `\normalmath`,
   * print information about the loaded font on the terminal,
   * redefine all encoding dependent setting by `\input unimath-codes.opm`,
   * protect new loading by setting \`\_ifmathloading` to false.
   \enditems
   \`\noloadmath` disallows Unicode-math loading by \`\_mathloadingfalse`.\nl
   \`\doloadmath` allows Unicode-math loading by \`\_mathloadingtrue`.
   \_cod -----------------------------

\_newifi \_ifmathloading   \_mathloadingtrue

\_def\_noloadmath{\_mathloadingfalse}
\_def\_doloadmath{\_mathloadingtrue}

\_def\_loadmath#1{%
   \_ifmathloading
   \_initunifonts
   \_isfont{#1}\_iffalse
      \_opwarning{Math font "#1" not found, skipped...}%
   \_else
      \_def\_unimathfont{#1}%
      \_let\_normalmath = \_normalunimath  \_let\_boldmath = \_boldunimath
      \_normalmath
      \_wterm {MATH-FONT: "#1" -- unicode math prepared.}%
      \_ifx\_ncharrmA\_undefined \_opinput {unimath-codes.opm}\_fi
      \_mathloadingfalse
   \_fi\_fi}

\_public \loadmath \noloadmath \doloadmath ;

   \_doc -----------------------------
   \`\loadboldmath` `{<bold-font>} \to {<normal-font>}`
   defines \`\_unimathboldfont` as `<bold-font>` only if `\_unimathfont` is
   defined as `<normal-font>`. It is used when \^`\boldmath` macro is run.
   When no `\_unimathboldfont` is defined then the `\boldmath` macro
   use \"fake bold" generated by `embolden` \LuaTeX/ font feature.
   \_cod -----------------------------

\_def\_loadboldmath#1#2\to #3{%
   \_def\_tmp{#3}\_ifx\_unimathfont\_tmp % do work only if #3 is loaded as normal Math
   \_isfont{#1}\_iffalse
      \_opwarning{Bold-Math font "#1" not found, skipped...}
   \_else
      \_def\_unimathboldfont{#1}%
      \_wterm {MATH-FONT: "#1" -- unicode math bold prepared.}%
   \_fi\_fi}

\_public \loadboldmath ;

   \_doc -----------------------------
   The Unicode version of the \^`\normalmath` and \^`\boldmath` macros
   are defined here as \`\_normalunimath` and \`\_boldunimath` macros.
   They are using \`\_setunimathdimens` in a similar sense as
   \^`\_setmathdimens`.
   \nl
   You can combine more fonts if you register them to another
   math families (5, 6, 7, etc.) in the \^`\normalmath` macro.
   \nl
   The default value of \^`\_normalunimath` shows a combination of base Unicode-math
   font with 8bit Math font at family 4. See definition of `\script` macro where
   `\fam4` is used.
   \_cod -----------------------------

\_def\_normalunimath{%
    \_loadumathfamily 1 {\_unimathfont}{} % Base font
    \_loadmathfamily  4 rsfs              % script
    \_setunimathdimens
}%
\_def\_boldunimath{%
    \_ifx\_unimathboldfont \_undefined
       \_loadumathfamily 1 {\_unimathfont}{embolden=1.7;} % Base faked bold
    \_else
       \_loadumathfamily 1 {\_unimathboldfont}{} % Base real bold font
    \_fi
    \_loadmathfamily  4 rsfs              % script
    \_setunimathdimens
}%
\_def\_setunimathdimens{% PlainTeX sets these dimens for 10pt size only:
  \_delimitershortfall=0.5\_fontdimen6\_textfont1
  \_nulldelimiterspace=0.12\_fontdimen6\_textfont1
  \_setmathparam\_Umathspaceafterscript \_scriptspacefactor
  \_setbox0=\_hbox{\_everymath{}$\_fam1\_displaystyle{0\_atop0}$}%
  \_Umathfractiondelsize\_displaystyle = \_dimexpr(\_ht0-\_Umathaxis\_displaystyle)*2\_relax
  \_setbox0=\_box\_voidbox
}

   \_doc -----------------------------
   If you try the example above about
   \~`\loadboldmath``{[xitsmath-bold]} \to {[xitsmath-regular]}`
   then you can find a bug in XITSMath-Bold font: the symbols for norm
   $\|x\|$ are missing. So, we have to define `\_boldmath` macro manually.
   The missing symbol is loaded from family 5 as no-bold variant in our example:
   \begtt
   \loadmath{[xitsmath-regular]}
   \def\_boldmath{%
      \_loadumathfamily 1 {[xitsmath-bold]}{} % Base font
      \_loadmathfamily 4  rsfs % script
      \_loadumathfamily 5 {[xitsmath-regular]}{}
      \_def\|{\_Udelimiter 0 5 "02016 }%      % norm delimiter from family 5
      \_setmathdimens
   }
   \endtt

   \`\_loadumathfamily` `<number> {<font>}{<font features>}`
   loads the given Unicode-math fonts in three sizes
   using single <font> with different `mathsize=1,2,3` font features.
   The math font family is set with given `<number>`.
   The `<font features>` are added to the default
   \`\_mfontfeatures` and to the size-dependent features `ssty=1`
   if script size is asked or `ssty=2` if scriptscriptsize is asked.\nl
   \`\_mparams``<number>` inserts additional font feature `nomathparam`
   if the <number> of the family is greater than 3. Lua\TeX/ sets math
   parameters (thickness of fraction rules etc., see section 7.4 in Lua\TeX/
   documentation) repeatedly from loaded math
   fonts if `nomathparam` is not given. We want to load these parameters only
   from fonts at families 0--3 (and actually we are using only family 1 as main math font).\nl
   The \^`\_corrmsize` `<factor><space>` can be used just before
   `\_loadumathfamily`, see section~\ref[math-preload] for more information.\nl
   The \`\_textmff`, \`\_scriptmff` and \`\_sscriptmff` are font
   features for text, script and sscript sizes respectively. They are
   locally re-defined in \^`\mathbox` macro.
   \_cod -----------------------------

\_def\_umathname#1#2{"#1:\_mfontfeatures#2"}
\_def\_mfontfeatures{mode=base;script=math;}

\_def\_loadumathfamily #1 #2#3 {%
  \_font\_mF=\_umathname{#2}{\_textmff   \_mparams{#1}#3} at\_sizemtext \_textfont        #1=\_mF
  \_font\_mF=\_umathname{#2}{\_scriptmff \_mparams{#1}#3} at\_sizemtext \_scriptfont      #1=\_mF
  \_font\_mF=\_umathname{#2}{\_sscriptmff\_mparams{#1}#3} at\_sizemtext \_scriptscriptfont#1=\_mF
  \_ptmunit=\_ptunit
}
\_def\_textmff   {ssty=0;mathsize=1;}
\_def\_scriptmff {ssty=1;mathsize=2;}
\_def\_sscriptmff{ssty=2;mathsize=3;}
\_def\_mparams#1{\_ifnum#1>3 nomathparam;\_fi}

   \_doc -----------------------------
   Unicode math font includes all typical math alphabets together, user needs not to
   load more \TeX/ math families. These math alphabets are encoded by
   different parts of Unicode table. We need auxiliary macros for setting
   mathcodes by selected math alphabet.
   \nl
   \`\_umathrange` `{<from->-<to>}<class><family>\<first>` sets `\Umathcode`s
   of the characters in the interval `<from>-<to>` to `\<first>`,
   `\<first>+1`, `\<first>+2`
   etc., but \`\_umathcharholes` are skipped
   (`\_umathcharholes` are parts of the Unicode table not designed for math
   alphabets, they cause that the math alphabets are
   not continuously spread out in the table; I mean that the
   designers were under the influence of drugs when they created
   this part of the Unicode table).
   The `<from>-<to>` clause includes characters like~`A-Z`.
   \nl
   \`\_umahrangegreek` `\<first>` is the same as
   `\_umathrange {<alpha>-<omega>}\<first>`.
   \nl
   \`\_umahrangeGREEK` `\<first>` is the same as
   `\_umathrange {<Alpha>-<Omega>}\<first>`.
   \nl
   \`\_greekdef` `<control sequences> \_relax` defines each control sequence
   as a normal character with codes `\_umathnumB`, `\_umathnumB+1`,
   `\_umathnumB+2` etc. It is used for redefinig the contol sequences for
   math Greek `\alpha`, `\beta`, `\gamma` etc.
   \_cod -----------------------------

\_newcount\_umathnumA  \_newcount\_umathnumB

\_def\_umathcorr#1#2{\_ea#1\_ea{\_the#2}}
\_def\_umathprepare#1{\_def\_umathscanholes##1[#1]##2##3\_relax{##2}}
\_def\_umathvalue#1{\_ea\_umathscanholes\_umathcharholes[#1]{#1}\_relax}

\_def\_umathcharholes{% holes in math alphabets:
   [119893]{"210E}[119965]{"212C}[119968]{"2130}[119969]{"2131}%
   [119971]{"210B}[119972]{"2110}[119975]{"2112}[119976]{"2133}[119981]{"211B}%
   [119994]{"212F}[119996]{"210A}[120004]{"2134}%
   [120070]{"212D}[120075]{"210C}[120076]{"2111}[120085]{"211C}[120093]{"2128}%
   [120122]{"2102}[120127]{"210D}[120133]{"2115}[120135]{"2119}
   [120136]{"211A}[120137]{"211D}[120145]{"2124}%
}
\_def\_umathrange#1#2#3#4{\_umathnumB=#4\_def\_tmp{#2 #3 }\_umathrangeA#1}
\_def\_umathrangeA#1-#2{\_umathnumA=`#1\_relax
   \_loop
      \_umathcorr\_umathprepare\_umathnumB
      \_Umathcode \_umathnumA = \_tmp \_umathcorr\_umathvalue{\_umathnumB}
      \_ifnum\_umathnumA<`#2\_relax
         \_advance\_umathnumA by1 \_advance\_umathnumB by1
   \_repeat
}
\_def\_umathrangeGREEK{\_umathrange{^^^^0391-^^^^03a9}}
\_def\_umathrangegreek{\_umathrange{^^^^03b1-^^^^03d6}}
\_def\_greekdef#1{\_ifx#1\_relax \_else
   \_begingroup \_lccode`X=\_umathnumB \_lowercase{\_endgroup \_def#1{X}}%
   \_advance\_umathnumB by 1
   \_ea\_greekdef \_fi
}

   \_doc -----------------------------
   \`\addUmathfont` `<fam> {[<normal-font>]}{<ffeatures>} {[<bold-font>]}{<ffeatures>} {<factor>}`
   allocates new <fam> using \^`\newfam` and adds loading this font to the
   \~`\normalmath` and \~`\boldmath` macros. Note that allocationos using
   \^`\newfam` starts from 43 because numbers 1--42 are reserved for direct
   usage without \^`\newfam`.
   \_cod -----------------------------

\_def\_addUmathfont #1#2#3#4#5#6{% #1: fam (will be set), #2#3: normal font, #4#5: bold font
   \_ifx\_ncharrmA\_undefined \_errmessage{basic Unicode math font must be loaded first}%
   \_else \_isfont{#2}\_iffalse \_opwarning{font #2 is unavailable}%
   \_else
      \_newfam#1\_relax
      \_global\_addto\_normalmath{\_corrmsize#6 \_loadumathfamily #1 {#2}{#3} }%
      \_ifx\_relax#4\_relax
         \_global\_addto\_boldmath{\_corrmsize#6 \_loadumathfamily #1 {#2}{embolden=1.7;} }%
      \_else
         \_global\_addto\_boldmath{\_corrmsize#6 \_loadumathfamily #1 {#4}{#5} }%
      \_fi
      \_normalmath
      \_wterm{add-MATH-FONT: #1=\the#1, "#2", \ifx"#4"\else bold: "#4"\fi}%
   \_fi \_fi
}

   \_doc -----------------------------
   \`\resetmathchars` `<fam> <list of sequences> ;`
   saves <fam> to \`\_mafam` and applies \`\_resetmathcharsX`
   to each sequence from <list of sequences>.
   The `\directlua` chunk prints the 8-digits hexadecimal code of the
   sequence followed by the sequence itself. The digts are scanned by \`\_resetmathcharsY`
   and new `\Umathchardef` and `\Umathcode` is declared. Note that the used
   primitives have the syntax:
   \begtt \catcode`<=13
   \Umathchardef <sequence> <math class> <math family> <slot number>
   \Umathcode <code> <math class> <math family> <slot number>
   \endtt
   \_cod -----------------------------

\_def\_resetmathchars #1{\_chardef\_mafam=#1\_relax \_xargs \_resetmathcharX}
\_def\_resetmathcharX#1{\_ea\_resetmathcharY
   \_directlua{tex.print(string.format("\_pcent08X", \_the#1))}#1}
\_def\_resetmathcharY#1#2#3#4#5#6#7#8#9{% #9 is given \math-sequence
   \_Umathchardef #9\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8
   \_Umathcode "#4#5#6#7#8=\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8
}
\_public \addUmathfont \resetmathchars ;

\_endcode


The \^`\loadmath` `{<Unicode-math font>}` macro loads math fonts and
redefines all default math-codes using `\input unimath-codes.opm`.
If Unicode-math font is loaded then \^`\_mathloadingfalse`
is set, so the new Unicode-math font isn't loaded until \^`\doloadmath` is used.

\^`\loadboldmath` `{<bold-font>} \to {<normal-font>}` loads bold variant only
if `<normal-font>` was sucessully loaded by the previous `\loadmath`. For example:

\begtt
\loadmath     {[xitsmath-regular]}
\loadboldmath {[xitsmath-bold]} \to {[xitsmath-regular]}
\endtt
There are very few Unicode-math fonts with full \~`\boldmath` support.
I know only XITSMath-Bold and KpMath-Bold. If \^`\loadboldmath` is not used
then \"faked bold" created from \~`\normalmath` is used by default.

The {\em main math font} is loaded by \^`\loadmath` (typically indirectly using
\^`\fontfam`) and you can load more {\em additional math fonts} by
\^`\addUmathfont`:
\begtt \catcode`<=13
\addUmathfont \famname {[<normal-font>]}{<ffeatures>} {[<bold-font>]}{<ffeatures>} {<factor>}
\endtt
The `\famname` is a control sequence declared by \^`\addUmathfont` for later
use. It gets math family number. The `<factor>` is decimal number for size
corrections in view of the main math font. If it is empty then <factor>=1.
If <bold-font> is empty, the \"faked bold" derived from <normal-font> is used.
Example:
\begtt
\fontfam[lm]  % does \lodmath{[latinmodern-math]}
\addUmathfont \xits {[XITSMath-Regular]}{} {[XITSMath-Bold]}{} {}
\endtt
%
declares `latinmodern-math` as main math font (its bold variant is \"faked bold")
and the additional math font `\xits` is `XITSMath-Regular` for normal
printing and `XITSMath-Bold` for bold printing.

All characters used in math formula is printed from main math font by
default. But you can redeclare a list of characters for printing from
additional font by \^`\resetmathchars` `\famname <list of sequences> ;`. For
example:

\begtt
\resetmathchars \xits \stareq \triangleq \veeeq \wedgeq ;
\endtt
%
sets the characters `\stareq`, `\triangleq`, `\veeeq`, `\wedgeq` from
the `\xits` additional font. You can see all possible sequences by
`\input print-unimath.opm`.
If you want to use whole math alphabet from additional math font, use
`\addto\selector{\fam\famname}`, for example `\addto\cal{\fam\xits}`
declares all `\cal` characters from the `\xits` font loaded by
\^`\addUmathfont`.


\secc Unicode-math macros preloaded in the format

\printdoc math-unicode.opm


\secc[unimath-codes] Macros and codes set when `\loadmath` is processed firstly

The file `unimath-codes.opm` is loaded when the \^`\loadmath` is used. The
macros here redefines globally all encoding dependent settings declared in
the section~\ref[math-macros].

\printdoc     unimath-codes.opm
\printdoctail unimath-codes.opm

\secc Printing all Unicode math slots in used math font

\printdoctail print-unimath.opm
\printdoc     print-unimath.opm

\_endinput

2022-07-22 \Umathspaceafterscript setting added.
2022-06-10 \addUmathfont and \resetmathchars added.
2021-08-16 \_loadumathfamily simplified, used mathsize= font feature.
2021-08-16 nomathparam font feature used for families > 3 (bug fixed).
2021-08-02 ssty fontfeatures rewritten; fam2, fam3 unused, \scriptspace not set
2021-04-04 \_setunimathdimens: \setbox0=\box\voidbox added
2021-03-09 \_setunimathdimes: \_begin/end/group instead {}, bug fixed
2021-02-15 \_textmff, \_scriptmff and \_sscriptmff introduced
2021-02-15 \_expandafter -> \_ea
2020-06-07 \Umathfractiondelsize (for \choose brackets) corrected, see https://tug.org/pipermail/luatex/2020-June/007365.html
2020-04-15 \_setmathdimens -> \_setuniathdimens
2020-02-25 implemented