+ docstring pars;
+ while (good() && nextToken().cat() != catBegin) {
+ pars += getToken().cs();
+ ++nargs;
+ }
+ nargs /= 2;
+
+ // read definition
+ MathData def;
+ parse(def, FLAG_ITEM, InsetMath::UNDECIDED_MODE);
+
+ // is a version for display attached?
+ skipSpaces();
+ MathData display;
+ if (nextToken().cat() == catBegin)
+ parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
+
+ cell->push_back(MathAtom(new MathMacroTemplate(buf,
+ name, nargs, 0, MacroTypeDef,
+ vector<MathData>(), def, display)));
+
+ if (buf && (mode_ & Parse::TRACKMACRO))
+ buf->usermacros.insert(name);
+ }
+
+ else if (t.cs() == "newcommand" ||
+ t.cs() == "renewcommand" ||
+ t.cs() == "newlyxcommand") {
+ // get name
+ if (getToken().cat() != catBegin) {
+ error("'{' in \\newcommand expected (1) ");
+ return success_;
+ }
+ docstring name = getToken().cs();
+ if (getToken().cat() != catEnd) {
+ error("'}' in \\newcommand expected");
+ return success_;
+ }
+
+ // get arity
+ docstring const arg = getArg('[', ']');
+ int nargs = 0;
+ if (!arg.empty())
+ nargs = convert<int>(arg);
+
+ // optional argument given?
+ skipSpaces();
+ int optionals = 0;
+ vector<MathData> optionalValues;
+ while (nextToken().character() == '[') {
+ getToken();
+ optionalValues.push_back(MathData());
+ parse(optionalValues[optionals], FLAG_BRACK_LAST, mode);
+ ++optionals;
+ }
+
+ MathData def;
+ parse(def, FLAG_ITEM, InsetMath::UNDECIDED_MODE);
+
+ // is a version for display attached?
+ skipSpaces();
+ MathData display;
+ if (nextToken().cat() == catBegin)
+ parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
+
+ cell->push_back(MathAtom(new MathMacroTemplate(buf,
+ name, nargs, optionals, MacroTypeNewcommand,
+ optionalValues, def, display)));
+
+ if (buf && (mode_ & Parse::TRACKMACRO))
+ buf->usermacros.insert(name);
+ }
+
+ else if (t.cs() == "newcommandx" ||
+ t.cs() == "renewcommandx") {
+ // \newcommandx{\foo}[2][usedefault, addprefix=\global,1=default]{#1,#2}
+ // get name
+ docstring name;
+ if (nextToken().cat() == catBegin) {
+ getToken();