Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.04 KB | None | 0 0
  1. consumeArg(delims): Token[] {
  2. // The argument for a delimited parameter is the shortest (possibly
  3. // empty) sequence of tokens with properly nested {...} groups that is
  4. // followed ... by this particular list of non-parameter tokens.
  5. // The argument for an undelimited parameter is the next nonblank
  6. // token, unless that token is ‘{’, when the argument will be the
  7. // entire {...} group that follows.
  8. const arg: Token[] = [];
  9. const isDelimited = delims && delims.length > 0;
  10. if (!isDelimited) {
  11. // Ignore spaces between arguments. As the TeXbook says:
  12. // "After you have said ‘\def\row#1#2{...}’, you are allowed to
  13. // put spaces between the arguments (e.g., ‘\row x n’), because
  14. // TeX doesn’t use single spaces as undelimited arguments."
  15. this.consumeSpaces();
  16. }
  17. const startOfArg = this.future();
  18. let depth = 0;
  19. let match = 0;
  20. do {
  21. const tok = this.popToken();
  22. arg.push(tok);
  23. if (tok.text === "{") {
  24. ++depth;
  25. } else if (tok.text === "}") {
  26. --depth;
  27. if (depth === -1) {
  28. throw new ParseError("Extra }", tok);
  29. }
  30. } else if (tok.text === "EOF") {
  31. throw new ParseError("End of input in macro argument", tok);
  32. }
  33. if (isDelimited) {
  34. if (depth === 0 && tok.text === delims[match]) {
  35. ++match;
  36. if (match === delims.length) {
  37. arg.splice(-match, tok.text === "{" ? match - 1 : match);
  38. break;
  39. }
  40. } else {
  41. match = 0;
  42. }
  43. }
  44. } while (depth !== 0 || isDelimited);
  45. // If the argument found ... has the form ‘{<nested tokens>}’,
  46. // ... the outermost braces enclosing the argument are removed
  47. if (startOfArg.text === "{" && arg[arg.length - 1].text === "}") {
  48. arg.pop();
  49. arg.shift();
  50. }
  51. arg.reverse(); // like above, to fit in with stack order
  52. return arg;
  53. }
  54.  
  55. /**
  56. * Consume the specified number of arguments from the token stream,
  57. * and return the resulting array of arguments.
  58. */
  59. consumeArgs(numArgs: number, delimiters): Token[][] {
  60. if (delimiters && delimiters[0].length > 0) {
  61. const delims = delimiters[0];
  62. for (let i = 0; i < delims.length; i++) {
  63. const tok = this.popToken();
  64. if (delims[i] !== tok.text) {
  65. throw new ParseError("Use doesn't match its definition", tok);
  66. }
  67. }
  68. }
  69.  
  70. const args: Token[][] = [];
  71. for (let i = 0; i < numArgs; ++i) {
  72. args.push(this.consumeArg(delimiters && delimiters[i + 1]));
  73. }
  74. return args;
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement