virtual InsetMathAMSArray const * asAMSArrayInset() const { return 0; }
virtual InsetMathArray * asArrayInset() { return 0; }
virtual InsetMathArray const * asArrayInset() const { return 0; }
- virtual InsetMathBrace * asBraceInset() { return 0; }
virtual InsetMathBrace const * asBraceInset() const { return 0; }
virtual InsetMathChar const * asCharInset() const { return 0; }
virtual InsetMathDelim * asDelimInset() { return 0; }
InsetMathBrace();
///
InsetMathBrace(MathArray const & ar);
+ ///
+ InsetMathBrace const * asBraceInset() const { return this; }
/// we write extra braces in any case...
bool extraBraces() const { return true; }
///
void mathmlize(MathStream &) const;
///
void infoize(odocstream & os) const;
-
- /// identifies brace insets
- InsetMathBrace * asBraceInset() { return this; }
- /// identifies brace insets
- InsetMathBrace const * asBraceInset() const { return this; }
private:
virtual std::auto_ptr<InsetBase> doClone() const;
};
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) : value_(value) {}
- ///
- 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_;
-};
-
-
-auto_ptr<InsetBase> MathMacroArgumentValue::doClone() const
-{
- return auto_ptr<InsetBase>(new MathMacroArgumentValue(*this));
-}
-
-
-bool MathMacroArgumentValue::metrics(MetricsInfo & mi, Dimension & dim) const
-{
- value_->metrics(mi, dim);
- metricsMarkers2(dim);
- if (dim_ == dim)
- return false;
- dim_ = dim;
- return true;
-}
-
-
-void MathMacroArgumentValue::draw(PainterInfo & pi, int x, int y) const
-{
- value_->draw(pi, x, y);
-}
-
-
-
-MathMacro::MathMacro(docstring const & name)
- : InsetMathNest(0), name_(name)
+MathMacro::MathMacro(docstring const & name, int numargs)
+ : InsetMathNest(numargs), name_(name)
{}
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])));
- macro.expand(values, expanded_);
+ MacroTable::globalMacros().get(name()).expand(cells_, expanded_);
expanded_.metrics(mi, dim);
}
metricsMarkers2(dim);
InsetBase * MathMacro::editXY(LCursor & cur, int x, int y)
{
// We may have 0 arguments, but InsetMathNest requires at least one.
- if (nargs() > 0)
+ if (nargs() > 0) {
+ // Prevent crash due to cold coordcache
+ // FIXME: This is only a workaround, the call of
+ // InsetMathNest::editXY is correct. The correct fix would
+ // ensure that the coordcache of the arguments is valid.
+ if (!editing(&cur.bv())) {
+ edit(cur, true);
+ return this;
+ }
return InsetMathNest::editXY(cur, x, y);
- else
- return this;
-}
-
-
-void MathMacro::detachArguments(std::vector<MathArray> &args)
-{
- args = cells_;
- cells_ = std::vector<MathArray>();
-}
-
-
-void MathMacro::attachArguments(std::vector<MathArray> const &args)
-{
- cells_ = args;
+ }
+ return this;
}
void MathMacro::maple(MapleStream & os) const
{
+ updateExpansion();
lyx::maple(expanded_, os);
}
void MathMacro::mathmlize(MathStream & os) const
{
+ updateExpansion();
lyx::mathmlize(expanded_, os);
}
void MathMacro::octave(OctaveStream & os) const
{
+ updateExpansion();
lyx::octave(expanded_, os);
}
+void MathMacro::updateExpansion() const
+{
+ //expanded_.substitute(*this);
+}
+
+
void MathMacro::infoize(odocstream & os) const
{
os << "Macro: " << name();
void MathMacro::infoize2(odocstream & os) const
{
os << "Macro: " << name();
+
}
class MathMacro : public InsetMathNest {
public:
/// A macro can be built from an existing template
- MathMacro(docstring const & name);
- ///
- virtual MathMacro * asMacro() { return this; }
- ///
- virtual MathMacro const * asMacro() const { return this; }
+ MathMacro(docstring const & name, int numargs);
///
void draw(PainterInfo & pi, int x, int y) const;
///
{ drawMarkers2(pi, x, y); }
///
bool metrics(MetricsInfo & mi, Dimension & dim) const;
- ///
- bool metricsExpanded(MetricsInfo & mi, Dimension & dim) const;
/// get cursor position
void cursorPos(BufferView const & bv, CursorSlice const & sl,
bool boundary, int & x, int & y) const;
///
docstring name() const;
///
- void detachArguments(std::vector<MathArray> &args);
- ///
- void attachArguments(std::vector<MathArray> const &args);
-
+ void setExpansion(MathArray const & exp, MathArray const & args) const;
+
///
void validate(LaTeXFeatures &) const;
private:
virtual std::auto_ptr<InsetBase> doClone() const;
-
+ ///
+ void updateExpansion() const;
+ ///
+ void expand() const;
+
/// name of macro
docstring name_;
- /// the macro template
+ /// the unexpanded macro defintition
mutable MathArray tmpl_;
/// the macro substituted with our args
mutable MathArray expanded_;
#include "InsetMathFont.h"
#include "InsetMathScript.h"
#include "InsetMathMacro.h"
-#include "InsetMathBrace.h"
#include "MathMacroTable.h"
#include "MathStream.h"
#include "MathSupport.h"
}
+
void MathArray::metrics(MetricsInfo & mi) const
{
frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
if (empty())
return;
- const_cast<MathArray*>(this)->updateMacros( mi );
-
dim_.asc = 0;
dim_.wid = 0;
- Dimension d;
- for (size_t i = 0; i != size(); ++i) {
+ Dimension d;
+ //BufferView & bv = *mi.base.bv;
+ //Buffer const & buf = *bv.buffer();
+ for (size_t i = 0, n = size(); i != n; ++i) {
MathAtom const & at = operator[](i);
+#if 0
+ MathMacro const * mac = at->asMacro();
+ if (mac && buf.hasMacro(mac->name())) {
+ MacroData const & tmpl = buf.getMacro(mac->name());
+ int numargs = tmpl.numargs();
+ if (i + numargs > n)
+ numargs = n - i - 1;
+ lyxerr << "metrics:found macro: " << mac->name()
+ << " numargs: " << numargs << endl;
+ if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) {
+ MathArray args(begin() + i + 1, begin() + i + numargs + 1);
+ MathArray exp;
+ tmpl.expand(args, exp);
+ mac->setExpansion(exp, args);
+ mac->metricsExpanded(mi, d);
+ dim_.wid += mac->widthExpanded();
+ i += numargs;
+ continue;
+ }
+ }
+#endif
at->metrics(mi, d);
dim_ += d;
- if (i == size() - 1)
+ if (i == n - 1)
kerning_ = at->kerning();
}
}
for (size_t i = 0, n = size(); i != n; ++i) {
MathAtom const & at = operator[](i);
+#if 0
+ Buffer const & buf = bv.buffer();
+ // special macro handling
+ MathMacro const * mac = at->asMacro();
+ if (mac && buf.hasMacro(mac->name())) {
+ MacroData const & tmpl = buf.getMacro(mac->name());
+ int numargs = tmpl.numargs();
+ if (i + numargs > n)
+ numargs = n - i - 1;
+ if (!isInside(bv.cursor(), *this, i + 1, i + numargs + 1)) {
+ mac->drawExpanded(pi, x, y);
+ x += mac->widthExpanded();
+ i += numargs;
+ continue;
+ }
+ }
+#endif
bv.coordCache().insets().add(at.nucleus(), x, y);
at->drawSelection(pi, x, y);
at->draw(pi, x, y);
}
-void MathArray::updateMacros(MetricsInfo & mi) {
- Buffer *buf = mi.base.bv->buffer();
-
- // go over the array and look for macros
- for (size_t i = 0; i != size(); ++i) {
- InsetMath * at = operator[](i).nucleus();
- MathMacro * macroInset = at->asMacro();
- if (macroInset) {
- // get arity of macro or 0 if unknown
- size_t numargs = 0;
- if (buf->hasMacro(macroInset->name())) {
- MacroData const & macro = buf->getMacro(macroInset->name());
- numargs = macro.numargs();
- }
-
- // arity of macro changed?
- if (macroInset->nargs() != numargs) {
- // detach all arguments
- std::vector<MathArray> detachedArgs;
- macroInset->detachArguments( detachedArgs );
-
- // too many arguments in the macro inset?
- if (detachedArgs.size() > numargs) {
- // insert overlap back as braces
- std::vector<MathArray> overlap(detachedArgs.begin()+numargs, detachedArgs.end());
- detachedArgs.erase(detachedArgs.begin()+numargs, detachedArgs.end());
- for (size_t j = 0; j < overlap.size(); ++j) {
- MathArray const & arg = overlap[j];
- if (arg.size() == 1)
- insert(i+j+1, MathAtom(new InsetMathBrace(arg)));
- else
- insert(i+j+1, arg[0]);
- }
- i += overlap.size();
- } else {
- // insert some cells from the array into the macro inset
- size_t missingArgs = numargs-detachedArgs.size();
- size_t j;
- for (j = 0; j < missingArgs && i+1+j < size(); ++j) {
- MathAtom & cell = operator[](i+1+j);
- InsetMathBrace const * brace = cell->asBraceInset();
- if (brace) {
- // found brace, convert into argument
- detachedArgs.push_back(brace->cell(0));
- } else {
- MathArray array;
- array.insert(0, cell);
- detachedArgs.push_back(array);
- }
- }
-
- // remove them from the array
- erase(begin()+i+1, begin()+i+1+j);
-
- // enough for the macro inset now?
- // Add some empty ones of necessary
- for (; j < missingArgs; ++j)
- detachedArgs.insert(detachedArgs.end(), MathArray());
- }
-
- // attach arguments back to macro inset
- macroInset->attachArguments(detachedArgs);
- }
- }
- }
-}
-
-
int MathArray::pos2x(size_type pos) const
{
return pos2x(pos, 0);
int kerning() const { return kerning_; }
///
void swap(MathArray & ar) { base_type::swap(ar); }
-
+
protected:
/// cached dimensions of cell
mutable Dimension dim_;
mutable int sshift_;
mutable int kerning_;
- /// attach/detach brace inset to macros
- void updateMacros(MetricsInfo & mi);
-
private:
/// is this an exact match at this position?
bool find1(MathArray const & ar, size_type pos) const;
if (s == "vphantom")
return MathAtom(new InsetMathPhantom(InsetMathPhantom::vphantom));
- return MathAtom(new MathMacro(s));
+ if (MacroTable::globalMacros().has(s))
+ return MathAtom(new MathMacro(s,
+ MacroTable::globalMacros().get(s).numargs()));
+ //if (MacroTable::localMacros().has(s))
+ // return MathAtom(new MathMacro(s,
+ // MacroTable::localMacros().get(s).numargs()));
+
+ //lyxerr << "creating unknown inset '" << s << "'" << endl;
+ return MathAtom(new InsetMathUnknown(s));
}
MacroData::MacroData(docstring const & def, int numargs, docstring const & disp, string const & requires)
- : def_(def), numargs_(numargs), disp_(disp), requires_(requires), lockCount_(0)
+ : def_(def), numargs_(numargs), disp_(disp), requires_(requires)
{}
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
- * \author AndrÈ Pˆnitz
+ * \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#ifndef MATH_MACROTABLE_H
#define MATH_MACROTABLE_H
-#include "support/docstring.h"
-
-#include <boost/assert.hpp>
-
#include <map>
#include <vector>
+#include "support/docstring.h"
+
namespace lyx {
class MathArray;
std::string requires() const { return requires_; }
///
std::string & requires() { return requires_; }
-
- ///
- int lock() { return ++lockCount_; }
- ///
- bool locked() const { return lockCount_ != 0; }
- ///
- void unlock() { --lockCount_; BOOST_ASSERT(lockCount_ >= 0); }
-
+
private:
///
docstring def_;
docstring disp_;
///
std::string requires_;
- ///
- int lockCount_;
};
docstring MathMacroTemplate::prefix() const
{
- return bformat(_(" Macro \\%1$s: "), name_);
+ return bformat(_(" Macro: %1$s: "), name_);
}