X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMathMacro.cpp;h=f4150f30f84250533ff313105aa5ebfda07605cb;hb=ff85a4902ec4fff1b3bf0dbc9c9c53b3e87563cf;hp=5564600d06487f06ed46261486e9ed608e80eaa3;hpb=c060a85d811674888c31db9ee0407d8b5cc37b6e;p=lyx.git diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index 5564600d06..f4150f30f8 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -28,19 +28,21 @@ #include "FuncStatus.h" #include "FuncRequest.h" #include "LaTeXFeatures.h" -#include "LyXFunc.h" +#include "LyX.h" #include "LyXRC.h" -#include "Undo.h" #include "frontends/Painter.h" #include "support/debug.h" +#include "support/gettext.h" #include "support/lassert.h" +#include "support/lstrings.h" #include "support/textutils.h" #include #include +using namespace lyx::support; using namespace std; namespace lyx { @@ -75,6 +77,8 @@ public: /// void mathmlize(MathStream & ms) const { ms << mathMacro_.cell(idx_); } /// + void htmlize(HtmlStream & ms) const { ms << mathMacro_.cell(idx_); } + /// void draw(PainterInfo & pi, int x, int y) const { if (mathMacro_.editMetrics(pi.base.bv)) { // The only way a ArgumentProxy can appear is in a cell of the @@ -124,7 +128,8 @@ private: MathMacro::MathMacro(Buffer * buf, docstring const & name) : InsetMathNest(buf, 0), name_(name), displayMode_(DISPLAY_INIT), expanded_(buf), attachedArgsNum_(0), optionals_(0), nextFoldMode_(true), - macroBackup_(buf), macro_(0), needsUpdate_(false), appetite_(9) + macroBackup_(buf), macro_(0), needsUpdate_(false), + isUpdating_(false), appetite_(9) {} @@ -137,6 +142,15 @@ Inset * MathMacro::clone() const } +void MathMacro::normalize(NormalStream & os) const +{ + os << "[macro " << name(); + for (size_t i = 0; i < nargs(); ++i) + os << ' ' << cell(i); + os << ']'; +} + + docstring MathMacro::name() const { if (displayMode_ == DISPLAY_UNFOLDED) @@ -163,9 +177,12 @@ bool MathMacro::editMode(BufferView const * bv) const { // look if there is no other macro in edit mode above ++i; for (; i != cur.depth(); ++i) { - MathMacro const * macro = dynamic_cast(&cur[i].inset()); - if (macro && macro->displayMode() == DISPLAY_NORMAL) - return false; + InsetMath * im = cur[i].asInsetMath(); + if (im) { + MathMacro const * macro = im->asMacro(); + if (macro && macro->displayMode() == DISPLAY_NORMAL) + return false; + } } // ok, none found, I am the highest one @@ -202,7 +219,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const && editing_[mi.base.bv]) { // Macro will be edited in a old-style list mode here: - LASSERT(macro_ != 0, /**/); + LBUFERR(macro_); Dimension fontDim; FontInfo labelFont = sane_font; math_font_max_dim(labelFont, fontDim.asc, fontDim.des); @@ -239,7 +256,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid += 2; metricsMarkers2(dim); } else { - LASSERT(macro_ != 0, /**/); + LBUFERR(macro_); // calculate metrics, hoping that all cells are seen macro_->lock(); @@ -248,7 +265,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const // otherwise do a manual metrics call CoordCache & coords = mi.base.bv->coordCache(); for (idx_type i = 0; i < nargs(); ++i) { - if (!coords.getArrays().has(&cell(i))) { + if (!coords.getArrays().hasDim(&cell(i))) { Dimension tdim; cell(i).metrics(mi, tdim); } @@ -287,7 +304,7 @@ int MathMacro::kerning(BufferView const * bv) const { void MathMacro::updateMacro(MacroContext const & mc) { if (validName()) { - macro_ = mc.get(name()); + macro_ = mc.get(name()); if (macro_ && macroBackup_ != *macro_) { macroBackup_ = *macro_; needsUpdate_ = true; @@ -298,8 +315,27 @@ void MathMacro::updateMacro(MacroContext const & mc) } -void MathMacro::updateRepresentation() +class MathMacro::UpdateLocker +{ +public: + explicit UpdateLocker(MathMacro & mm) : mac(mm) + { + mac.isUpdating_ = true; + } + ~UpdateLocker() { mac.isUpdating_ = false; } +private: + MathMacro & mac; +}; + + +void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc, + UpdateType utype) { + if (isUpdating_) + return; + + UpdateLocker locker(*this); + // known macro? if (macro_ == 0) return; @@ -307,14 +343,11 @@ void MathMacro::updateRepresentation() // update requires requires_ = macro_->requires(); - // non-normal mode? We are done! - if (displayMode_ != DISPLAY_NORMAL) + if (!needsUpdate_ + // non-normal mode? We are done! + || (displayMode_ != DISPLAY_NORMAL)) return; - // macro changed? - if (!needsUpdate_) - return; - needsUpdate_ = false; // get default values of macro @@ -332,6 +365,8 @@ void MathMacro::updateRepresentation() } // expanding macro with the values macro_->expand(values, expanded_.cell(0)); + if (utype == OutputUpdate && !expanded_.cell(0).empty()) + expanded_.cell(0).updateMacros(cur, mc, utype); // get definition for list edit mode docstring const & display = macro_->display(); asArray(display.empty() ? macro_->definition() : display, definition_); @@ -445,14 +480,14 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const // edit mode changed? if (editing_[pi.base.bv] != editMode(pi.base.bv)) - pi.base.bv->cursor().updateFlags(Update::SinglePar); + pi.base.bv->cursor().screenUpdateFlags(Update::SinglePar); } void MathMacro::drawSelection(PainterInfo & pi, int x, int y) const { // We may have 0 arguments, but InsetMathNest requires at least one. - if (cells_.size() > 0) + if (!cells_.empty()) InsetMathNest::drawSelection(pi, x, y); } @@ -494,8 +529,7 @@ bool MathMacro::validName() const { docstring n = name(); - // empty name? - if (n.size() == 0) + if (n.empty()) return false; // converting back and force doesn't swallow anything? @@ -534,7 +568,7 @@ void MathMacro::validate(LaTeXFeatures & features) const void MathMacro::edit(Cursor & cur, bool front, EntryDirection entry_from) { - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); InsetMathNest::edit(cur, front, entry_from); } @@ -543,7 +577,7 @@ Inset * MathMacro::editXY(Cursor & cur, int x, int y) { // We may have 0 arguments, but InsetMathNest requires at least one. if (nargs() > 0) { - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); return InsetMathNest::editXY(cur, x, y); } else return this; @@ -552,7 +586,7 @@ Inset * MathMacro::editXY(Cursor & cur, int x, int y) void MathMacro::removeArgument(Inset::pos_type pos) { if (displayMode_ == DISPLAY_NORMAL) { - LASSERT(size_t(pos) < cells_.size(), /**/); + LASSERT(size_t(pos) < cells_.size(), return); cells_.erase(cells_.begin() + pos); if (size_t(pos) < attachedArgsNum_) --attachedArgsNum_; @@ -567,7 +601,7 @@ void MathMacro::removeArgument(Inset::pos_type pos) { void MathMacro::insertArgument(Inset::pos_type pos) { if (displayMode_ == DISPLAY_NORMAL) { - LASSERT(size_t(pos) <= cells_.size(), /**/); + LASSERT(size_t(pos) <= cells_.size(), return); cells_.insert(cells_.begin() + pos, MathData()); if (size_t(pos) < attachedArgsNum_) ++attachedArgsNum_; @@ -581,7 +615,7 @@ void MathMacro::insertArgument(Inset::pos_type pos) { void MathMacro::detachArguments(vector & args, bool strip) { - LASSERT(displayMode_ == DISPLAY_NORMAL, /**/); + LASSERT(displayMode_ == DISPLAY_NORMAL, return); args = cells_; // strip off empty cells, but not more than arity-attachedArgsNum_ @@ -602,7 +636,7 @@ void MathMacro::detachArguments(vector & args, bool strip) void MathMacro::attachArguments(vector const & args, size_t arity, int optionals) { - LASSERT(displayMode_ == DISPLAY_NORMAL, /**/); + LASSERT(displayMode_ == DISPLAY_NORMAL, return); cells_ = args; attachedArgsNum_ = args.size(); cells_.resize(arity); @@ -615,14 +649,14 @@ void MathMacro::attachArguments(vector const & args, size_t arity, int bool MathMacro::idxFirst(Cursor & cur) const { - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); return InsetMathNest::idxFirst(cur); } bool MathMacro::idxLast(Cursor & cur) const { - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); return InsetMathNest::idxLast(cur); } @@ -635,18 +669,21 @@ bool MathMacro::notifyCursorLeaves(Cursor const & old, Cursor & cur) // The macro name was changed Cursor inset_cursor = old; int macroSlice = inset_cursor.find(this); - LASSERT(macroSlice != -1, /**/); + // 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.updateFlags(cur.disp_.update() | Update::SinglePar); + cur.resetAnchor(); + cur.screenUpdateFlags(cur.result().screenUpdate() | Update::SinglePar); return true; } } - cur.updateFlags(Update::Force); + cur.screenUpdateFlags(Update::Force); return InsetMathNest::notifyCursorLeaves(old, cur); } @@ -655,7 +692,7 @@ void MathMacro::fold(Cursor & cur) { if (!nextFoldMode_) { nextFoldMode_ = true; - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); } } @@ -664,7 +701,7 @@ void MathMacro::unfold(Cursor & cur) { if (nextFoldMode_) { nextFoldMode_ = false; - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); } } @@ -688,10 +725,11 @@ void MathMacro::write(WriteStream & os) const } // normal mode - LASSERT(macro_, /**/); + // we should be ok to continue even if this fails. + LATTEST(macro_); - // optional arguments make macros fragile - if (optionals_ > 0 && os.fragile()) + // Always protect macros in a fragile environment + if (os.fragile()) os << "\\protect"; os << "\\" << name(); @@ -719,7 +757,7 @@ void MathMacro::write(WriteStream & os) const for (; i < cells_.size(); ++i) { if (cell(i).size() == 1 && cell(i)[0].nucleus()->asCharInset() - && cell(i)[0].nucleus()->asCharInset()->getChar() < 0x80) { + && isASCII(cell(i)[0].nucleus()->asCharInset()->getChar())) { if (first) os << " "; os << cell(i); @@ -742,7 +780,23 @@ void MathMacro::maple(MapleStream & os) const void MathMacro::mathmlize(MathStream & os) const { - os << expanded_.cell(0); + MathData const & data = expanded_.cell(0); + if (data.empty()) { + // this means that we do not recognize the macro + throw MathExportException(); + } + os << data; +} + + +void MathMacro::htmlize(HtmlStream & os) const +{ + MathData const & data = expanded_.cell(0); + if (data.empty()) { + // this means that we do not recognize the macro + throw MathExportException(); + } + os << data; } @@ -754,14 +808,13 @@ void MathMacro::octave(OctaveStream & os) const void MathMacro::infoize(odocstream & os) const { - os << "Macro: " << name(); + os << bformat(_("Macro: %1$s"), name()); } void MathMacro::infoize2(odocstream & os) const { - os << "Macro: " << name(); - + os << bformat(_("Macro: %1$s"), name()); } @@ -840,13 +893,13 @@ bool MathMacro::insertCompletion(Cursor & cur, docstring const & s, docstring newName = name() + s; asArray(newName, cell(0)); cur.bv().cursor().pos() = name().size(); - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); // finish macro if (finished) { cur.bv().cursor().pop(); ++cur.bv().cursor().pos(); - cur.updateFlags(Update::SinglePar); + cur.screenUpdateFlags(Update::SinglePar); } return true;