Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- consumeArg(delims): Token[] {
- // The argument for a delimited parameter is the shortest (possibly
- // empty) sequence of tokens with properly nested {...} groups that is
- // followed ... by this particular list of non-parameter tokens.
- // The argument for an undelimited parameter is the next nonblank
- // token, unless that token is ‘{’, when the argument will be the
- // entire {...} group that follows.
- const arg: Token[] = [];
- const isDelimited = delims && delims.length > 0;
- if (!isDelimited) {
- // Ignore spaces between arguments. As the TeXbook says:
- // "After you have said ‘\def\row#1#2{...}’, you are allowed to
- // put spaces between the arguments (e.g., ‘\row x n’), because
- // TeX doesn’t use single spaces as undelimited arguments."
- this.consumeSpaces();
- }
- const startOfArg = this.future();
- let depth = 0;
- let match = 0;
- do {
- const tok = this.popToken();
- arg.push(tok);
- if (tok.text === "{") {
- ++depth;
- } else if (tok.text === "}") {
- --depth;
- if (depth === -1) {
- throw new ParseError("Extra }", tok);
- }
- } else if (tok.text === "EOF") {
- throw new ParseError("End of input in macro argument", tok);
- }
- if (isDelimited) {
- if (depth === 0 && tok.text === delims[match]) {
- ++match;
- if (match === delims.length) {
- arg.splice(-match, tok.text === "{" ? match - 1 : match);
- break;
- }
- } else {
- match = 0;
- }
- }
- } while (depth !== 0 || isDelimited);
- // If the argument found ... has the form ‘{<nested tokens>}’,
- // ... the outermost braces enclosing the argument are removed
- if (startOfArg.text === "{" && arg[arg.length - 1].text === "}") {
- arg.pop();
- arg.shift();
- }
- arg.reverse(); // like above, to fit in with stack order
- return arg;
- }
- /**
- * Consume the specified number of arguments from the token stream,
- * and return the resulting array of arguments.
- */
- consumeArgs(numArgs: number, delimiters): Token[][] {
- if (delimiters && delimiters[0].length > 0) {
- const delims = delimiters[0];
- for (let i = 0; i < delims.length; i++) {
- const tok = this.popToken();
- if (delims[i] !== tok.text) {
- throw new ParseError("Use doesn't match its definition", tok);
- }
- }
- }
- const args: Token[][] = [];
- for (let i = 0; i < numArgs; ++i) {
- args.push(this.consumeArg(delimiters && delimiters[i + 1]));
- }
- return args;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement