aboutsummaryrefslogtreecommitdiff
path: root/js/mathjax/extensions/TeX/unicode.js
blob: 0c3e50a5adf18108bd578faf5a03a1e362bd167d (plain) (blame)
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
// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */

/*************************************************************
 *
 *  MathJax/extensions/TeX/unicode.js
 *  
 *  Implements the \unicode extension to TeX to allow arbitrary unicode
 *  code points to be entered into the TeX file.  You can specify
 *  the height and depth of the character (the width is determined by
 *  the browser), and the default font from which to take the character.
 *  
 *  Examples:
 *      \unicode{65}                        % the character 'A'
 *      \unicode{x41}                       % the character 'A'
 *      \unicode[.55,0.05]{x22D6}           % less-than with dot, with height .55 and depth 0.05
 *      \unicode[.55,0.05][Geramond]{x22D6} % same taken from Geramond font
 *      \unicode[Garamond]{x22D6}           % same, but with default height, depth of .8,.2
 *
 *  Once a size and font are provided for a given code point, they need
 *  not be specified again in subsequent \unicode calls for that character.
 *  Note that a font list can be given, but Internet Explorer has a buggy
 *  implementation of font-family where it only looks in the first
 *  available font and if the glyph is not in that, it does not look at
 *  later fonts, but goes directly to the default font as set in the
 *  Internet-Options/Font panel.  For this reason, the default font list is
 *  "STIXGeneral,'Arial Unicode MS'", so if the user has STIX fonts, the
 *  symbol will be taken from that (almost all the symbols are in
 *  STIXGeneral), otherwise Arial Unicode MS is tried.
 *  
 *  To configure the default font list, use
 *  
 *      MathJax.Hub.Config({
 *        TeX: {
 *          unicode: {
 *            fonts: "STIXGeneral,'Arial Unicode MS'"
 *          }
 *        }
 *      });
 *
 *  The result of \unicode will have TeX class ORD (i.e., it will act like a
 *  variable).  Use \mathbin, \mathrel, etc, to specify a different class.
 *  
 *  ---------------------------------------------------------------------
 *  
 *  Copyright (c) 2009-2020 The MathJax Consortium
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

//
//  The configuration defaults, augmented by the user settings
//  
MathJax.Extension["TeX/unicode"] = {
  version: "2.7.9",
  unicode: {},
  config: MathJax.Hub.CombineConfig("TeX.unicode",{
    fonts: "STIXGeneral,'Arial Unicode MS'"
  })
};
  
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
  var TEX = MathJax.InputJax.TeX;
  var MML = MathJax.ElementJax.mml;
  var UNICODE = MathJax.Extension["TeX/unicode"].unicode;
  
  //
  //  Add \unicode macro
  //
  TEX.Definitions.Add({macros: {unicode: 'Unicode'}},null,true);
  //
  //  Implementation of \unicode in parser
  //
  TEX.Parse.Augment({
    Unicode: function(name) {
      var HD = this.GetBrackets(name), font;
      if (HD) {
        if (HD.replace(/ /g,"").match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/))
          {HD = HD.replace(/ /g,"").split(/,/); font = this.GetBrackets(name)}
            else {font = HD; HD = null}
      }
      var n = this.trimSpaces(this.GetArgument(name)).replace(/^0x/,"x");
      if (!n.match(/^(x[0-9A-Fa-f]+|[0-9]+)$/)) {
        TEX.Error(["BadUnicode","Argument to \\unicode must be a number"]);
      }
      var N = parseInt(n.match(/^x/) ? "0"+n : n);
      if (!UNICODE[N]) {UNICODE[N] = [800,200,font,N]}
      else if (!font) {font = UNICODE[N][2]}
      if (HD) {
        UNICODE[N][0] = Math.floor(HD[0]*1000);
        UNICODE[N][1] = Math.floor(HD[1]*1000);
      }
      var variant = this.stack.env.font, def = {};
      if (font) {
        UNICODE[N][2] = def.fontfamily = font.replace(/"/g,"'");
        if (variant) {
          if (variant.match(/bold/)) {def.fontweight = "bold"}
          if (variant.match(/italic|-mathit/)) {def.fontstyle = "italic"}
        }
      } else if (variant) {def.mathvariant = variant}
      def.unicode = [].concat(UNICODE[N]); // make a copy
      this.Push(MML.mtext(MML.entity("#"+n)).With(def));
    }
  });

  MathJax.Hub.Startup.signal.Post("TeX unicode Ready");
  
});
    
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
  var MML = MathJax.ElementJax.mml;
  var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;

  //
  //  Override getVariant to make one that includes the font and size
  //
  var GETVARIANT = MML.mbase.prototype.HTMLgetVariant;
  MML.mbase.Augment({
    HTMLgetVariant: function () {
      var variant = GETVARIANT.apply(this,arguments);
      if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
      if (!this.unicode) {return variant}
      variant.unicode = true;
      if (!variant.defaultFont) {
        variant = MathJax.Hub.Insert({},variant); // make a copy
        variant.defaultFont = {family:FONTS};
      }
      var family = this.unicode[2]; if (family) {family += ","+FONTS} else {family = FONTS}
      variant.defaultFont[this.unicode[3]] = [
        this.unicode[0],this.unicode[1],500,0,500,
        {isUnknown:true, isUnicode:true, font:family}
      ];
      return variant;
    }
  });
});

MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
  var MML = MathJax.ElementJax.mml;
  var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;

  //
  //  Override getVariant to make one that includes the font and size
  //
  var GETVARIANT = MML.mbase.prototype.SVGgetVariant;
  MML.mbase.Augment({
    SVGgetVariant: function () {
      var variant = GETVARIANT.call(this);
      if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
      if (!this.unicode) {return variant}
      variant.unicode = true;
      if (!variant.forceFamily) {variant = MathJax.Hub.Insert({},variant)} // make a copy
      variant.defaultFamily = FONTS; variant.noRemap = true;
      variant.h = this.unicode[0]; variant.d = this.unicode[1];
      return variant;
    }
  });
});

MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/unicode.js");
// @license-end