* Parses a group with optional super/subscripts.
(breakOnTokenText)
| 15134 | |
| 15135 | |
| 15136 | parseAtom(breakOnTokenText) { |
| 15137 | // The body of an atom is an implicit group, so that things like |
| 15138 | // \left(x\right)^2 work correctly. |
| 15139 | const base = this.parseGroup("atom", false, null, breakOnTokenText); // In text mode, we don't have superscripts or subscripts |
| 15140 | |
| 15141 | if (this.mode === "text") { |
| 15142 | return base; |
| 15143 | } // Note that base may be empty (i.e. null) at this point. |
| 15144 | |
| 15145 | |
| 15146 | let superscript; |
| 15147 | let subscript; |
| 15148 | |
| 15149 | while (true) { |
| 15150 | // Guaranteed in math mode, so eat any spaces first. |
| 15151 | this.consumeSpaces(); // Lex the first token |
| 15152 | |
| 15153 | const lex = this.nextToken; |
| 15154 | |
| 15155 | if (lex.text === "\\limits" || lex.text === "\\nolimits") { |
| 15156 | // We got a limit control |
| 15157 | const opNode = checkNodeType(base, "op"); |
| 15158 | |
| 15159 | if (opNode) { |
| 15160 | const limits = lex.text === "\\limits"; |
| 15161 | opNode.limits = limits; |
| 15162 | opNode.alwaysHandleSupSub = true; |
| 15163 | } else { |
| 15164 | throw new ParseError("Limit controls must follow a math operator", lex); |
| 15165 | } |
| 15166 | |
| 15167 | this.consume(); |
| 15168 | } else if (lex.text === "^") { |
| 15169 | // We got a superscript start |
| 15170 | if (superscript) { |
| 15171 | throw new ParseError("Double superscript", lex); |
| 15172 | } |
| 15173 | |
| 15174 | superscript = this.handleSupSubscript("superscript"); |
| 15175 | } else if (lex.text === "_") { |
| 15176 | // We got a subscript start |
| 15177 | if (subscript) { |
| 15178 | throw new ParseError("Double subscript", lex); |
| 15179 | } |
| 15180 | |
| 15181 | subscript = this.handleSupSubscript("subscript"); |
| 15182 | } else if (lex.text === "'") { |
| 15183 | // We got a prime |
| 15184 | if (superscript) { |
| 15185 | throw new ParseError("Double superscript", lex); |
| 15186 | } |
| 15187 | |
| 15188 | const prime = { |
| 15189 | type: "textord", |
| 15190 | mode: this.mode, |
| 15191 | text: "\\prime" |
| 15192 | }; // Many primes can be grouped together, so we handle this here |
| 15193 |
no test coverage detected