color.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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/color.js
  6. *
  7. * Implements LaTeX-compatible \color macro rather than MathJax's original
  8. * (non-standard) version. It includes the rgb, RGB, gray, and named color
  9. * models, and the \textcolor, \definecolor, \colorbox, and \fcolorbox
  10. * macros.
  11. *
  12. * ---------------------------------------------------------------------
  13. *
  14. * Copyright (c) 2011-2019 The MathJax Consortium
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the "License");
  17. * you may not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * http://www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an "AS IS" BASIS,
  24. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. //
  29. // The configuration defaults, augmented by the user settings
  30. //
  31. MathJax.Extension["TeX/color"] = {
  32. version: "2.7.7",
  33. config: MathJax.Hub.CombineConfig("TeX.color",{
  34. padding: "5px",
  35. border: "2px"
  36. }),
  37. colors: {
  38. Apricot: "#FBB982",
  39. Aquamarine: "#00B5BE",
  40. Bittersweet: "#C04F17",
  41. Black: "#221E1F",
  42. Blue: "#2D2F92",
  43. BlueGreen: "#00B3B8",
  44. BlueViolet: "#473992",
  45. BrickRed: "#B6321C",
  46. Brown: "#792500",
  47. BurntOrange: "#F7921D",
  48. CadetBlue: "#74729A",
  49. CarnationPink: "#F282B4",
  50. Cerulean: "#00A2E3",
  51. CornflowerBlue: "#41B0E4",
  52. Cyan: "#00AEEF",
  53. Dandelion: "#FDBC42",
  54. DarkOrchid: "#A4538A",
  55. Emerald: "#00A99D",
  56. ForestGreen: "#009B55",
  57. Fuchsia: "#8C368C",
  58. Goldenrod: "#FFDF42",
  59. Gray: "#949698",
  60. Green: "#00A64F",
  61. GreenYellow: "#DFE674",
  62. JungleGreen: "#00A99A",
  63. Lavender: "#F49EC4",
  64. LimeGreen: "#8DC73E",
  65. Magenta: "#EC008C",
  66. Mahogany: "#A9341F",
  67. Maroon: "#AF3235",
  68. Melon: "#F89E7B",
  69. MidnightBlue: "#006795",
  70. Mulberry: "#A93C93",
  71. NavyBlue: "#006EB8",
  72. OliveGreen: "#3C8031",
  73. Orange: "#F58137",
  74. OrangeRed: "#ED135A",
  75. Orchid: "#AF72B0",
  76. Peach: "#F7965A",
  77. Periwinkle: "#7977B8",
  78. PineGreen: "#008B72",
  79. Plum: "#92268F",
  80. ProcessBlue: "#00B0F0",
  81. Purple: "#99479B",
  82. RawSienna: "#974006",
  83. Red: "#ED1B23",
  84. RedOrange: "#F26035",
  85. RedViolet: "#A1246B",
  86. Rhodamine: "#EF559F",
  87. RoyalBlue: "#0071BC",
  88. RoyalPurple: "#613F99",
  89. RubineRed: "#ED017D",
  90. Salmon: "#F69289",
  91. SeaGreen: "#3FBC9D",
  92. Sepia: "#671800",
  93. SkyBlue: "#46C5DD",
  94. SpringGreen: "#C6DC67",
  95. Tan: "#DA9D76",
  96. TealBlue: "#00AEB3",
  97. Thistle: "#D883B7",
  98. Turquoise: "#00B4CE",
  99. Violet: "#58429B",
  100. VioletRed: "#EF58A0",
  101. White: "#FFFFFF",
  102. WildStrawberry: "#EE2967",
  103. Yellow: "#FFF200",
  104. YellowGreen: "#98CC70",
  105. YellowOrange: "#FAA21A"
  106. },
  107. /*
  108. * Look up a color based on its model and definition
  109. */
  110. getColor: function (model,def) {
  111. if (!model) {model = "named"}
  112. var fn = this["get_"+model];
  113. if (!fn) {this.TEX.Error(["UndefinedColorModel","Color model '%1' not defined",model])}
  114. return fn.call(this,def);
  115. },
  116. /*
  117. * Get an rgb color
  118. */
  119. get_rgb: function (rgb) {
  120. rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#";
  121. if (rgb.length !== 3)
  122. {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","rgb"])}
  123. for (var i = 0; i < 3; i++) {
  124. if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/))
  125. {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])}
  126. var n = parseFloat(rgb[i]);
  127. if (n < 0 || n > 1) {
  128. this.TEX.Error(["ModelArg2",
  129. "Color values for the %1 model must be between %2 and %3",
  130. "rgb",0,1]);
  131. }
  132. n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
  133. RGB += n;
  134. }
  135. return RGB;
  136. },
  137. /*
  138. * Get an RGB color
  139. */
  140. get_RGB: function (rgb) {
  141. rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#";
  142. if (rgb.length !== 3)
  143. {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","RGB"])}
  144. for (var i = 0; i < 3; i++) {
  145. if (!rgb[i].match(/^\d+$/))
  146. {this.TEX.Error(["InvalidNumber","Invalid number"])}
  147. var n = parseInt(rgb[i]);
  148. if (n > 255) {
  149. this.TEX.Error(["ModelArg2",
  150. "Color values for the %1 model must be between %2 and %3",
  151. "RGB",0,255]);
  152. }
  153. n = n.toString(16); if (n.length < 2) {n = "0"+n}
  154. RGB += n;
  155. }
  156. return RGB;
  157. },
  158. /*
  159. * Get a gray-scale value
  160. */
  161. get_gray: function (gray) {
  162. if (!gray.match(/^\s*(\d+(\.\d*)?|\.\d+)\s*$/))
  163. {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])}
  164. var n = parseFloat(gray);
  165. if (n < 0 || n > 1) {
  166. this.TEX.Error(["ModelArg2",
  167. "Color values for the %1 model must be between %2 and %3",
  168. "gray",0,1]);
  169. }
  170. n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
  171. return "#"+n+n+n;
  172. },
  173. /*
  174. * Get a named value
  175. */
  176. get_named: function (name) {
  177. if (this.colors.hasOwnProperty(name)) {return this.colors[name]}
  178. return name;
  179. },
  180. padding: function () {
  181. var pad = "+"+this.config.padding;
  182. var unit = this.config.padding.replace(/^.*?([a-z]*)$/,"$1");
  183. var pad2 = "+"+(2*parseFloat(pad))+unit;
  184. return {width:pad2, height:pad, depth:pad, lspace:this.config.padding};
  185. }
  186. };
  187. MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
  188. var TEX = MathJax.InputJax.TeX,
  189. MML = MathJax.ElementJax.mml;
  190. var STACKITEM = TEX.Stack.Item;
  191. var COLOR = MathJax.Extension["TeX/color"];
  192. COLOR.TEX = TEX; // for reference in getColor above
  193. TEX.Definitions.Add({
  194. macros: {
  195. color: "Color",
  196. textcolor: "TextColor",
  197. definecolor: "DefineColor",
  198. colorbox: "ColorBox",
  199. fcolorbox: "fColorBox"
  200. }
  201. },null,true);
  202. TEX.Parse.Augment({
  203. //
  204. // Override \color macro definition
  205. //
  206. Color: function (name) {
  207. var model = this.GetBrackets(name),
  208. color = this.GetArgument(name);
  209. color = COLOR.getColor(model,color);
  210. var mml = STACKITEM.style().With({styles:{mathcolor:color}});
  211. this.stack.env.color = color;
  212. this.Push(mml);
  213. },
  214. TextColor: function (name) {
  215. var model = this.GetBrackets(name),
  216. color = this.GetArgument(name);
  217. color = COLOR.getColor(model,color);
  218. var old = this.stack.env.color; this.stack.env.color = color;
  219. var math = this.ParseArg(name);
  220. if (old) {this.stack.env.color} else {delete this.stack.env.color}
  221. this.Push(MML.mstyle(math).With({mathcolor: color}));
  222. },
  223. //
  224. // Define the \definecolor macro
  225. //
  226. DefineColor: function (name) {
  227. var cname = this.GetArgument(name),
  228. model = this.GetArgument(name),
  229. def = this.GetArgument(name);
  230. COLOR.colors[cname] = COLOR.getColor(model,def);
  231. },
  232. //
  233. // Produce a text box with a colored background
  234. //
  235. ColorBox: function (name) {
  236. var cname = this.GetArgument(name),
  237. arg = this.InternalMath(this.GetArgument(name));
  238. this.Push(MML.mpadded.apply(MML,arg).With({
  239. mathbackground:COLOR.getColor("named",cname)
  240. }).With(COLOR.padding()));
  241. },
  242. //
  243. // Procude a framed text box with a colored background
  244. //
  245. fColorBox: function (name) {
  246. var fname = this.GetArgument(name),
  247. cname = this.GetArgument(name),
  248. arg = this.InternalMath(this.GetArgument(name));
  249. this.Push(MML.mpadded.apply(MML,arg).With({
  250. mathbackground: COLOR.getColor("named",cname),
  251. style: "border: "+COLOR.config.border+" solid "+COLOR.getColor("named",fname)
  252. }).With(COLOR.padding()));
  253. }
  254. });
  255. MathJax.Hub.Startup.signal.Post("TeX color Ready");
  256. });
  257. MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/color.js");