Style.js (3780B)
1 /** 2 * This file contains information and classes for the various kinds of styles 3 * used in TeX. It provides a generic `Style` class, which holds information 4 * about a specific style. It then provides instances of all the different kinds 5 * of styles possible, and provides functions to move between them and get 6 * information about them. 7 */ 8 9 const sigmas = require("./fontMetrics.js").sigmas; 10 11 const metrics = [{}, {}, {}]; 12 for (const key in sigmas) { 13 if (sigmas.hasOwnProperty(key)) { 14 for (let i = 0; i < 3; i++) { 15 metrics[i][key] = sigmas[key][i]; 16 } 17 } 18 } 19 for (let i = 0; i < 3; i++) { 20 metrics[i].emPerEx = sigmas.xHeight[i] / sigmas.quad[i]; 21 } 22 23 /** 24 * The main style class. Contains a unique id for the style, a size (which is 25 * the same for cramped and uncramped version of a style), a cramped flag, and a 26 * size multiplier, which gives the size difference between a style and 27 * textstyle. 28 */ 29 function Style(id, size, multiplier, cramped) { 30 this.id = id; 31 this.size = size; 32 this.cramped = cramped; 33 this.sizeMultiplier = multiplier; 34 this.metrics = metrics[size > 0 ? size - 1 : 0]; 35 } 36 37 /** 38 * Get the style of a superscript given a base in the current style. 39 */ 40 Style.prototype.sup = function() { 41 return styles[sup[this.id]]; 42 }; 43 44 /** 45 * Get the style of a subscript given a base in the current style. 46 */ 47 Style.prototype.sub = function() { 48 return styles[sub[this.id]]; 49 }; 50 51 /** 52 * Get the style of a fraction numerator given the fraction in the current 53 * style. 54 */ 55 Style.prototype.fracNum = function() { 56 return styles[fracNum[this.id]]; 57 }; 58 59 /** 60 * Get the style of a fraction denominator given the fraction in the current 61 * style. 62 */ 63 Style.prototype.fracDen = function() { 64 return styles[fracDen[this.id]]; 65 }; 66 67 /** 68 * Get the cramped version of a style (in particular, cramping a cramped style 69 * doesn't change the style). 70 */ 71 Style.prototype.cramp = function() { 72 return styles[cramp[this.id]]; 73 }; 74 75 /** 76 * HTML class name, like "displaystyle cramped" 77 */ 78 Style.prototype.cls = function() { 79 return sizeNames[this.size] + (this.cramped ? " cramped" : " uncramped"); 80 }; 81 82 /** 83 * HTML Reset class name, like "reset-textstyle" 84 */ 85 Style.prototype.reset = function() { 86 return resetNames[this.size]; 87 }; 88 89 /** 90 * Return if this style is tightly spaced (scriptstyle/scriptscriptstyle) 91 */ 92 Style.prototype.isTight = function() { 93 return this.size >= 2; 94 }; 95 96 // IDs of the different styles 97 const D = 0; 98 const Dc = 1; 99 const T = 2; 100 const Tc = 3; 101 const S = 4; 102 const Sc = 5; 103 const SS = 6; 104 const SSc = 7; 105 106 // String names for the different sizes 107 const sizeNames = [ 108 "displaystyle textstyle", 109 "textstyle", 110 "scriptstyle", 111 "scriptscriptstyle", 112 ]; 113 114 // Reset names for the different sizes 115 const resetNames = [ 116 "reset-textstyle", 117 "reset-textstyle", 118 "reset-scriptstyle", 119 "reset-scriptscriptstyle", 120 ]; 121 122 // Instances of the different styles 123 const styles = [ 124 new Style(D, 0, 1.0, false), 125 new Style(Dc, 0, 1.0, true), 126 new Style(T, 1, 1.0, false), 127 new Style(Tc, 1, 1.0, true), 128 new Style(S, 2, 0.7, false), 129 new Style(Sc, 2, 0.7, true), 130 new Style(SS, 3, 0.5, false), 131 new Style(SSc, 3, 0.5, true), 132 ]; 133 134 // Lookup tables for switching from one style to another 135 const sup = [S, Sc, S, Sc, SS, SSc, SS, SSc]; 136 const sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc]; 137 const fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc]; 138 const fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc]; 139 const cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc]; 140 141 // We only export some of the styles. Also, we don't export the `Style` class so 142 // no more styles can be generated. 143 module.exports = { 144 DISPLAY: styles[D], 145 TEXT: styles[T], 146 SCRIPT: styles[S], 147 SCRIPTSCRIPT: styles[SS], 148 };