common-math-jmn.lfg /size: 14 Kb    last modification: 2024-01-16 10:22
1if CONTEXTLMTXMODE == 0 then
2
3    fonts.encodings.math["extensible-jmn-private"] = { }
4    fonts.encodings.math["tex-ex-braces"]          = { }
5
6    return false
7
8end
9
10local nps = fonts.helpers.newprivateslot
11
12local fake20D6 = nps("arrow fake 0x20D6")
13local fake20D7 = nps("arrow fake 0x20D7")
14local fake20E1 = nps("arrow fake 0x20E1")
15
16local fake20EE = nps("arrow fake 0x20EE")
17local fake20EF = nps("arrow fake 0x20EF")
18local fake034D = nps("arrow fake 0x034D")
19
20local real034D = nps("arrow real 0x034D")
21
22if not fonts.encodings.math["extensible-jmn-private"] then
23
24    local ps = fonts.helpers.privateslot
25
26    fonts.encodings.math["extensible-jmn-private"] = {
27        [ps("rule middle piece")]        = 200, -- minusjmn
28        [ps("rule right piece")]         = 201, -- minusrightjmn
29        [ps("rule left piece")]          = 202, -- minusleftjmn
30        [ps("double rule middle piece")] = 203, -- equaljmn
31        [ps("double rule right piece")]  = 204, -- equalrightjmn
32        [ps("double rule left piece")]   = 205, -- equalleftjmn
33        [ps("arrow left piece")]         = 206, -- arrowleftjmn
34        [ps("arrow right piece")]        = 207, -- arrowrightjmn
35        [ps("double arrow left piece")]  = 208, -- arrowdblleftjmn
36        [ps("double arrow right piece")] = 209, -- arrowdblrightjmn
37    }
38
39end
40
41return {
42    name = "common-math-jmn",
43    version = "1.00",
44    comment = "Goodies that complement the JMN collection.",
45    author = "Hans, Mikael",
46    copyright = "ConTeXt development team",
47    mathematics = {
48        helpers = {
49            copyrecipes = function(recipes)
50                local list = table.keys(recipes)
51                for i=1,#list do
52                    local n = list[i]
53                    local t = table.copy(recipes[n])
54                    t[1].features = t[1].features .. "-nt"
55                    recipes[n .. "-nt"] = t
56                end
57            end,
58            addmissing = function(main)
59
60                local max            = math.max
61                local copytable      = table.copy
62                local slotcommand    = fonts.helpers.commands.slot
63
64                local builders       = fonts.handlers.vf.math.builders
65                local ps             = fonts.helpers.privateslot
66
67                local characters     = main.characters
68                local variables      = main.goodies.mathematics and main.goodies.mathematics.variables or { }
69                local joinrelfactor  = variables.joinrelfactor or 3
70                local notshiftfactor = variables.notshiftfactor or 0
71
72                local umbracepiece = ps("um brace piece")
73                local lmbracepiece = ps("lm brace piece")
74                local cmbracepiece = ps("cm brace piece")
75
76                local ulbracepiece = ps("ul brace piece")
77                local urbracepiece = ps("ur brace piece")
78                local llbracepiece = ps("ll brace piece")
79                local lrbracepiece = ps("lr brace piece")
80
81                builders.brace(main,0x23DE,ulbracepiece,cmbracepiece,lrbracepiece,llbracepiece,cmbracepiece,urbracepiece,"top")
82                builders.brace(main,0x23DF,llbracepiece,cmbracepiece,urbracepiece,ulbracepiece,cmbracepiece,lrbracepiece,"bottom")
83
84                builders.parent(main,0x23DC,ulbracepiece,umbracepiece,urbracepiece,"top")
85                builders.parent(main,0x23DD,llbracepiece,lmbracepiece,lrbracepiece,"bottom")
86
87                builders.dots(main,0x2026) -- ldots
88                builders.dots(main,0x22EE) -- vdots
89                builders.dots(main,0x22EF) -- cdots
90                builders.dots(main,0x22F1) -- ddots
91                builders.dots(main,0x22F0) -- udots
92
93                builders.jointwo(main,0x21A6,ps("maps to piece"),.15,0x02192) -- \mapstochar\rightarrow
94
95                local srl = ps("rule left piece")
96                local srm = ps("rule middle piece")
97                local srr = ps("rule right piece")
98
99                local drl = ps("double rule left piece")
100                local drm = ps("double rule middle piece")
101                local drr = ps("double rule right piece")
102
103                local sfl = ps("flat rule left piece")
104                local sfm = ps("flat rule middle piece")
105                local sfr = ps("flat rule right piece")
106
107                local mrl = ps("minus rule left piece")
108                local mrm = ps("minus rule middle piece")
109                local mrr = ps("minus rule right piece")
110
111                local dfl = ps("flat double rule left piece")
112                local dfm = ps("flat double rule middle piece")
113                local dfr = ps("flat double rule right piece")
114
115                local sal = ps("arrow left piece")
116                local sar = ps("arrow right piece")
117
118                local dal = ps("double arrow left piece")
119                local dar = ps("double arrow right piece")
120
121                local rad = ps("radical bar extender")
122                local frc = ps("fraction bar extender")
123
124                local antykwa = characters[srm]
125
126                if not antykwa then
127
128                    sal = 0x02190  sar = 0x02192
129                    dal = 0x021D0  dar = 0x021D2
130
131                    srl = 0x0002D  srr = 0x0002D
132                    drl = 0x0003D  drr = 0x0003D
133
134                    sfl = 0x0002D  srm = 0x0002D
135                    dfl = 0x0003D  drm = 0x0003D
136
137                end
138
139                if not characters[sfm] then
140
141                    local csal = characters[sal]  local sheight = csal.height  local sdepth = csal.depth
142                    local cdal = characters[dal]  local dheight = cdal.height  local ddepth = cdal.depth
143
144                    local csfl = copytable(characters[srl])  characters[sfl] = csfl  csfl.height = sheight  csfl.depth = sdepth csfl.italic = nil
145                    local csfm = copytable(characters[srm])  characters[sfm] = csfm  csfm.height = sheight  csfm.depth = sdepth csfm.italic = nil
146                    local csfr = copytable(characters[srr])  characters[sfr] = csfr  csfr.height = sheight  csfr.depth = sdepth csfr.italic = nil
147                    local cdfl = copytable(characters[drl])  characters[dfl] = cdfl  cdfl.height = dheight  cdfl.depth = ddepth cdfl.italic = nil
148                    local cdfm = copytable(characters[drm])  characters[dfm] = cdfm  cdfm.height = dheight  cdfm.depth = ddepth cdfm.italic = nil
149                    local cdfr = copytable(characters[drr])  characters[dfr] = cdfr  cdfr.height = dheight  cdfr.depth = ddepth cdfr.italic = nil
150
151                end
152
153                builders.jointwo(main,0x27F5,sal,joinrelfactor,srr)
154                builders.jointwo(main,0x27F6,srl,joinrelfactor,sar)
155                builders.jointwo(main,0x27F7,sal,joinrelfactor,sar)
156                builders.jointwo(main,0x27F8,dal,joinrelfactor,drr)
157                builders.jointwo(main,0x27F9,drl,joinrelfactor,dar)
158                builders.jointwo(main,0x27FA,dal,joinrelfactor,dar)
159
160                if antykwa then
161                    builders.horibar(main,0x2212,mrm,mrl,mrr,0x2212,true,srm,srl,srr) -- minus
162                    builders.horibar(main,0x203E,srm,srl,srr,0x2212) -- overbar underbar fraction (we take 90/91/92 too!)
163                    builders.horibar(main,frc,srm,srl,srr,0x2212)    -- fraction
164                    builders.rootbar(main,rad,srm,srr,0x2212)        -- radical
165                else
166                    builders.horibar(main,0x2212,false,false,false,0x2212,true) -- minus
167                    builders.horibar(main,0x203E,false,false,false,0x02212)
168                end
169
170                local ffactor = antykwa and 1 or 1   -- check MS
171                local mfactor = antykwa and 1 or .8
172                local lfactor = antykwa and 1 or .8
173
174                builders.extension(main,0x2190,sal,sfm,sfr,ffactor,mfactor,lfactor) -- \leftarrow
175                builders.extension(main,0x2192,sfl,sfm,sar,ffactor,mfactor,lfactor) -- \rightarrow
176                builders.extension(main,0x27F5,sal,sfm,sfr,ffactor,mfactor,lfactor)
177                builders.extension(main,0x27F6,sfl,sfm,sar,ffactor,mfactor,lfactor)
178                builders.extension(main,0x27F7,sal,sfm,sar,ffactor,mfactor,lfactor)
179                builders.extension(main,0x27F8,dal,dfm,dfr,ffactor,mfactor,lfactor)
180                builders.extension(main,0x27F9,dfl,dfm,dar,ffactor,mfactor,lfactor)
181                builders.extension(main,0x27FA,dal,dfm,dar,ffactor,mfactor,lfactor)
182
183                local tfactor = antykwa and -0.8 or -1.1  -- move up check MS
184                local bfactor = antykwa and  0.1 or  0.2
185
186local tfactor = antykwa and -0.6 or -.6  -- move up check MS
187local bfactor = antykwa and  0.1 or  0.2
188
189                local left  = characters[0x27F5]
190                local right = characters[0x27F6]
191                local both  = characters[0x27F7]
192
193                local height = max(left.height or 0,right.height or 0,both.height or 0)
194                local depth  = max(left.depth  or 0,right.depth  or 0,both.depth  or 0)
195
196                left .height = height ; left .depth = depth
197                right.height = height ; right.depth = depth
198                both .height = height ; both .depth = depth
199
200                -- top and bottom arrows : a real mess but now we're drawn into patching it; why are these
201                -- small ones shifted in the bbox; we could do a better job on top and bottom anchors; we
202                -- also could use the bbox as in opentype (\wideoverleftarrow etc)
203
204                local rightarrow  = characters[0x20D7]
205                local leftarrow   = copytable(rightarrow)
206                local doublearrow = copytable(rightarrow)
207                local width       = rightarrow.width
208                local height      = rightarrow.height
209
210                -- top
211
212                characters[0x20D6] = leftarrow
213                characters[0x20E1] = doublearrow
214
215                rightarrow.xoffset = -.2*width
216                leftarrow.commands = {
217                    { "offset", width, 0, 0x20D7, -1, 1 }
218                }
219                doublearrow.commands = {
220                    { "offset", antykwa and .9*width or width, 0, 0x20D7, -1, 1 },
221                    { "offset", antykwa and .1*width or     0, 0, 0x20D7,  1, 1 }
222                }
223
224                -- bottom
225
226                local rightarrow  = copytable(rightarrow)
227                local leftarrow   = copytable(leftarrow)
228                local doublearrow = copytable(doublearrow)
229
230                characters[0x20EE] = leftarrow
231                characters[0x20EF] = rightarrow
232                characters[0x034D] = doublearrow
233
234                local bheight =  .40*height -- can be tuned to match top
235                local yoffset = -.65*height -- can be tuned to match top
236
237                leftarrow  .height = bheight
238                rightarrow .height = bheight
239                doublearrow.height = bheight
240
241                rightarrow .yoffset = yoffset
242                leftarrow  .yoffset = yoffset
243                doublearrow.yoffset = yoffset
244
245                leftarrow.commands = {
246                    { "offset", width, 0, 0x20D7, -1, 1 }
247                }
248                doublearrow.commands = {
249                    { "offset", antykwa and .9*width or width, 0, 0x20D7, -1, 1 },
250                    { "offset", antykwa and .1*width or     0, 0, 0x20D7,  1, 1 }
251                }
252
253                -- extensibles
254
255                local tl = copytable(left)  ; characters[fake20D6] = tl ; characters[0x20D6].next = fake20D6 -- over
256                local tm = copytable(right) ; characters[fake20D7] = tm ; characters[0x20D7].next = fake20D7
257                local tr = copytable(both)  ; characters[fake20E1] = tr ; characters[0x20E1].next = fake20E1
258
259                tl.inneryoffset = tfactor*height ; tl.innerlocation = "top" ; tl.next = nil ; tl.italic = nil
260                tm.inneryoffset = tfactor*height ; tm.innerlocation = "top" ; tm.next = nil ; tm.italic = nil
261                tr.inneryoffset = tfactor*height ; tr.innerlocation = "top" ; tr.next = nil ; tr.italic = nil
262
263                local bl = copytable(left)  ; characters[fake20EE] = bl ; characters[0x20EE].next = fake20EE -- under
264                local bm = copytable(right) ; characters[fake20EF] = bm ; characters[0x20EF].next = fake20EF
265                local br = copytable(both)  ; characters[fake034D] = br ; characters[0x034D].next = fake034D
266
267                bl.inneryoffset = bfactor*height bl.innerlocation = "bottom" ; bl.next = nil ; bl.italic = nil
268                bm.inneryoffset = bfactor*height bm.innerlocation = "bottom" ; bm.next = nil ; bm.italic = nil
269                br.inneryoffset = bfactor*height br.innerlocation = "bottom" ; br.next = nil ; br.italic = nil
270
271                --
272
273                local tfactor = antykwa and -15 or -15
274                local bfactor = antykwa and   1 or   1
275
276                local t = copytable(characters[0x203E]) characters[0x0305] = t t.inneryoffset = tfactor*t.height t.innerlocation = "top"    t.next = nil t.italic = nil
277                local t = copytable(characters[0x203E]) characters[0x0332] = t t.inneryoffset = bfactor*t.height t.innerlocation = "bottom" t.next = nil t.italic = nil
278
279                builders.jointwo(main,0x2016,0x007C,0.20,0x007C)
280                builders.jointwo(main,0x2980,0x007C,0.20,0x007C,0.20,0x007C)
281
282                characters[0x007C].extensible      = true
283                characters[0x007C].varianttemplate = 0x5B
284                characters[0x2016].extensible      = true
285                characters[0x2016].varianttemplate = 0x5B
286                characters[0x2980].extensible      = true
287                characters[0x2980].varianttemplate = 0x5B
288
289-- characters[0x0302].keepbase = true -- can also be a tweak
290
291                -- 21CB leftrightharpoon
292                -- 21CC rightleftharpoon
293
294                builders.stack(main,0x2259,0x0003D,3,0x02227) -- \buildrel\wedge\over=
295
296                builders.jointwo(main,0x22C8,0x022B3,joinrelfactor,0x022B2) -- \mathrel\triangleright\joinrel\mathrel\triangleleft (4 looks better than 3)
297                builders.jointwo(main,0x22A7,0x0007C,joinrelfactor,0x0003D) -- \mathrel|\joinrel=
298
299                builders.overlaytwo(main,0x2260,0x00338,notshiftfactor,0x0003D) -- \not\equal
300                builders.overlaytwo(main,0x2284,0x00338,notshiftfactor,0x02282) -- \not\subset
301                builders.overlaytwo(main,0x2285,0x00338,notshiftfactor,0x02283) -- \not\supset
302                builders.overlaytwo(main,0x2209,0x00338,notshiftfactor,0x02208) -- \not\in
303
304                -- builders.jointwo  (main,0x2254,0x03A,0,0x03D)         -- :=
305                -- builders.jointhree(main,0x2A74,0x03A,0,0x03A,0,0x03D) -- ::=
306                -- builders.jointwo  (main,0x2A75,0x03D,0,0x03D)         -- ==
307
308                builders.repeated(main,0x222B,0x222B,1,1/2)
309                builders.repeated(main,0x222C,0x222B,2,1/2)
310                builders.repeated(main,0x222D,0x222B,3,1/2)
311
312                characters[0x02B9] = characters[0x2032] -- we're nice
313
314                -- some things are done automatically:
315
316                -- add primes
317                -- add equals and alike
318
319            end
320        }
321    }
322}
323