From: André Pönitz Date: Tue, 13 Apr 2004 06:27:29 +0000 (+0000) Subject: macro rework X-Git-Tag: 1.6.10~15322 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=b447408de232872fef1537fca542abc23702d572;p=features.git macro rework git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8644 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 4b838eea32..f2efe7a6f4 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -572,12 +572,17 @@ void BufferView::Pimpl::update() // check needed to survive LyX startup if (buffer_) { + // update macro store + buffer_->buildMacros(); + // update all 'visible' paragraphs lyx::par_type beg, end; getParsInRange(buffer_->paragraphs(), top_y(), top_y() + workarea().workHeight(), beg, end); bv_->text()->redoParagraphs(beg, end); + + // and the scrollbar updateScrollbar(); } screen().redraw(*bv_); @@ -854,18 +859,22 @@ void BufferView::Pimpl::trackChanges() bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) { + //lyxerr << "BufferView::Pimpl::workAreaDispatch: request: " + // << cmd << std::endl; // this is only called for mouse related events including // LFUN_FILE_OPEN generated by drag-and-drop. FuncRequest cmd = cmd0; - // handle drag&deop + // handle drag&drop if (cmd.action == LFUN_FILE_OPEN) { owner_->dispatch(cmd); return true; } cmd.y += bv_->top_y(); - //lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl; + if (!bv_->buffer()) + return false; + LCursor cur(*bv_); cur.push(bv_->buffer()->inset()); cur.selection() = bv_->cursor().selection(); diff --git a/src/buffer.C b/src/buffer.C index d16d74ed22..5c4139974a 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -54,6 +54,10 @@ #include "insets/insetinclude.h" #include "insets/insettext.h" +#include "mathed/math_macrotemplate.h" +#include "mathed/math_macrotable.h" +#include "mathed/math_support.h" + #include "frontends/Alert.h" #include "graphics/Previews.h" @@ -116,6 +120,7 @@ using std::make_pair; using std::ifstream; using std::ios; +using std::map; using std::ostream; using std::ostringstream; using std::ofstream; @@ -179,6 +184,9 @@ struct Buffer::Impl /// our LyXText that should be wrapped in an InsetText InsetText inset; + + /// + MacroTable macros; }; @@ -1475,3 +1483,45 @@ Buffer const * Buffer::getMasterBuffer() const return this; } + + +MacroData const & Buffer::getMacro(std::string const & name) const +{ + return pimpl_->macros.get(name); +} + + +bool Buffer::hasMacro(string const & name) const +{ + return pimpl_->macros.has(name); +} + + +void Buffer::insertMacro(string const & name, MacroData const & data) +{ + pimpl_->macros.insert(name, data); +} + + +void Buffer::buildMacros() +{ + // Start with global table. + pimpl_->macros = MacroTable::globalMacros(); + + // Now add our own. + ParagraphList & pars = text().paragraphs(); + for (size_t i = 0, n = pars.size(); i != n; ++i) { + //lyxerr << "searching main par " << i + // << " for macro definitions" << std::endl; + InsetList::iterator it = pars[i].insetlist.begin(); + InsetList::iterator end = pars[i].insetlist.end(); + for ( ; it != end; ++it) { + //lyxerr << "found inset code " << it->inset->lyxCode() << std::endl; + if (it->inset->lyxCode() == InsetBase::MATHMACRO_CODE) { + MathMacroTemplate & mac + = static_cast(*it->inset); + insertMacro(mac.name(), mac.asMacroData()); + } + } + } +} diff --git a/src/buffer.h b/src/buffer.h index 50b1cc2427..5ddca29398 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -39,7 +39,7 @@ class LyXText; class LyXVC; class LaTeXFeatures; class Language; -class Messages; +class MacroData; class OutputParams; class ParagraphList; class ParConstIterator; @@ -308,6 +308,18 @@ public: /// InsetBase & inset() const; + // + // Macro handling + // + /// + void buildMacros(); + /// + bool hasMacro(std::string const & name) const; + /// + MacroData const & getMacro(std::string const & name) const; + /// + void insertMacro(std::string const & name, MacroData const & data); + private: /** Inserts a file into a document \param par if != 0 insert the file. diff --git a/src/cursor.C b/src/cursor.C index 8ca2bd906c..41716183f4 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -38,6 +38,8 @@ #include "mathed/math_data.h" #include "mathed/math_support.h" #include "mathed/math_inset.h" +#include "mathed/math_braceinset.h" +#include "mathed/math_macrotable.h" #include "support/limited_stack.h" #include "support/std_sstream.h" @@ -525,8 +527,9 @@ void LCursor::selHandle(bool sel) { //lyxerr << "LCursor::selHandle" << endl; if (sel == selection()) { - if (!sel) - noUpdate(); +#warning Alfredo: This is too strong (Andre) + //if (!sel) + // noUpdate(); return; } @@ -867,7 +870,12 @@ void LCursor::macroModeClose() if (macro && macro->getInsetName() == name) lyxerr << "can't enter recursive macro" << endl; - niceInsert(createMathInset(name)); + plainInsert(createMathInset(name)); + if (buffer().hasMacro(name)) { + MacroData const & tmpl = buffer().getMacro(name); + for (int i = 0; i < tmpl.numargs(); ++i) + cell().insert(pos(), MathAtom(new MathBraceInset)); + } } diff --git a/src/dociterator.C b/src/dociterator.C index d884598300..f0bf8da069 100644 --- a/src/dociterator.C +++ b/src/dociterator.C @@ -27,9 +27,15 @@ using std::endl; -//we could be able to get rid of this if only every BufferView were -//associated to a buffer on construction -DocIterator::DocIterator() : inset_(0) +// We could be able to get rid of this if only every BufferView were +// associated to a buffer on construction. +DocIterator::DocIterator() + : inset_(0) +{} + + +DocIterator::DocIterator(InsetBase & inset) + : inset_(&inset) {} @@ -47,10 +53,6 @@ DocIterator doc_iterator_end(InsetBase & inset) } -DocIterator::DocIterator(InsetBase & inset) : inset_(&inset) -{} - - InsetBase * DocIterator::nextInset() { BOOST_ASSERT(!empty()); @@ -103,7 +105,7 @@ MathAtom & DocIterator::prevAtom() MathAtom const & DocIterator::nextAtom() const { BOOST_ASSERT(!empty()); - lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; + //lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } @@ -112,7 +114,7 @@ MathAtom const & DocIterator::nextAtom() const MathAtom & DocIterator::nextAtom() { BOOST_ASSERT(!empty()); - lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; + //lyxerr << "lastpos: " << lastpos() << " next atom:\n" << *this << endl; BOOST_ASSERT(pos() < lastpos()); return cell()[pos()]; } diff --git a/src/factory.C b/src/factory.C index a5c1d4de80..e42cb32101 100644 --- a/src/factory.C +++ b/src/factory.C @@ -53,7 +53,7 @@ #include "insets/insetvspace.h" #include "insets/insetwrap.h" -#include "mathed/formulamacro.h" +#include "mathed/math_macrotemplate.h" #include "mathed/math_hullinset.h" #include "frontends/Dialogs.h" @@ -403,7 +403,7 @@ InsetBase * readInset(LyXLex & lex, Buffer const & buf) } else if (tmptok == "External") { inset.reset(new InsetExternal); } else if (tmptok == "FormulaMacro") { - inset.reset(new InsetFormulaMacro); + inset.reset(new MathMacroTemplate); } else if (tmptok == "Formula") { inset.reset(new MathHullInset); } else if (tmptok == "Graphics") { diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index d08c3459c2..7bc3fc0b5b 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -84,8 +84,7 @@ TranslatorMap const build_translator() InsetName("box", InsetBase::BOX_CODE), InsetName("charstyle", InsetBase::CHARSTYLE_CODE), InsetName("vspace", InsetBase::VSPACE_CODE), - InsetName("mathgrid", InsetBase::MATHGRID_CODE), - InsetName("mathhull", InsetBase::MATHHULL_CODE) + InsetName("mathmacroarg", InsetBase::MATHMACROARG_CODE), }; std::size_t const insetnames_size = diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index bd1e3054d7..6c70bceed8 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -294,9 +294,7 @@ public: /// VSPACE_CODE, /// - MATHGRID_CODE, - /// - MATHHULL_CODE + MATHMACROARG_CODE }; /** returns the Code corresponding to the \c name. diff --git a/src/lyx_main.C b/src/lyx_main.C index c3c1edf933..51697e73c7 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -38,6 +38,8 @@ #include "MenuBackend.h" #include "ToolbarBackend.h" +#include "mathed/math_inset.h" + #include "frontends/Alert.h" #include "frontends/lyx_gui.h" #include "frontends/LyXView.h" @@ -71,7 +73,8 @@ using lyx::support::setLyxPaths; using lyx::support::system_lyxdir; using lyx::support::user_lyxdir; -namespace os = lyx::support::os; +using lyx::support::os::getTmpDir; +using lyx::support::os::setTmpDir; using std::endl; using std::string; @@ -204,6 +207,8 @@ void LyX::priv_exec(int & argc, char * argv[]) if (want_gui) lyx_gui::parse_lyxrc(); + initMath(); + vector files; for (int argi = argc - 1; argi >= 1; --argi) @@ -397,8 +402,8 @@ void LyX::init(bool gui) if (lyxerr.debugging(Debug::LYXRC)) lyxrc.print(); - os::setTmpDir(createLyXTmpDir(lyxrc.tempdir_path)); - if (os::getTmpDir().empty()) { + setTmpDir(createLyXTmpDir(lyxrc.tempdir_path)); + if (getTmpDir().empty()) { Alert::error(_("Could not create temporary directory"), bformat(_("Could not create a temporary directory in\n" "%1$s. Make sure that this\n" @@ -413,7 +418,7 @@ void LyX::init(bool gui) } if (lyxerr.debugging(Debug::INIT)) { - lyxerr << "LyX tmp dir: `" << os::getTmpDir() << '\'' << endl; + lyxerr << "LyX tmp dir: `" << getTmpDir() << '\'' << endl; } lyxerr[Debug::INIT] << "Reading lastfiles `" diff --git a/src/lyxlength.C b/src/lyxlength.C index e94b90e0d6..c461efd475 100644 --- a/src/lyxlength.C +++ b/src/lyxlength.C @@ -52,45 +52,41 @@ LyXLength::LyXLength(string const & data) string const LyXLength::asString() const { - ostringstream buffer; - buffer << val_ << unit_name[unit_]; // setw? - return buffer.str(); + ostringstream os; + os << val_ << unit_name[unit_]; // setw? + return os.str(); } string const LyXLength::asLatexString() const { - ostringstream buffer; + char buffer[80]; switch (unit_) { case PTW: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\textwidth"; - break; - case PCW: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\columnwidth"; - break; - case PPW: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\paperwidth"; - break; - case PLW: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\linewidth"; - break; - case PPH: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\paperheight"; - break; - case PTH: - buffer << abs(static_cast(val_/100)) << '.' - << abs(static_cast(val_)%100) << "\\textheight"; - break; + snprintf(buffer, 78, "%.2f\\textwidth", val_/100.0); + break; + case PCW: + snprintf(buffer, 78, "%.2f\\columnwidth", val_/100.0); + break; + case PPW: + snprintf(buffer, 78, "%.2f\\paperwidth", val_/100.0); + break; + case PLW: + snprintf(buffer, 78, "%.2f\\linewidth", val_/100.0); + break; + case PPH: + snprintf(buffer, 78, "%.2f\\paperheight", val_/100.0); + break; + case PTH: + snprintf(buffer, 78, "%.2f\\textheight", val_/100.0); + break; default: - buffer << val_ << unit_name[unit_]; // setw? - break; + snprintf(buffer, 78, "%f%s", val_, unit_name[unit_]); + break; } - return buffer.str(); + // paranoia + buffer[79] = 0; + return buffer; } diff --git a/src/main.C b/src/main.C index ba4637edfe..cc4a51537a 100644 --- a/src/main.C +++ b/src/main.C @@ -14,6 +14,7 @@ #include "debug.h" #include "lyx_main.h" #include "gettext.h" + #include "support/os.h" #ifdef HAVE_IOS diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index 9e2dec5669..c0626947e7 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -7,8 +7,6 @@ INCLUDES = -I$(srcdir)/../ $(BOOST_INCLUDES) libmathed_la_SOURCES = \ textpainter.C \ textpainter.h \ - formulamacro.C \ - formulamacro.h \ math_amsarrayinset.C \ math_amsarrayinset.h \ math_arrayinset.C \ diff --git a/src/mathed/README b/src/mathed/README index d2ad10a309..f160b137e1 100644 --- a/src/mathed/README +++ b/src/mathed/README @@ -7,16 +7,16 @@ Inset hierarchy: MathInset (abstract base) - / | \ + / | \ - Dim Char MacroArg + Dim Char Symbol, Space, ... (thing that need (for things formerly the width_/ascent_ known as characters) /descent_ cache) / \ - Nest Dots Func Space Symbol Bigop Noglyph + Nest Dots, Func, ... (for thing with nested content) @@ -29,9 +29,3 @@ Inset hierarchy: Array Hull (base for eqnarray/align/...) - - -There are only two "real LyXInsets" in here: - -Formula - containing a pointer to a MathHullInset -FormulaMacro - containing a pointer to a MathMacroTemplate diff --git a/src/mathed/math_arrayinset.h b/src/mathed/math_arrayinset.h index 6b15ed72b4..dbd9fe3bc0 100644 --- a/src/mathed/math_arrayinset.h +++ b/src/mathed/math_arrayinset.h @@ -28,7 +28,7 @@ public: /// convienience constructor from whitespace/newline seperated data MathArrayInset(std::string const &, std::string const & str); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// diff --git a/src/mathed/math_braceinset.C b/src/mathed/math_braceinset.C index 99bb5110d2..a23154cb2b 100644 --- a/src/mathed/math_braceinset.C +++ b/src/mathed/math_braceinset.C @@ -44,10 +44,9 @@ void MathBraceInset::metrics(MetricsInfo & mi, Dimension & dim) const cell(0).metrics(mi); Dimension t; mathed_char_dim(mi.base.font, '{', t); - dim.wid = t.wid; dim.asc = max(cell(0).ascent(), t.asc); dim.des = max(cell(0).descent(), t.des); - dim.wid = cell(0).width() + 2 * dim.wid; + dim.wid = cell(0).width() + 2 * t.wid; metricsMarkers(dim); dim_ = dim; } @@ -57,9 +56,11 @@ void MathBraceInset::draw(PainterInfo & pi, int x, int y) const { LyXFont font = pi.base.font; font.setColor(LColor::latex); + Dimension t; + mathed_char_dim(font, '{', t); drawChar(pi, font, x, y, '{'); - cell(0).draw(pi, x + wid_, y); - drawChar(pi, font, x + dim_.width() - wid_, y, '}'); + cell(0).draw(pi, x + t.wid, y); + drawChar(pi, font, x + t.wid + cell(0).width(), y, '}'); drawMarkers(pi, x, y); } diff --git a/src/mathed/math_braceinset.h b/src/mathed/math_braceinset.h index 49960a4898..29bfd2524b 100644 --- a/src/mathed/math_braceinset.h +++ b/src/mathed/math_braceinset.h @@ -23,7 +23,9 @@ public: /// MathBraceInset(MathArray const & ar); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; + /// + MathBraceInset const * asBraceInset() const { return this; } /// we write extra braces in any case... bool extraBraces() const { return true; } /// @@ -44,10 +46,6 @@ public: void mathmlize(MathMLStream &) const; /// void infoize(std::ostream & os) const; - -private: - /// width of brace character - mutable int wid_; }; #endif diff --git a/src/mathed/math_data.C b/src/mathed/math_data.C index e612ae2564..2a8f630119 100644 --- a/src/mathed/math_data.C +++ b/src/mathed/math_data.C @@ -13,11 +13,17 @@ #include "math_data.h" #include "math_fontinset.h" #include "math_scriptinset.h" +#include "math_macro.h" +#include "math_macrotable.h" #include "math_mathmlstream.h" #include "math_support.h" #include "math_replace.h" -#include "debug.h" + #include "LColor.h" +#include "BufferView.h" +#include "buffer.h" +#include "cursor.h" +#include "debug.h" #include "frontends/Painter.h" @@ -27,6 +33,8 @@ using std::abs; using std::endl; using std::min; using std::ostringstream; +using std::string; +using std::vector; MathArray::MathArray() @@ -39,13 +47,6 @@ MathArray::MathArray(const_iterator from, const_iterator to) {} -void MathArray::substitute(MathMacro const & m) -{ - for (iterator it = begin(); it != end(); ++it) - it->nucleus()->substitute(m); -} - - MathAtom & MathArray::operator[](pos_type pos) { BOOST_ASSERT(pos < size()); @@ -217,6 +218,23 @@ void MathArray::metrics(MetricsInfo & mi, Dimension & dim) const } +namespace { + +bool isInside(DocIterator const & it, MathArray const & ar, + lyx::pos_type p1, lyx::pos_type p2) +{ + for (size_t i = 0; i != it.size(); ++i) { + CursorSlice const & sl = it[i]; + if (sl.inset().inMathed() && &sl.cell() == &ar) + return p1 <= sl.pos() && sl.pos() < p2; + } + return false; +} + +} + + + void MathArray::metrics(MetricsInfo & mi) const { //if (clean_) @@ -226,14 +244,36 @@ void MathArray::metrics(MetricsInfo & mi) const mathed_char_dim(mi.base.font, 'I', dim_); - if (!empty()) { - dim_.wid = 0; - Dimension d; - for (const_iterator it = begin(), et = end(); it != et; ++it) { - (*it)->metrics(mi, d); - dim_ += d; - //it->width_ = d.wid; + if (empty()) + return; + + dim_.wid = 0; + 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); + 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; + } } + at->metrics(mi, d); + dim_ += d; } } @@ -248,24 +288,39 @@ void MathArray::draw(PainterInfo & pi, int x, int y) const yo_ = y; drawn_ = true; - if (y + descent() <= 0) // don't draw above the workarea - return; - if (y - ascent() >= pi.pain.paperHeight()) // don't draw below the workarea - return; - if (x + width() <= 0) // don't draw left of workarea - return; - if (x >= pi.pain.paperWidth()) // don't draw right of workarea - return; - if (empty()) { pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); return; } - for (const_iterator it = begin(), et = end(); it != et; ++it) { - (*it)->drawSelection(pi, x, y); - (*it)->draw(pi, x, y); - x += (*it)->width(); + // don't draw outside the workarea + if (y + descent() <= 0 + || y - ascent() >= pi.pain.paperHeight() + || x + width() <= 0 + || x >= pi.pain.paperWidth()) + return; + + BufferView & bv = *pi.base.bv; + Buffer const & buf = *bv.buffer(); + for (size_t i = 0, n = size(); i != n; ++i) { + MathAtom const & at = operator[](i); + // 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; + } + } + at->drawSelection(pi, x, y); + at->draw(pi, x, y); + x += at->width(); } } diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index 89c116cce3..f9b58cc428 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -20,7 +20,6 @@ #include "math_atom.h" #include "dimension.h" -class MathMacro; class LaTeXFeatures; class ReplaceData; class MetricsInfo; @@ -78,9 +77,9 @@ public: /// void dump2() const; /// - void substitute(MathMacro const & macro); - /// void replace(ReplaceData &); + /// + void substitute(MathArray const & m); /// looks for exact match bool match(MathArray const & ar) const; diff --git a/src/mathed/math_dotsinset.h b/src/mathed/math_dotsinset.h index 1177507bfc..79f5cef64f 100644 --- a/src/mathed/math_dotsinset.h +++ b/src/mathed/math_dotsinset.h @@ -23,7 +23,7 @@ public: /// explicit MathDotsInset(latexkeys const * l); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index cc76614ab5..ba2d1d3522 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -37,6 +37,7 @@ #include "math_makeboxinset.h" #include "math_oversetinset.h" #include "math_parboxinset.h" +#include "math_parser.h" #include "math_rootinset.h" #include "math_sizeinset.h" #include "math_spaceinset.h" @@ -139,9 +140,8 @@ void initSymbols() // special case of pre-defined macros if (line.size() > 8 && line.substr(0, 5) == "\\def\\") { - //lyxerr << "defining: '" << line << '\'' << endl; - istringstream is(line); - MathMacroTable::create(MathAtom(new MathMacroTemplate(is))); + //lyxerr << "macro definition: '" << line << '\'' << endl; + MacroTable::globalMacros().insert(line); continue; } @@ -218,6 +218,7 @@ void initMath() { static bool initialized = false; if (!initialized) { + initParser(); initSymbols(); initialized = true; } @@ -235,7 +236,7 @@ latexkeys const * in_word_set(string const & str) MathAtom createMathInset(string const & s) { - //lyxerr << "creating inset with name: '" << s << '\'' << endl;; + //lyxerr << "creating inset with name: '" << s << '\'' << endl; latexkeys const * l = in_word_set(s); if (l) { string const & inset = l->inset; @@ -319,11 +320,7 @@ MathAtom createMathInset(string const & s) if (s == "dfrac") return MathAtom(new MathDfracInset); - if (MathMacroTable::has(s)) - return MathAtom(new MathMacro(s)); - - //lyxerr << "creating inset 2 with name: '" << s << '\'' << endl; - return MathAtom(new MathUnknownInset(s)); + return MathAtom(new MathMacro(s)); } diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index cadde9f34b..bcacee79cf 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -116,8 +116,6 @@ namespace { MathHullInset::MathHullInset() : MathGridInset(1, 1), type_("none"), nonum_(1), label_(1) { - // This is needed as long the math parser is not re-entrant - initMath(); //lyxerr << "sizeof MathInset: " << sizeof(MathInset) << endl; //lyxerr << "sizeof MetricsInfo: " << sizeof(MetricsInfo) << endl; //lyxerr << "sizeof MathCharInset: " << sizeof(MathCharInset) << endl; @@ -902,7 +900,6 @@ bool MathHullInset::getStatus(LCursor & cur, FuncRequest const & cmd, ///////////////////////////////////////////////////////////////////// -#include "formulamacro.h" #include "math_arrayinset.h" #include "math_deliminset.h" #include "math_factory.h" @@ -912,12 +909,10 @@ bool MathHullInset::getStatus(LCursor & cur, FuncRequest const & cmd, #include "bufferview_funcs.h" #include "lyxtext.h" -#include "undo.h" #include "frontends/LyXView.h" #include "frontends/Dialogs.h" -#include "support/std_sstream.h" #include "support/lstrings.h" #include "support/lyxlib.h" @@ -975,8 +970,8 @@ void MathHullInset::handleFont2(LCursor & cur, string const & arg) void MathHullInset::edit(LCursor & cur, bool left) { - lyxerr << "MathHullInset: edit left/right" << endl; cur.push(*this); + left ? idxFirst(cur) : idxLast(cur); } @@ -1039,20 +1034,11 @@ InsetBase::Code MathHullInset::lyxCode() const ///////////////////////////////////////////////////////////////////// -#if 1 -bool MathHullInset::searchForward(BufferView *, string const &, bool, bool) -{ - return false; -} - -#else +#if 0 bool MathHullInset::searchForward(BufferView * bv, string const & str, bool, bool) { - return false; -#ifdef WITH_WARNINGS -#warning pretty ugly -#endif +#warning completely broken static MathHullInset * lastformula = 0; static CursorBase current = DocIterator(ibegin(nucleus())); static MathArray ar; @@ -1089,15 +1075,6 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str, #endif -bool MathHullInset::searchBackward(BufferView * bv, string const & what, - bool a, bool b) -{ - lyxerr[Debug::MATHED] - << "searching backward not implemented in mathed" << endl; - return searchForward(bv, what, a, b); -} - - void MathHullInset::write(Buffer const &, std::ostream & os) const { WriteStream wi(os, false, false); diff --git a/src/mathed/math_hullinset.h b/src/mathed/math_hullinset.h index fb5aa72d5d..ba0ebfb4de 100644 --- a/src/mathed/math_hullinset.h +++ b/src/mathed/math_hullinset.h @@ -156,16 +156,6 @@ public: virtual std::string const editMessage() const; /// virtual void getCursorDim(int &, int &) const; - - /// To allow transparent use of math editing functions - //virtual void status(FuncRequest &); - - /// - virtual bool searchForward(BufferView *, std::string const &, - bool = true, bool = false); - /// - virtual bool searchBackward(BufferView *, std::string const &, - bool = true, bool = false); /// virtual bool isTextInset() const { return true; } /// @@ -173,7 +163,7 @@ public: /// virtual void revealCodes(LCursor & cur) const; /// - virtual EDITABLE editable() const { return HIGHLY_EDITABLE; } + EDITABLE editable() const { return HIGHLY_EDITABLE; } /// void edit(LCursor & cur, bool left); /// diff --git a/src/mathed/math_inset.C b/src/mathed/math_inset.C index 00f9c90124..d7fc527af1 100644 --- a/src/mathed/math_inset.C +++ b/src/mathed/math_inset.C @@ -21,10 +21,9 @@ using std::ostream; using std::endl; -MathArray dummyCell; - MathArray & MathInset::cell(idx_type) { + static MathArray dummyCell; lyxerr << "I don't have a cell 1" << endl; return dummyCell; } @@ -32,16 +31,12 @@ MathArray & MathInset::cell(idx_type) MathArray const & MathInset::cell(idx_type) const { + static MathArray dummyCell; lyxerr << "I don't have a cell 2" << endl; return dummyCell; } -void MathInset::substitute(MathMacro const &) -{} - - - void MathInset::dump() const { lyxerr << "---------------------------------------------" << endl; diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 557cd9825f..7e8365d05a 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -34,6 +34,7 @@ inclusion in the "real LyX insets" FormulaInset and FormulaMacroInset. class OutputParams; class MathArrayInset; class MathAMSArrayInset; +class MathBraceInset; class MathCharInset; class MathDelimInset; class MathFracInset; @@ -80,8 +81,6 @@ public: /// this is overridden in math text insets (i.e. mbox) bool inMathed() const { return true; } - /// substitutes macro arguments if necessary - virtual void substitute(MathMacro const & macro); /// the ascent of the inset above the baseline /// compute the size of the object for text based drawing virtual void metricsT(TextMetricsInfo const & mi, Dimension & dim) const; @@ -98,6 +97,7 @@ public: virtual MathAMSArrayInset const * asAMSArrayInset() const { return 0; } virtual MathArrayInset * asArrayInset() { return 0; } virtual MathArrayInset const * asArrayInset() const { return 0; } + virtual MathBraceInset const * asBraceInset() const { return 0; } virtual MathCharInset const * asCharInset() const { return 0; } virtual MathDelimInset * asDelimInset() { return 0; } virtual MathDelimInset const * asDelimInset() const { return 0; } @@ -109,6 +109,8 @@ public: virtual MathGridInset const * asGridInset() const { return 0; } virtual MathHullInset * asHullInset() { return 0; } virtual MathHullInset const * asHullInset() const { return 0; } + virtual MathMacro * asMacro() { return 0; } + virtual MathMacro const * asMacro() const { return 0; } virtual MathMacroTemplate * asMacroTemplate() { return 0; } virtual MathMacroTemplate const * asMacroTemplate() const { return 0; } virtual MathMatrixInset const * asMatrixInset() const { return 0; } diff --git a/src/mathed/math_kerninset.C b/src/mathed/math_kerninset.C index 8807f0ec5b..fa288ad55d 100644 --- a/src/mathed/math_kerninset.C +++ b/src/mathed/math_kerninset.C @@ -16,7 +16,6 @@ #include "math_support.h" #include "dimension.h" - using std::string; using std::auto_ptr; @@ -55,7 +54,9 @@ void MathKernInset::draw(PainterInfo &, int, int) const void MathKernInset::write(WriteStream & os) const { - os << "\\kern" << wid_.asLatexString() << ' '; +#warning this crashs on startup! + //os << "\\kern" << wid_.asLatexString() << ' '; + os << "\\kern0mm "; } diff --git a/src/mathed/math_kerninset.h b/src/mathed/math_kerninset.h index aa30e03bd9..3a3de3b7c4 100644 --- a/src/mathed/math_kerninset.h +++ b/src/mathed/math_kerninset.h @@ -28,7 +28,7 @@ public: /// explicit MathKernInset(std::string const & wid); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// diff --git a/src/mathed/math_macro.C b/src/mathed/math_macro.C index 50e30927e0..d0d91646e1 100644 --- a/src/mathed/math_macro.C +++ b/src/mathed/math_macro.C @@ -14,33 +14,26 @@ #include "math_macro.h" #include "math_support.h" #include "math_extern.h" -#include "math_macrotable.h" -#include "math_macrotemplate.h" #include "math_mathmlstream.h" + +#include "buffer.h" #include "cursor.h" #include "debug.h" +#include "BufferView.h" #include "LaTeXFeatures.h" - using std::string; using std::max; using std::auto_ptr; using std::endl; -MathMacro::MathMacro(string const & name) - : MathNestInset(MathMacroTable::provide(name)->asMacroTemplate()->numargs()), - tmplate_(MathMacroTable::provide(name)) -{} - -MathMacro::MathMacro(MathMacro const & m) - : MathNestInset(m), - tmplate_(m.tmplate_) // don't copy 'expanded_'! +MathMacro::MathMacro(string const & name) + : name_(name) {} - auto_ptr MathMacro::clone() const { return auto_ptr(new MathMacro(*this)); @@ -49,136 +42,54 @@ auto_ptr MathMacro::clone() const string MathMacro::name() const { - return tmplate_->asMacroTemplate()->name(); + return name_; } -bool MathMacro::defining() const +void MathMacro::setExpansion(MathArray const & exp, MathArray const & arg) const { - return false; - //return mathcursor->formula()->getInsetName() == name(); + expanded_ = exp; + args_ = arg; } -void MathMacro::expand() const +void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const { - expanded_ = tmplate_->cell(tmplate_->cell(1).empty() ? 0 : 1); + LyXFont font = mi.base.font; + augmentFont(font, "lyxtex"); + mathed_string_dim(font, "\\" + name(), dim); + dim_ = dim; } -void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const +void MathMacro::metricsExpanded(MetricsInfo & mi, Dimension & dim) const { - augmentFont(font_, "lyxtex"); - mi_ = mi; - - if (defining()) { - - mathed_string_dim(font_, name(), dim); - - } else if (editing(mi.base.bv)) { - - expand(); - expanded_.metrics(mi, dim); - metricsMarkers(dim); - - dim.wid += mathed_string_width(font_, name()) + 10; - - int ww = mathed_string_width(font_, "#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 { - - expand(); - expanded_.substitute(*this); - expanded_.metrics(mi, dim); - - } - + args_.metrics(mi); + expanded_.metrics(mi, dim); + dim.wid -= args_.size() ? args_.width() : 0; dim_ = dim; } void MathMacro::draw(PainterInfo & pi, int x, int y) const { - metrics(mi_, dim_); - - LyXFont texfont; - augmentFont(texfont, "lyxtex"); - - if (defining()) { - drawStr(pi, texfont, x, y, name()); - return; - } - - if (editing(pi.base.bv)) { - int h = y - dim_.ascent() + 2 + expanded_.ascent(); - drawStr(pi, font_, x + 3, h, name()); - - int const w = mathed_string_width(font_, name()); - expanded_.draw(pi, x + w + 12, h); - h += expanded_.descent(); - - Dimension ldim; - mathed_string_dim(font_, "#1: ", 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 str[] = "#1:"; - str[1] += static_cast(i); - drawStr(pi, texfont, x + 3, h, str); - h += max(c.descent(), ldim.des) + 5; - } - return; - } - - expanded_.draw(pi, x, y); + LyXFont font = pi.base.font; + augmentFont(font, "lyxtex"); + drawStr(pi, font, x, y, "\\" + name()); setPosCache(pi, x, y); } -void MathMacro::dump() const -{ - MathMacroTable::dump(); - lyxerr << "\n macro: '" << this << "'\n" - << " name: '" << name() << "'\n" - << " template: '"; - WriteStream wi(lyxerr); - tmplate_->write(wi); - lyxerr << "'" << endl; -} - - -bool MathMacro::idxUpDown(LCursor & cur, bool up) const -{ - if (up) { - if (!MathNestInset::idxLeft(cur)) - return false; - } else { - if (!MathNestInset::idxRight(cur)) - return false; - } - cur.pos() = cur.cell().x2pos(cur.x_target()); - return true; -} - - -bool MathMacro::idxLeft(LCursor &) const +void MathMacro::drawExpanded(PainterInfo & pi, int x, int y) const { - return false; + expanded_.draw(pi, x, y); + drawMarkers2(pi, x, y); } -bool MathMacro::idxRight(LCursor &) const +int MathMacro::widthExpanded() const { - return false; + return expanded_.width(); } @@ -186,7 +97,6 @@ void MathMacro::validate(LaTeXFeatures & features) const { if (name() == "binom" || name() == "mathcircumflex") features.require(name()); - //MathInset::validate(features); } @@ -213,8 +123,9 @@ void MathMacro::octave(OctaveStream & os) const void MathMacro::updateExpansion() const { - expand(); - expanded_.substitute(*this); +#warning FIXME + //expand(); + //expanded_.substitute(*this); } @@ -227,4 +138,5 @@ void MathMacro::infoize(std::ostream & os) const void MathMacro::infoize2(std::ostream & os) const { os << "Macro: " << name(); + } diff --git a/src/mathed/math_macro.h b/src/mathed/math_macro.h index 9351d8ea51..a1637a7607 100644 --- a/src/mathed/math_macro.h +++ b/src/mathed/math_macro.h @@ -13,41 +13,38 @@ #ifndef MATH_MACRO_H #define MATH_MACRO_H -#include "math_data.h" #include "math_nestinset.h" -#include "metricsinfo.h" - - -class MathMacroTemplate; +#include "math_data.h" /// This class contains the data for a macro. -class MathMacro : public MathNestInset { +class MathMacro : public MathDimInset { public: /// A macro can be built from an existing template explicit MathMacro(std::string const &); /// - MathMacro(MathMacro const &); + std::auto_ptr clone() const; + /// + MathMacro * asMacro() { return this; } + /// + MathMacro const * asMacro() const { return this; } /// void draw(PainterInfo & pi, int x, int y) const; /// - void metrics(MetricsInfo & mi, Dimension & dim) const; + void drawExpanded(PainterInfo & pi, int x, int y) const; /// - virtual std::auto_ptr clone() const; + void metrics(MetricsInfo & mi, Dimension & dim) const; /// - void dump() const; - + void metricsExpanded(MetricsInfo & mi, Dimension & dim) const; /// - bool idxUpDown(LCursor & cur, bool up) const; + int widthExpanded() const; /// - bool idxLeft(LCursor & cur) const; + std::string name() const; /// - bool idxRight(LCursor & cur) const; + void setExpansion(MathArray const & exp, MathArray const & args) const; /// void validate(LaTeXFeatures &) const; - /// - bool isMacro() const { return true; } /// void maple(MapleStream &) const; @@ -61,25 +58,15 @@ public: void infoize2(std::ostream &) const; private: - /// - void operator=(MathMacro const &); - /// - std::string name() const; - /// - bool defining() const; /// void updateExpansion() const; - /// - void expand() const; /// - MathAtom & tmplate_; + std::string name_; /// mutable MathArray expanded_; /// - mutable MetricsInfo mi_; - /// - mutable LyXFont font_; + mutable MathArray args_; }; diff --git a/src/mathed/math_macroarg.C b/src/mathed/math_macroarg.C index 655ff52932..f6b720473b 100644 --- a/src/mathed/math_macroarg.C +++ b/src/mathed/math_macroarg.C @@ -22,7 +22,7 @@ using std::auto_ptr; MathMacroArgument::MathMacroArgument(int n) - : MathNestInset(1), number_(n), expanded_(false) + : number_(n) { if (n < 1 || n > 9) { lyxerr << "MathMacroArgument::MathMacroArgument: wrong Argument id: " @@ -48,20 +48,14 @@ void MathMacroArgument::write(WriteStream & os) const void MathMacroArgument::metrics(MetricsInfo & mi, Dimension & dim) const { - if (expanded_) - cell(0).metrics(mi, dim_); - else - mathed_string_dim(mi.base.font, str_, dim_); + mathed_string_dim(mi.base.font, str_, dim_); dim = dim_; } void MathMacroArgument::draw(PainterInfo & pi, int x, int y) const { - if (expanded_) - cell(0).draw(pi, x, y); - else - drawStrRed(pi, x, y, str_); + drawStrRed(pi, x, y, str_); setPosCache(pi, x, y); } @@ -70,10 +64,3 @@ void MathMacroArgument::normalize(NormalStream & os) const { os << "[macroarg " << str_ << "] "; } - - -void MathMacroArgument::substitute(MathMacro const & m) -{ - cell(0) = m.cell(number_ - 1); - expanded_ = true; -} diff --git a/src/mathed/math_macroarg.h b/src/mathed/math_macroarg.h index 0c4e440dd6..434c3fd8db 100644 --- a/src/mathed/math_macroarg.h +++ b/src/mathed/math_macroarg.h @@ -13,24 +13,24 @@ #ifndef MATHMACROARGUMENT_H #define MATHMACROARGUMENT_H -#include "math_nestinset.h" +#include "math_diminset.h" /// A macro argument. -class MathMacroArgument : public MathNestInset { +class MathMacroArgument : public MathDimInset { public: /// explicit MathMacroArgument(int); /// - virtual std::auto_ptr clone() const; - /// - bool isActive() const { return false; } + std::auto_ptr clone() const; /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// void draw(PainterInfo &, int x, int y) const; /// - void substitute(MathMacro const & macro); + int number() const { return number_; } + /// + InsetBase::Code lyxCode() const { return MATHMACROARG_CODE; } /// void normalize(NormalStream &) const; @@ -42,8 +42,6 @@ private: int number_; /// char str_[3]; - /// - bool expanded_; }; #endif diff --git a/src/mathed/math_macrotable.C b/src/mathed/math_macrotable.C index a671319cc4..952b4e4861 100644 --- a/src/mathed/math_macrotable.C +++ b/src/mathed/math_macrotable.C @@ -12,53 +12,110 @@ #include "math_macrotable.h" #include "math_macrotemplate.h" +#include "math_macroarg.h" +#include "math_support.h" +#include "math_sqrtinset.h" + #include "debug.h" +#include "dociterator.h" -#include +#include "support/std_sstream.h" +#include -using std::string; using std::endl; +using std::istringstream; +using std::map; +using std::pair; +using std::string; +using std::vector; + +MacroData::MacroData() + : numargs_(0) +{} -MathMacroTable::table_type MathMacroTable::macro_table; +MacroData::MacroData(string const & def, int numargs, string const & disp) + : def_(def), numargs_(numargs), disp_(disp) +{} -void MathMacroTable::dump() + +void MacroData::expand(MathArray const & args, MathArray & to) const { -/* - lyxerr << "\n------------------------------------------" << endl; - table_type::const_iterator it; - for (it = macro_table.begin(); it != macro_table.end(); ++it) - lyxerr << it->first - << " [" << it->second->asMacroTemplate()->nargs() << "] : " - << it->second->cell(0) << endl; - lyxerr << "------------------------------------------" << endl; -*/ + MathSqrtInset inset; // Hack. Any inset with a cell would do. + asArray(disp_.empty() ? def_ : disp_, inset.cell(0)); + //lyxerr << "MathData::expand: args: " << args << endl; + //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl; + for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) { + if (!it.nextInset()) + continue; + if (it.nextInset()->lyxCode() != InsetBase::MATHMACROARG_CODE) + continue; + //it.cell().erase(it.pos()); + //it.cell().insert(it.pos(), it.nextInset()->asMathInset() + int n = static_cast(it.nextInset())->number(); + if (n <= args.size()) { + if (args[n - 1]->asBraceInset()) { + it.cell().erase(it.pos()); + it.cell().insert(it.pos(), args[n - 1]->cell(0)); + } else { + it.cell()[it.pos()] = args[n - 1]; + } + } + } + //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl; + to = inset.cell(0); } -MathAtom & MathMacroTable::provide(string const & name) + +// The global table. +MacroTable & MacroTable::globalMacros() { - table_type::iterator pos = macro_table.find(name); - if (pos == macro_table.end()) { - lyxerr << "MathMacroTable::provideTemplate: no template with name '" - << name << "' available." << endl; - BOOST_ASSERT(false); - } - return pos->second; + static MacroTable theGlobalMacros; + return theGlobalMacros; +} + + +bool MacroTable::has(string const & name) const +{ + return macros_.find(name) != macros_.end(); +} + + +MacroData const & MacroTable::get(string const & name) const +{ + table_type::const_iterator it = macros_.find(name); + BOOST_ASSERT(it != macros_.end()); + return it->second; } -void MathMacroTable::create(MathAtom const & at) +void MacroTable::insert(string const & name, MacroData const & data) { - //lyxerr << "MathMacroTable::create: '" - // << at->asMacroTemplate()->name() << "'" << endl; - macro_table[at->asMacroTemplate()->name()] = at; + lyxerr << "MathMacroTable::insert: " << name << endl; + macros_[name] = data; } -bool MathMacroTable::has(string const & name) +void MacroTable::insert(string const & def) { - return macro_table.find(name) != macro_table.end(); + //lyxerr << "MathMacroTable::insert, def: " << def << endl; + istringstream is(def); + MathMacroTemplate mac(is); + insert(mac.name(), mac.asMacroData()); +} + + +void MacroTable::dump() +{ + lyxerr << "\n------------------------------------------" << endl; + table_type::const_iterator it; + for (it = macros_.begin(); it != macros_.end(); ++it) + lyxerr << it->first + << " [" << it->second.def() << "] : " + << " [" << it->second.disp() << "] : " + << endl; + lyxerr << "------------------------------------------" << endl; } diff --git a/src/mathed/math_macrotable.h b/src/mathed/math_macrotable.h index b1433964c9..1dfac3d717 100644 --- a/src/mathed/math_macrotable.h +++ b/src/mathed/math_macrotable.h @@ -12,27 +12,64 @@ #ifndef MATH_MACROTABLE_H #define MATH_MACROTABLE_H -#include "math_atom.h" - #include #include +#include +class MathArray; -class MathMacroTable { +/// +class MacroData { public: /// - static void create(MathAtom const &); + MacroData(); + /// + MacroData(std::string const & def, int nargs, std::string const & disp); + /// + std::string def() const { return def_; } + /// + std::string disp() const { return disp_; } + /// + int numargs() const { return numargs_; } + /// replace #1,#2,... by given MathAtom 0,1,.. + void expand(MathArray const & from, MathArray & to) const; + +private: + /// + std::string def_; + /// + int numargs_; /// - static MathAtom & provide(std::string const & name); + std::string disp_; +}; + + +// This contains a table of "global" macros that are always accessible, +// either because they implement a feature of standard LaTeX or some +// hack to display certain contents nicely. + +class MacroTable { +public: + /// Parse full "\def..." or "\newcommand..." or ... + void insert(std::string const & definition); + /// Insert pre-digested macro definition + void insert(std::string const & name, MacroData const & data); + /// Do we have a macro by that name? + bool has(std::string const & name) const; /// - static bool has(std::string const & name); + MacroData const & get(std::string const & name) const; /// - static void dump(); + void dump(); + + /// the global list + static MacroTable & globalMacros(); + private: /// - typedef std::map table_type; - // - static table_type macro_table; + typedef std::map table_type; + + /// + table_type macros_; }; #endif diff --git a/src/mathed/math_macrotemplate.C b/src/mathed/math_macrotemplate.C index b24c59d0d5..708b554be8 100644 --- a/src/mathed/math_macrotemplate.C +++ b/src/mathed/math_macrotemplate.C @@ -13,16 +13,27 @@ #include "math_macrotemplate.h" #include "math_mathmlstream.h" #include "math_parser.h" -#include "frontends/Painter.h" +#include "math_support.h" + +#include "cursor.h" #include "debug.h" +#include "gettext.h" +#include "lyxlex.h" #include "LColor.h" +#include "frontends/Painter.h" +#include "frontends/font_metrics.h" + +#include "support/lstrings.h" + +using lyx::support::bformat; + using std::string; using std::auto_ptr; +using std::ostream; using std::endl; - MathMacroTemplate::MathMacroTemplate() : MathNestInset(2), numargs_(0), name_(), type_("newcommand") {} @@ -40,7 +51,6 @@ MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs, } - MathMacroTemplate::MathMacroTemplate(std::istream & is) : MathNestInset(2), numargs_(0), name_() { @@ -56,11 +66,17 @@ MathMacroTemplate::MathMacroTemplate(std::istream & is) auto_ptr MathMacroTemplate::clone() const { - //lyxerr << "cloning MacroTemplate!" << endl; return auto_ptr(new MathMacroTemplate(*this)); } +void MathMacroTemplate::edit(LCursor & cur, bool left) +{ + lyxerr << "MathMacroTemplate: edit left/right" << endl; + cur.push(*this); +} + + int MathMacroTemplate::numargs() const { return numargs_; @@ -79,29 +95,85 @@ string MathMacroTemplate::name() const } +string MathMacroTemplate::prefix() const +{ + return bformat(_(" Macro: %1$s: "), name_); +} + + void MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const { - lyxerr << "drawing template " << name() << ' ' << this << std::endl; cell(0).metrics(mi); cell(1).metrics(mi); - dim.wid = cell(0).width() + cell(1).width() + 10; - dim.asc = std::max(cell(0).ascent(), cell(1).ascent()) + 2; - dim.des = std::max(cell(0).descent(), cell(1).descent()) + 2; + dim.wid = cell(0).width() + cell(1).width() + 20 + + font_metrics::width(prefix(), mi.base.font); + dim.asc = std::max(cell(0).ascent(), cell(1).ascent()) + 7; + dim.des = std::max(cell(0).descent(), cell(1).descent()) + 7; dim_ = dim; } -void MathMacroTemplate::draw(PainterInfo & pi, int x, int y) const +void MathMacroTemplate::draw(PainterInfo & p, int x, int y) const { + setPosCache(p, x, y); + + // label + LyXFont font = p.base.font; + font.setColor(LColor::math); + + PainterInfo pi(p.base.bv, p.pain); + pi.base.style = LM_ST_TEXT; + pi.base.font = font; + + int const a = y - dim_.asc + 1; + int const w = dim_.wid - 2; + int const h = dim_.height() - 2; + + // LColor::mathbg used to be "AntiqueWhite" but is "linen" now, too + // the next line would overwrite the selection! + //pi.pain.fillRectangle(x, a, w, h, LColor::mathmacrobg); + pi.pain.rectangle(x, a, w, h, LColor::mathframe); + +#ifdef WITH_WARNINGS +#warning FIXME +#endif +#if 0 + LCursor & cur = p.base.bv->cursor(); + if (cur.isInside(this)) + cur.drawSelection(pi); +#endif + + pi.pain.text(x + 2, y, prefix(), font); + x += font_metrics::width(prefix(), pi.base.font) + 6; + int const w0 = cell(0).width(); int const w1 = cell(1).width(); cell(0).draw(pi, x + 2, y + 1); - pi.pain.rectangle(x, y - dim_.ascent() + 1, w0 + 4, dim_.height(), - LColor::mathline); + pi.pain.rectangle(x, y - dim_.ascent() + 3, + w0 + 4, dim_.height() - 6, LColor::mathline); cell(1).draw(pi, x + 8 + w0, y + 1); - pi.pain.rectangle(x + w0 + 6 , y - dim_.ascent() + 1, w1 + 4, - dim_.height(), LColor::mathline); - setPosCache(pi, x, y); + pi.pain.rectangle(x + w0 + 6, y - dim_.ascent() + 3, + w1 + 4, dim_.height() - 6, LColor::mathline); +} + + +void MathMacroTemplate::read(Buffer const &, LyXLex & lex) +{ + MathArray ar; + mathed_parse_cell(ar, lex.getStream()); + if (ar.size() != 1 || !ar[0]->asMacroTemplate()) { + lyxerr << "cannot read macro from '" << ar << "'" << endl; + return; + } + operator=( *(ar[0]->asMacroTemplate()) ); +} + + +void MathMacroTemplate::write(Buffer const &, std::ostream & os) const +{ + WriteStream wi(os, false, false); + os << "FormulaMacro "; + write(wi); } @@ -129,3 +201,9 @@ void MathMacroTemplate::write(WriteStream & os) const os << "\n{" << cell(1) << '}'; } } + + +MacroData MathMacroTemplate::asMacroData() const +{ + return MacroData(asString(cell(0)), numargs(), asString(cell(1))); +} diff --git a/src/mathed/math_macrotemplate.h b/src/mathed/math_macrotemplate.h index a246e90408..ff888046ae 100644 --- a/src/mathed/math_macrotemplate.h +++ b/src/mathed/math_macrotemplate.h @@ -14,15 +14,9 @@ #define MATH_MACROTEMPLATE_H #include "math_data.h" +#include "math_macrotable.h" #include "math_nestinset.h" -#include - - -class MathMacro; - - -//class MathMacroTemplate : public MathInset, boost::noncopyable /// This class contains the macro definition. class MathMacroTemplate : public MathNestInset { @@ -30,12 +24,22 @@ public: /// MathMacroTemplate(); /// - MathMacroTemplate(std::string const & name, int nargs, std::string const & type, - MathArray const & = MathArray(), MathArray const & = MathArray()); + MathMacroTemplate(std::string const & name, int nargs, + std::string const & type, + MathArray const & = MathArray(), + MathArray const & = MathArray()); /// explicit MathMacroTemplate(std::istream & is); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; + /// + void edit(LCursor & cur, bool left); + /// + EDITABLE editable() const { return HIGHLY_EDITABLE; } + /// + void read(Buffer const &, LyXLex & lex); + /// + void write(Buffer const &, std::ostream & os) const; /// void write(WriteStream & os) const; /// Number of arguments @@ -45,14 +49,22 @@ public: /// std::string name() const; /// - void draw(PainterInfo &, int x, int y) const; + MacroData asMacroData() const; + /// + void draw(PainterInfo & pi, int x, int y) const; /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// identifies macro templates MathMacroTemplate * asMacroTemplate() { return this; } /// identifies macro templates MathMacroTemplate const * asMacroTemplate() const { return this; } + /// + InsetBase::Code lyxCode() const { return MATHMACRO_CODE; } + private: + /// prefix in inset + std::string prefix() const; + /// int numargs_; /// diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 9c6552c43f..e4d0cfb34c 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -99,13 +99,6 @@ void MathNestInset::getCursorPos(CursorSlice const & cur, } -void MathNestInset::substitute(MathMacro const & m) -{ - for (idx_type i = 0; i < nargs(); ++i) - cell(i).substitute(m); -} - - void MathNestInset::metrics(MetricsInfo const & mi) const { MetricsInfo m = mi; @@ -193,10 +186,8 @@ void MathNestInset::draw(PainterInfo & pi, int x, int y) const } -void MathNestInset::drawSelection(PainterInfo & pi, int, int) const +void MathNestInset::drawSelection(PainterInfo & pi, int x, int y) const { - //lyxerr << "MathNestInset::drawing selection: " - // << " x: " << x << " y: " << y << endl; // this should use the x/y values given, not the cached values LCursor & cur = pi.base.bv->cursor(); if (!cur.selection()) @@ -214,6 +205,9 @@ void MathNestInset::drawSelection(PainterInfo & pi, int, int) const int x2 = c.xo() + c.pos2x(s2.pos()); int y2 = c.yo() + c.descent(); pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection); + lyxerr << "MathNestInset::drawing selection 3: " + << " x1: " << x1 << " x2: " << x2 + << " y1: " << y1 << " y2: " << y2 << endl; } else { for (idx_type i = 0; i < nargs(); ++i) { if (idxBetween(i, s1.idx(), s2.idx())) { diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index 7bb9f08f22..d315ef306a 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -32,8 +32,6 @@ public: void draw(PainterInfo & pi, int x, int y) const; /// draw selection background void drawSelection(PainterInfo & pi, int x, int y) const; - /// appends itself with macro arguments substituted - void substitute(MathMacro const & macro); /// identifies NestInsets MathNestInset * asNestInset() { return this; } /// identifies NestInsets diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index eab9bbf56d..f5fd396069 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -147,31 +147,6 @@ enum { }; -void catInit() -{ - fill(theCatcode, theCatcode + 256, catOther); - fill(theCatcode + 'a', theCatcode + 'z' + 1, catLetter); - fill(theCatcode + 'A', theCatcode + 'Z' + 1, catLetter); - - theCatcode[int('\\')] = catEscape; - theCatcode[int('{')] = catBegin; - theCatcode[int('}')] = catEnd; - theCatcode[int('$')] = catMath; - theCatcode[int('&')] = catAlign; - theCatcode[int('\n')] = catNewline; - theCatcode[int('#')] = catParameter; - theCatcode[int('^')] = catSuper; - theCatcode[int('_')] = catSub; - theCatcode[int(0x7f)] = catIgnore; - theCatcode[int(' ')] = catSpace; - theCatcode[int('\t')] = catSpace; - theCatcode[int('\r')] = catNewline; - theCatcode[int('~')] = catActive; - theCatcode[int('%')] = catComment; -} - - - // // Helper class for parsing // @@ -415,13 +390,6 @@ void Parser::tokenize(istream & is) void Parser::tokenize(string const & buffer) { - static bool init_done = false; - - if (!init_done) { - catInit(); - init_done = true; - } - istringstream is(buffer.c_str(), ios::in | ios::binary); char c; @@ -1291,3 +1259,30 @@ void mathed_parse_normal(MathGridInset & grid, string const & str) istringstream is(str.c_str()); Parser(is).parse1(grid, 0, MathInset::MATH_MODE, false); } + + +void initParser() +{ + fill(theCatcode, theCatcode + 256, catOther); + fill(theCatcode + 'a', theCatcode + 'z' + 1, catLetter); + fill(theCatcode + 'A', theCatcode + 'Z' + 1, catLetter); + + theCatcode[int('\\')] = catEscape; + theCatcode[int('{')] = catBegin; + theCatcode[int('}')] = catEnd; + theCatcode[int('$')] = catMath; + theCatcode[int('&')] = catAlign; + theCatcode[int('\n')] = catNewline; + theCatcode[int('#')] = catParameter; + theCatcode[int('^')] = catSuper; + theCatcode[int('_')] = catSub; + theCatcode[int(0x7f)] = catIgnore; + theCatcode[int(' ')] = catSpace; + theCatcode[int('\t')] = catSpace; + theCatcode[int('\r')] = catNewline; + theCatcode[int('~')] = catActive; + theCatcode[int('%')] = catComment; +} + + + diff --git a/src/mathed/math_parser.h b/src/mathed/math_parser.h index 90fc7bf20e..1066db7011 100644 --- a/src/mathed/math_parser.h +++ b/src/mathed/math_parser.h @@ -54,4 +54,6 @@ void mathed_parse_cell(MathArray & ar, std::string const &); /// ... a stream void mathed_parse_cell(MathArray & ar, std::istream &); +void initParser(); + #endif diff --git a/src/metricsinfo.C b/src/metricsinfo.C index 0175f0e7b2..60ba208a4f 100644 --- a/src/metricsinfo.C +++ b/src/metricsinfo.C @@ -10,11 +10,15 @@ #include +#include "BufferView.h" +#include "LColor.h" #include "metricsinfo.h" + #include "mathed/math_support.h" + #include "frontends/Painter.h" -#include "BufferView.h" -#include "LColor.h" + +#include using std::string; @@ -25,7 +29,6 @@ MetricsBase::MetricsBase() {} - MetricsBase::MetricsBase(BufferView * b, LyXFont const & f, int w) : bv(b), font(f), style(LM_ST_TEXT), fontname("mathnormal"), textwidth(w) @@ -43,8 +46,8 @@ MetricsInfo::MetricsInfo(BufferView * bv, LyXFont const & font, int textwidth) -PainterInfo::PainterInfo(BufferView * bv, Painter & pa) - : pain(pa) +PainterInfo::PainterInfo(BufferView * bv, Painter & painter) + : pain(painter) { base.bv = bv; } diff --git a/src/paragraph.C b/src/paragraph.C index c421f56740..0e1dd01a90 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -306,7 +306,7 @@ void Paragraph::insertInset(pos_type pos, InsetBase * inset, bool Paragraph::insetAllowed(InsetOld_code code) { - return pimpl_->inset_owner->insetAllowed(code); + return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code); } diff --git a/src/text.C b/src/text.C index 9821af99e9..a9eb292e9d 100644 --- a/src/text.C +++ b/src/text.C @@ -1589,14 +1589,12 @@ void LyXText::changeCase(LCursor & cur, LyXText::TextCase action) void LyXText::Delete(LCursor & cur) { BOOST_ASSERT(this == cur.text()); - // just move to the right, if we had success make a backspace - CursorSlice sl = cur.top(); - cursorRight(cur); - if (sl != cur.top()) { - recordUndo(cur, Undo::DELETE, cur.par(), - max(par_type(0), cur.par() - 1)); + if (cur.pos() != cur.lastpos()) { + recordUndo(cur, Undo::DELETE, cur.par()); + setCursorIntern(cur, cur.par(), cur.pos() + 1, false, cur.boundary()); backspace(cur); } + // should we do anything in an else branch? } diff --git a/src/text3.C b/src/text3.C index a2f7b01560..8f1c0b6799 100644 --- a/src/text3.C +++ b/src/text3.C @@ -57,7 +57,7 @@ #include "support/std_sstream.h" #include "mathed/math_hullinset.h" -#include "mathed/formulamacro.h" +#include "mathed/math_macrotemplate.h" #include @@ -158,8 +158,9 @@ namespace { cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); cur.dispatch(FuncRequest(LFUN_INSERT_MATH, sel)); } else { - cur.insert(new InsetFormulaMacro(sel)); - cur.dispatch(FuncRequest(LFUN_RIGHT)); + cur.insert(new MathMacroTemplate); + //cur.dispatch(FuncRequest(LFUN_RIGHT)); + //cur.dispatch(FuncRequest(LFUN_INSERT_MATH, sel)); } } cur.message(N_("Math editor mode")); @@ -1312,8 +1313,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) int const nargs = s1.empty() ? 0 : atoi(s1); string const s2 = token(s, ' ', 2); string const type = s2.empty() ? "newcommand" : s2; - cur.insert(new InsetFormulaMacro(token(s, ' ', 0), nargs, s2)); - cur.nextInset()->edit(cur, true); + cur.insert(new MathMacroTemplate(token(s, ' ', 0), nargs, s2)); + //cur.nextInset()->edit(cur, true); } break;