using std::vector;
+/// This class is the value of a macro argument, technically
+/// a wrapper of the cells of MathMacro.
+class MathMacroArgumentValue : public InsetMathDim {
+public:
+ ///
+ MathMacroArgumentValue(MathArray const * value, docstring const & macroName)
+ : value_(value), macroName_(macroName) {}
+ ///
+ bool metrics(MetricsInfo & mi, Dimension & dim) const;
+ ///
+ void draw(PainterInfo &, int x, int y) const;
+
+private:
+ std::auto_ptr<InsetBase> doClone() const;
+ MathArray const * value_;
+ docstring macroName_;
+};
+
+
+auto_ptr<InsetBase> MathMacroArgumentValue::doClone() const
+{
+ return auto_ptr<InsetBase>(new MathMacroArgumentValue(*this));
+}
+
+
+bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ // unlock outer macro in arguments, and lock it again later
+ MacroTable::globalMacros().get(macroName_).unlock();
+ value_->metrics(mi, dim);
+ MacroTable::globalMacros().get(macroName_).lock();
+ metricsMarkers2(dim);
+ if (dim_ == dim)
+ return false;
+ dim_ = dim;
+ return true;
+}
+
+
+void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const
+{
+ // unlock outer macro in arguments, and lock it again later
+ MacroTable::globalMacros().get(macroName_).unlock();
+ value_->draw(pi, x, y);
+ MacroTable::globalMacros().get(macroName_).lock();
+}
+
+
MathMacro::MathMacro(docstring const & name, int numargs)
: InsetMathNest(numargs), name_(name)
{}
{
if (!MacroTable::globalMacros().has(name())) {
mathed_string_dim(mi.base.font, "Unknown: " + name(), dim);
- } else if (editing(mi.base.bv)) {
- // FIXME UNICODE
- asArray(MacroTable::globalMacros().get(name()).def(), tmpl_);
- LyXFont font = mi.base.font;
- augmentFont(font, from_ascii("lyxtex"));
- tmpl_.metrics(mi, dim);
- // FIXME UNICODE
- dim.wid += mathed_string_width(font, name()) + 10;
- // FIXME UNICODE
- int ww = mathed_string_width(font, from_ascii("#1: "));
- for (idx_type i = 0; i < nargs(); ++i) {
- MathArray const & c = cell(i);
- c.metrics(mi);
- dim.wid = max(dim.wid, c.width() + ww);
- dim.des += c.height() + 10;
- }
} else {
- MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
- expanded_.metrics(mi, dim);
+ MacroData const & macro = MacroTable::globalMacros().get(name());
+ if (macro.locked()) {
+ mathed_string_dim(mi.base.font, "Self reference: " + name(), dim);
+ expanded_ = MathArray();
+ } else if (editing(mi.base.bv)) {
+ // FIXME UNICODE
+ asArray(macro.def(), tmpl_);
+ LyXFont font = mi.base.font;
+ augmentFont(font, from_ascii("lyxtex"));
+ tmpl_.metrics(mi, dim);
+ // FIXME UNICODE
+ dim.wid += mathed_string_width(font, name()) + 10;
+ // FIXME UNICODE
+ int ww = mathed_string_width(font, from_ascii("#1: "));
+ for (idx_type i = 0; i < nargs(); ++i) {
+ MathArray const & c = cell(i);
+ c.metrics(mi);
+ dim.wid = max(dim.wid, c.width() + ww);
+ dim.des += c.height() + 10;
+ }
+ } else {
+ // create MathMacroArgumentValue object pointing to the cells of the macro
+ MacroData const & macro = MacroTable::globalMacros().get(name());
+ vector<MathArray> values(nargs());
+ for (size_t i = 0; i != nargs(); ++i)
+ values[i].insert(0, MathAtom(new MathMacroArgumentValue(&cells_[i], name())));
+ macro.expand(values, expanded_);
+
+ MacroTable::globalMacros().get(name()).lock();
+ expanded_.metrics(mi, dim);
+ MacroTable::globalMacros().get(name()).unlock();
+ }
}
metricsMarkers2(dim);
if (dim_ == dim)
if (!MacroTable::globalMacros().has(name())) {
// FIXME UNICODE
drawStrRed(pi, x, y, "Unknown: " + name());
- } else if (editing(pi.base.bv)) {
- LyXFont font = pi.base.font;
- augmentFont(font, from_ascii("lyxtex"));
- int h = y - dim_.ascent() + 2 + tmpl_.ascent();
- pi.pain.text(x + 3, h, name(), font);
- int const w = mathed_string_width(font, name());
- tmpl_.draw(pi, x + w + 12, h);
- h += tmpl_.descent();
- Dimension ldim;
- docstring t = from_ascii("#1: ");
- mathed_string_dim(font, t, ldim);
- for (idx_type i = 0; i < nargs(); ++i) {
- MathArray const & c = cell(i);
- h += max(c.ascent(), ldim.asc) + 5;
- c.draw(pi, x + ldim.wid, h);
- char_type str[] = { '#', '1', ':', '\0' };
- str[1] += static_cast<char_type>(i);
- pi.pain.text(x + 3, h, str, font);
- h += max(c.descent(), ldim.des) + 5;
- }
} else {
- expanded_.draw(pi, x, y);
+ MacroData const & macro = MacroTable::globalMacros().get(name());
+ if (macro.locked()) {
+ // FIXME UNICODE
+ drawStrRed(pi, x, y, "Self reference: " + name());
+ } else if (editing(pi.base.bv)) {
+ LyXFont font = pi.base.font;
+ augmentFont(font, from_ascii("lyxtex"));
+ int h = y - dim_.ascent() + 2 + tmpl_.ascent();
+ pi.pain.text(x + 3, h, name(), font);
+ int const w = mathed_string_width(font, name());
+ tmpl_.draw(pi, x + w + 12, h);
+ h += tmpl_.descent();
+ Dimension ldim;
+ string t = "#1: ";
+ mathed_string_dim(font, name(), ldim);
+ for (idx_type i = 0; i < nargs(); ++i) {
+ MathArray const & c = cell(i);
+ h += max(c.ascent(), ldim.asc) + 5;
+ c.draw(pi, x + ldim.wid, h);
+ char_type str[] = { '#', '1', ':', '\0' };
+ str[1] += static_cast<char_type>(i);
+ pi.pain.text(x + 3, h, str, font);
+ h += max(c.descent(), ldim.des) + 5;
+ }
+ } else {
+ MacroTable::globalMacros().get(name()).lock();
+ expanded_.draw(pi, x, y);
+ MacroTable::globalMacros().get(name()).unlock();
+ }
}
drawMarkers2(pi, x, y);
}