/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /************************************************************* * * MathJax/extensions/TeX/color.js * * Implements LaTeX-compatible \color macro rather than MathJax's original * (non-standard) version. It includes the rgb, RGB, gray, and named color * models, and the \textcolor, \definecolor, \colorbox, and \fcolorbox * macros. * * --------------------------------------------------------------------- * * Copyright (c) 2011-2018 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/color"] = { version: "2.7.4", config: MathJax.Hub.CombineConfig("TeX.color",{ padding: "5px", border: "2px" }), colors: { Apricot: "#FBB982", Aquamarine: "#00B5BE", Bittersweet: "#C04F17", Black: "#221E1F", Blue: "#2D2F92", BlueGreen: "#00B3B8", BlueViolet: "#473992", BrickRed: "#B6321C", Brown: "#792500", BurntOrange: "#F7921D", CadetBlue: "#74729A", CarnationPink: "#F282B4", Cerulean: "#00A2E3", CornflowerBlue: "#41B0E4", Cyan: "#00AEEF", Dandelion: "#FDBC42", DarkOrchid: "#A4538A", Emerald: "#00A99D", ForestGreen: "#009B55", Fuchsia: "#8C368C", Goldenrod: "#FFDF42", Gray: "#949698", Green: "#00A64F", GreenYellow: "#DFE674", JungleGreen: "#00A99A", Lavender: "#F49EC4", LimeGreen: "#8DC73E", Magenta: "#EC008C", Mahogany: "#A9341F", Maroon: "#AF3235", Melon: "#F89E7B", MidnightBlue: "#006795", Mulberry: "#A93C93", NavyBlue: "#006EB8", OliveGreen: "#3C8031", Orange: "#F58137", OrangeRed: "#ED135A", Orchid: "#AF72B0", Peach: "#F7965A", Periwinkle: "#7977B8", PineGreen: "#008B72", Plum: "#92268F", ProcessBlue: "#00B0F0", Purple: "#99479B", RawSienna: "#974006", Red: "#ED1B23", RedOrange: "#F26035", RedViolet: "#A1246B", Rhodamine: "#EF559F", RoyalBlue: "#0071BC", RoyalPurple: "#613F99", RubineRed: "#ED017D", Salmon: "#F69289", SeaGreen: "#3FBC9D", Sepia: "#671800", SkyBlue: "#46C5DD", SpringGreen: "#C6DC67", Tan: "#DA9D76", TealBlue: "#00AEB3", Thistle: "#D883B7", Turquoise: "#00B4CE", Violet: "#58429B", VioletRed: "#EF58A0", White: "#FFFFFF", WildStrawberry: "#EE2967", Yellow: "#FFF200", YellowGreen: "#98CC70", YellowOrange: "#FAA21A" }, /* * Look up a color based on its model and definition */ getColor: function (model,def) { if (!model) {model = "named"} var fn = this["get_"+model]; if (!fn) {this.TEX.Error(["UndefinedColorModel","Color model '%1' not defined",model])} return fn.call(this,def); }, /* * Get an rgb color */ get_rgb: function (rgb) { rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#"; if (rgb.length !== 3) {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","rgb"])} for (var i = 0; i < 3; i++) { if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/)) {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])} var n = parseFloat(rgb[i]); if (n < 0 || n > 1) { this.TEX.Error(["ModelArg2", "Color values for the %1 model must be between %2 and %3", "rgb",0,1]); } n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n} RGB += n; } return RGB; }, /* * Get an RGB color */ get_RGB: function (rgb) { rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#"; if (rgb.length !== 3) {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","RGB"])} for (var i = 0; i < 3; i++) { if (!rgb[i].match(/^\d+$/)) {this.TEX.Error(["InvalidNumber","Invalid number"])} var n = parseInt(rgb[i]); if (n > 255) { this.TEX.Error(["ModelArg2", "Color values for the %1 model must be between %2 and %3", "RGB",0,255]); } n = n.toString(16); if (n.length < 2) {n = "0"+n} RGB += n; } return RGB; }, /* * Get a gray-scale value */ get_gray: function (gray) { if (!gray.match(/^\s*(\d+(\.\d*)?|\.\d+)\s*$/)) {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])} var n = parseFloat(gray); if (n < 0 || n > 1) { this.TEX.Error(["ModelArg2", "Color values for the %1 model must be between %2 and %3", "gray",0,1]); } n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n} return "#"+n+n+n; }, /* * Get a named value */ get_named: function (name) { if (this.colors[name]) {return this.colors[name]} return name; }, padding: function () { var pad = "+"+this.config.padding; var unit = this.config.padding.replace(/^.*?([a-z]*)$/,"$1"); var pad2 = "+"+(2*parseFloat(pad))+unit; return {width:pad2, height:pad, depth:pad, lspace:this.config.padding}; } }; MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () { var TEX = MathJax.InputJax.TeX, MML = MathJax.ElementJax.mml; var STACKITEM = TEX.Stack.Item; var COLOR = MathJax.Extension["TeX/color"]; COLOR.TEX = TEX; // for reference in getColor above TEX.Definitions.Add({ macros: { color: "Color", textcolor: "TextColor", definecolor: "DefineColor", colorbox: "ColorBox", fcolorbox: "fColorBox" } },null,true); TEX.Parse.Augment({ // // Override \color macro definition // Color: function (name) { var model = this.GetBrackets(name), color = this.GetArgument(name); color = COLOR.getColor(model,color); var mml = STACKITEM.style().With({styles:{mathcolor:color}}); this.stack.env.color = color; this.Push(mml); }, TextColor: function (name) { var model = this.GetBrackets(name), color = this.GetArgument(name); color = COLOR.getColor(model,color); var old = this.stack.env.color; this.stack.env.color = color; var math = this.ParseArg(name); if (old) {this.stack.env.color} else {delete this.stack.env.color} this.Push(MML.mstyle(math).With({mathcolor: color})); }, // // Define the \definecolor macro // DefineColor: function (name) { var cname = this.GetArgument(name), model = this.GetArgument(name), def = this.GetArgument(name); COLOR.colors[cname] = COLOR.getColor(model,def); }, // // Produce a text box with a colored background // ColorBox: function (name) { var cname = this.GetArgument(name), arg = this.InternalMath(this.GetArgument(name)); this.Push(MML.mpadded.apply(MML,arg).With({ mathbackground:COLOR.getColor("named",cname) }).With(COLOR.padding())); }, // // Procude a framed text box with a colored background // fColorBox: function (name) { var fname = this.GetArgument(name), cname = this.GetArgument(name), arg = this.InternalMath(this.GetArgument(name)); this.Push(MML.mpadded.apply(MML,arg).With({ mathbackground: COLOR.getColor("named",cname), style: "border: "+COLOR.config.border+" solid "+COLOR.getColor("named",fname) }).With(COLOR.padding())); } }); MathJax.Hub.Startup.signal.Post("TeX color Ready"); }); MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/color.js");