/************************************************************* * * Copyright (c) 2018-2025 Omar Al-Ithawi and 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. */ /** * @file Parse methods and helper functtions for the color package. * * @author i@omardo.com (Omar Al-Ithawi) */ import NodeUtil from '../NodeUtil.js'; import { ParseMethod } from '../Types.js'; import { PropertyList } from '../../../core/Tree/Node.js'; import { ParseUtil } from '../ParseUtil.js'; import TexParser from '../TexParser.js'; import { ColorModel } from './ColorUtil.js'; /** * Build PropertyList from padding value. * * @param {string} colorPadding Padding for \colorbox and \fcolorbox. * @returns {PropertyList} The padding properties. */ export function padding(colorPadding: string): PropertyList { const pad = `+${colorPadding}`; const unit = colorPadding.replace(/^.*?([a-z]*)$/, '$1'); const pad2 = 2 * parseFloat(pad); return { width: `+${pad2}${unit}`, height: pad, depth: pad, lspace: colorPadding, }; } export const ColorMethods: { [key: string]: ParseMethod } = { /** * Override \color macro definition. * * @param {TexParser} parser The calling parser. * @param {string} name The name of the control sequence. */ Color(parser: TexParser, name: string) { const model = parser.GetBrackets(name, ''); const colorDef = parser.GetArgument(name); const colorModel: ColorModel = parser.configuration.packageData.get('color').model; const color = colorModel.getColor(model, colorDef); const style = parser.itemFactory .create('style') .setProperties({ styles: { mathcolor: color } }); parser.stack.env['color'] = color; parser.Push(style); }, /** * Define the \textcolor macro. * * @param {TexParser} parser The calling parser. * @param {string} name The name of the control sequence. */ TextColor(parser: TexParser, name: string) { const model = parser.GetBrackets(name, ''); const colorDef = parser.GetArgument(name); const colorModel: ColorModel = parser.configuration.packageData.get('color').model; const color = colorModel.getColor(model, colorDef); const old = parser.stack.env['color']; parser.stack.env['color'] = color; const math = parser.ParseArg(name); if (old) { parser.stack.env['color'] = old; } else { delete parser.stack.env['color']; } const node = parser.create('node', 'mstyle', [math], { mathcolor: color }); parser.Push(node); }, /** * Define the \definecolor macro. * * @param {TexParser} parser The calling parser. * @param {string} name The name of the control sequence. */ DefineColor(parser: TexParser, name: string) { const cname = parser.GetArgument(name); const model = parser.GetArgument(name); const def = parser.GetArgument(name); const colorModel: ColorModel = parser.configuration.packageData.get('color').model; colorModel.defineColor(model, cname, def); parser.Push(parser.itemFactory.create('null')); }, /** * Produce a text box with a colored background: `\colorbox`. * * @param {TexParser} parser The calling parser. * @param {string} name The name of the control sequence. */ ColorBox(parser: TexParser, name: string) { const model = parser.GetBrackets(name, ''); const cdef = parser.GetArgument(name); const math = ParseUtil.internalMath(parser, parser.GetArgument(name)); const colorModel = parser.configuration.packageData.get('color').model; const node = parser.create('node', 'mpadded', math, { mathbackground: colorModel.getColor(model, cdef), }); NodeUtil.setProperties(node, padding(parser.options.color.padding)); parser.Push(node); }, /** * Produce a framed text box with a colored background: `\fcolorbox`. * * @param {TexParser} parser The calling parser. * @param {string} name The name of the control sequence. */ FColorBox(parser: TexParser, name: string) { const fmodel = parser.GetBrackets(name, ''); const fname = parser.GetArgument(name); const cmodel = parser.GetBrackets(name, fmodel); const cname = parser.GetArgument(name); const math = ParseUtil.internalMath(parser, parser.GetArgument(name)); const options = parser.options.color; const colorModel = parser.configuration.packageData.get('color').model; const node = parser.create('node', 'mpadded', math, { mathbackground: colorModel.getColor(cmodel, cname), style: `border: ${options.borderWidth} solid ${colorModel.getColor(fmodel, fname)}`, }); NodeUtil.setProperties(node, padding(options.padding)); parser.Push(node); }, };