+ if (d->displayMode_ == DISPLAY_UNFOLDED) {
+ docstring const & unfolded_name = name();
+ if (unfolded_name != d->name_) {
+ // The macro name was changed
+ Cursor inset_cursor = old;
+ int macroSlice = inset_cursor.find(this);
+ // returning true means the cursor is "now" invalid,
+ // which it was.
+ LASSERT(macroSlice != -1, return true);
+ inset_cursor.cutOff(macroSlice);
+ inset_cursor.recordUndoInset();
+ inset_cursor.pop();
+ inset_cursor.cell().erase(inset_cursor.pos());
+ inset_cursor.cell().insert(inset_cursor.pos(),
+ createInsetMath(unfolded_name, cur.buffer()));
+ cur.resetAnchor();
+ cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar);
+ return true;
+ }
+ }
+ cur.screenUpdateFlags(Update::Force);
+ return InsetMathNest::notifyCursorLeaves(old, cur);
+}
+
+
+void MathMacro::fold(Cursor & cur)
+{
+ if (!d->nextFoldMode_) {
+ d->nextFoldMode_ = true;
+ cur.screenUpdateFlags(Update::SinglePar);
+ }
+}
+
+
+void MathMacro::unfold(Cursor & cur)
+{
+ if (d->nextFoldMode_) {
+ d->nextFoldMode_ = false;
+ cur.screenUpdateFlags(Update::SinglePar);
+ }
+}
+
+
+bool MathMacro::folded() const
+{
+ return d->nextFoldMode_;
+}
+
+
+void MathMacro::write(WriteStream & os) const
+{
+ mode_type mode = modeToEnsure();
+ bool textmode_macro = mode == TEXT_MODE;
+ bool needs_mathmode = mode == MATH_MODE;
+ MathEnsurer ensurer(os, needs_mathmode, true, textmode_macro);
+
+ // non-normal mode
+ if (d->displayMode_ != DISPLAY_NORMAL) {
+ os << "\\" << name();
+ if (name().size() != 1 || isAlphaASCII(name()[0]))
+ os.pendingSpace(true);
+ return;
+ }
+
+ // normal mode
+ // we should be ok to continue even if this fails.
+ LATTEST(d->macro_);
+
+ // We may already be in the argument of a macro
+ bool const inside_macro = os.insideMacro();
+ os.insideMacro(true);
+
+ // Enclose in braces to avoid latex errors with xargs if we have
+ // optional arguments and are in the optional argument of a macro
+ if (d->optionals_ && inside_macro)
+ os << '{';
+
+ // Always protect macros in a fragile environment
+ if (os.fragile())
+ os << "\\protect";
+
+ os << "\\" << name();
+ bool first = true;
+
+ // Optional arguments:
+ // First find last non-empty optional argument
+ idx_type emptyOptFrom = 0;
+ idx_type i = 0;
+ for (; i < cells_.size() && i < d->optionals_; ++i) {
+ if (!cell(i).empty())
+ emptyOptFrom = i + 1;
+ }
+
+ // print out optionals
+ for (i=0; i < cells_.size() && i < emptyOptFrom; ++i) {
+ first = false;
+ os << "[" << cell(i) << "]";
+ }
+
+ // skip the tailing empty optionals
+ i = d->optionals_;
+
+ // Print remaining arguments
+ for (; i < cells_.size(); ++i) {
+ if (cell(i).size() == 1
+ && cell(i)[0].nucleus()->asCharInset()
+ && isASCII(cell(i)[0].nucleus()->asCharInset()->getChar())) {
+ if (first)
+ os << " ";
+ os << cell(i);
+ } else
+ os << "{" << cell(i) << "}";
+ first = false;
+ }
+
+ // Close the opened brace or add space if there was no argument
+ if (d->optionals_ && inside_macro)
+ os << '}';
+ else if (first)
+ os.pendingSpace(true);
+
+ os.insideMacro(inside_macro);