unicode.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
  2. /* vim: set ts=2 et sw=2 tw=80: */
  3. /*************************************************************
  4. *
  5. * MathJax/extensions/TeX/unicode.js
  6. *
  7. * Implements the \unicode extension to TeX to allow arbitrary unicode
  8. * code points to be entered into the TeX file. You can specify
  9. * the height and depth of the character (the width is determined by
  10. * the browser), and the default font from which to take the character.
  11. *
  12. * Examples:
  13. * \unicode{65} % the character 'A'
  14. * \unicode{x41} % the character 'A'
  15. * \unicode[.55,0.05]{x22D6} % less-than with dot, with height .55 and depth 0.05
  16. * \unicode[.55,0.05][Geramond]{x22D6} % same taken from Geramond font
  17. * \unicode[Garamond]{x22D6} % same, but with default height, depth of .8,.2
  18. *
  19. * Once a size and font are provided for a given code point, they need
  20. * not be specified again in subsequent \unicode calls for that character.
  21. * Note that a font list can be given, but Internet Explorer has a buggy
  22. * implementation of font-family where it only looks in the first
  23. * available font and if the glyph is not in that, it does not look at
  24. * later fonts, but goes directly to the default font as set in the
  25. * Internet-Options/Font panel. For this reason, the default font list is
  26. * "STIXGeneral,'Arial Unicode MS'", so if the user has STIX fonts, the
  27. * symbol will be taken from that (almost all the symbols are in
  28. * STIXGeneral), otherwise Arial Unicode MS is tried.
  29. *
  30. * To configure the default font list, use
  31. *
  32. * MathJax.Hub.Config({
  33. * TeX: {
  34. * unicode: {
  35. * fonts: "STIXGeneral,'Arial Unicode MS'"
  36. * }
  37. * }
  38. * });
  39. *
  40. * The result of \unicode will have TeX class ORD (i.e., it will act like a
  41. * variable). Use \mathbin, \mathrel, etc, to specify a different class.
  42. *
  43. * ---------------------------------------------------------------------
  44. *
  45. * Copyright (c) 2009-2018 The MathJax Consortium
  46. *
  47. * Licensed under the Apache License, Version 2.0 (the "License");
  48. * you may not use this file except in compliance with the License.
  49. * You may obtain a copy of the License at
  50. *
  51. * http://www.apache.org/licenses/LICENSE-2.0
  52. *
  53. * Unless required by applicable law or agreed to in writing, software
  54. * distributed under the License is distributed on an "AS IS" BASIS,
  55. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  56. * See the License for the specific language governing permissions and
  57. * limitations under the License.
  58. */
  59. //
  60. // The configuration defaults, augmented by the user settings
  61. //
  62. MathJax.Extension["TeX/unicode"] = {
  63. version: "2.7.5",
  64. unicode: {},
  65. config: MathJax.Hub.CombineConfig("TeX.unicode",{
  66. fonts: "STIXGeneral,'Arial Unicode MS'"
  67. })
  68. };
  69. MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
  70. var TEX = MathJax.InputJax.TeX;
  71. var MML = MathJax.ElementJax.mml;
  72. var UNICODE = MathJax.Extension["TeX/unicode"].unicode;
  73. //
  74. // Add \unicode macro
  75. //
  76. TEX.Definitions.Add({macros: {unicode: 'Unicode'}},null,true);
  77. //
  78. // Implementation of \unicode in parser
  79. //
  80. TEX.Parse.Augment({
  81. Unicode: function(name) {
  82. var HD = this.GetBrackets(name), font;
  83. if (HD) {
  84. if (HD.replace(/ /g,"").match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/))
  85. {HD = HD.replace(/ /g,"").split(/,/); font = this.GetBrackets(name)}
  86. else {font = HD; HD = null}
  87. }
  88. var n = this.trimSpaces(this.GetArgument(name)).replace(/^0x/,"x");
  89. if (!n.match(/^(x[0-9A-Fa-f]+|[0-9]+)$/)) {
  90. TEX.Error(["BadUnicode","Argument to \\unicode must be a number"]);
  91. }
  92. var N = parseInt(n.match(/^x/) ? "0"+n : n);
  93. if (!UNICODE[N]) {UNICODE[N] = [800,200,font,N]}
  94. else if (!font) {font = UNICODE[N][2]}
  95. if (HD) {
  96. UNICODE[N][0] = Math.floor(HD[0]*1000);
  97. UNICODE[N][1] = Math.floor(HD[1]*1000);
  98. }
  99. var variant = this.stack.env.font, def = {};
  100. if (font) {
  101. UNICODE[N][2] = def.fontfamily = font.replace(/"/g,"'");
  102. if (variant) {
  103. if (variant.match(/bold/)) {def.fontweight = "bold"}
  104. if (variant.match(/italic|-mathit/)) {def.fontstyle = "italic"}
  105. }
  106. } else if (variant) {def.mathvariant = variant}
  107. def.unicode = [].concat(UNICODE[N]); // make a copy
  108. this.Push(MML.mtext(MML.entity("#"+n)).With(def));
  109. }
  110. });
  111. MathJax.Hub.Startup.signal.Post("TeX unicode Ready");
  112. });
  113. MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
  114. var MML = MathJax.ElementJax.mml;
  115. var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
  116. //
  117. // Override getVariant to make one that includes the font and size
  118. //
  119. var GETVARIANT = MML.mbase.prototype.HTMLgetVariant;
  120. MML.mbase.Augment({
  121. HTMLgetVariant: function () {
  122. var variant = GETVARIANT.apply(this,arguments);
  123. if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
  124. if (!this.unicode) {return variant}
  125. variant.unicode = true;
  126. if (!variant.defaultFont) {
  127. variant = MathJax.Hub.Insert({},variant); // make a copy
  128. variant.defaultFont = {family:FONTS};
  129. }
  130. var family = this.unicode[2]; if (family) {family += ","+FONTS} else {family = FONTS}
  131. variant.defaultFont[this.unicode[3]] = [
  132. this.unicode[0],this.unicode[1],500,0,500,
  133. {isUnknown:true, isUnicode:true, font:family}
  134. ];
  135. return variant;
  136. }
  137. });
  138. });
  139. MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
  140. var MML = MathJax.ElementJax.mml;
  141. var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
  142. //
  143. // Override getVariant to make one that includes the font and size
  144. //
  145. var GETVARIANT = MML.mbase.prototype.SVGgetVariant;
  146. MML.mbase.Augment({
  147. SVGgetVariant: function () {
  148. var variant = GETVARIANT.call(this);
  149. if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
  150. if (!this.unicode) {return variant}
  151. variant.unicode = true;
  152. if (!variant.forceFamily) {variant = MathJax.Hub.Insert({},variant)} // make a copy
  153. variant.defaultFamily = FONTS; variant.noRemap = true;
  154. variant.h = this.unicode[0]; variant.d = this.unicode[1];
  155. return variant;
  156. }
  157. });
  158. });
  159. MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/unicode.js");