]> git.lyx.org Git - features.git/commitdiff
macro rework
authorAndré Pönitz <poenitz@gmx.net>
Tue, 13 Apr 2004 06:27:29 +0000 (06:27 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Tue, 13 Apr 2004 06:27:29 +0000 (06:27 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8644 a592a061-630c-0410-9148-cb99ea01b6c8

42 files changed:
src/BufferView_pimpl.C
src/buffer.C
src/buffer.h
src/cursor.C
src/dociterator.C
src/factory.C
src/insets/insetbase.C
src/insets/insetbase.h
src/lyx_main.C
src/lyxlength.C
src/main.C
src/mathed/Makefile.am
src/mathed/README
src/mathed/math_arrayinset.h
src/mathed/math_braceinset.C
src/mathed/math_braceinset.h
src/mathed/math_data.C
src/mathed/math_data.h
src/mathed/math_dotsinset.h
src/mathed/math_factory.C
src/mathed/math_hullinset.C
src/mathed/math_hullinset.h
src/mathed/math_inset.C
src/mathed/math_inset.h
src/mathed/math_kerninset.C
src/mathed/math_kerninset.h
src/mathed/math_macro.C
src/mathed/math_macro.h
src/mathed/math_macroarg.C
src/mathed/math_macroarg.h
src/mathed/math_macrotable.C
src/mathed/math_macrotable.h
src/mathed/math_macrotemplate.C
src/mathed/math_macrotemplate.h
src/mathed/math_nestinset.C
src/mathed/math_nestinset.h
src/mathed/math_parser.C
src/mathed/math_parser.h
src/metricsinfo.C
src/paragraph.C
src/text.C
src/text3.C

index 4b838eea324e6a27e68455357deeea86c324d8a2..f2efe7a6f4aff10c4ed68eec50d447b08f690820 100644 (file)
@@ -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();
index d16d74ed22177300e34627147129d731f324a29a..5c4139974a969722d7b09e61165637525327e81a 100644 (file)
 #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<MathMacroTemplate &>(*it->inset);
+                               insertMacro(mac.name(), mac.asMacroData());
+                       }
+               }
+       }
+}
index 50b1cc2427baf88813310232f8826c6c77b70dfd..5ddca293989e1d974b8d16373041bbe1483c0f9d 100644 (file)
@@ -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.
index 8ca2bd906c45fb6530d69bad0b77d5bb7e78234d..41716183f48551b3fef33c2b52057dc8a14fe86a 100644 (file)
@@ -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));
+       }
 }
 
 
index d884598300b1be9bdcfec31860672cf3c9d1654b..f0bf8da06988cc805d8bcf79d0810ca8fa7b6aea 100644 (file)
 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()];
 }
index a5c1d4de80ded8897883e932abf916964da61b41..e42cb3210149d7d482f4d045327014d67d89a69c 100644 (file)
@@ -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") {
index d08c3459c2c11e4165817ad87543157a0c0f76a3..7bc3fc0b5b49d1addf745d0090bbe97f85d8c5b3 100644 (file)
@@ -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 =
index bd1e3054d74f1272032807f5cef14ccceb45c16d..6c70bceed88ff5c325e2efd5ceb2453b3d6983bb 100644 (file)
@@ -294,9 +294,7 @@ public:
                ///
                VSPACE_CODE,
                ///
-               MATHGRID_CODE,
-               ///
-               MATHHULL_CODE
+               MATHMACROARG_CODE
        };
 
        /** returns the Code corresponding to the \c name.
index c3c1edf9338a5c6343908c42a70ff400ea7dc2ea..51697e73c7f988e6aa78bfbf070af34f81299112 100644 (file)
@@ -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<string> 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 `"
index e94b90e0d6bd138900da25f8b04e596bd89e79ec..c461efd4755dd666661e2c7275aabafef4ceeadf 100644 (file)
@@ -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<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(val_)%100) << "\\textwidth";
-           break;
-       case PCW:
-           buffer << abs(static_cast<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(val_)%100) << "\\columnwidth";
-           break;
-       case PPW:
-           buffer << abs(static_cast<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(val_)%100) << "\\paperwidth";
-           break;
-       case PLW:
-           buffer << abs(static_cast<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(val_)%100) << "\\linewidth";
-           break;
-       case PPH:
-           buffer << abs(static_cast<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(val_)%100) << "\\paperheight";
-           break;
-       case PTH:
-           buffer << abs(static_cast<int>(val_/100)) << '.'
-                  << abs(static_cast<int>(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;
 }
 
 
index ba4637edfed9601bf781367b083d6b762d08d2c0..cc4a51537a1cf7f7c3dffb3238df6039b876a373 100644 (file)
@@ -14,6 +14,7 @@
 #include "debug.h"
 #include "lyx_main.h"
 #include "gettext.h"
+
 #include "support/os.h"
 
 #ifdef HAVE_IOS
index 9e2dec5669d4e109bcf78a74fce5bc5413b08bc1..c0626947e7bb78ee66ce8b5af830a49531c5b780 100644 (file)
@@ -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 \
index d2ad10a30996b0a4fbf4e7eae70abfaa10a72e08..f160b137e14bcaa228c21e06ee0fe5e078a2c093 100644 (file)
@@ -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
index 6b15ed72b49be908e7fa4b5ed498f98dda945dcd..dbd9fe3bc035b5aa70429a703d351c8c8375ef49 100644 (file)
@@ -28,7 +28,7 @@ public:
        /// convienience constructor from whitespace/newline seperated data
        MathArrayInset(std::string const &, std::string const & str);
        ///
-       virtual std::auto_ptr<InsetBase> clone() const;
+       std::auto_ptr<InsetBase> clone() const;
        ///
        void metrics(MetricsInfo & mi, Dimension & dim) const;
        ///
index 99bb5110d27b7dda6b7c1f067e33fa0c3108bc14..a23154cb2b9fed7cb735ed196e775df710ebadd9 100644 (file)
@@ -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);
 }
 
index 49960a4898976be93a355c114d9e26171afd1877..29bfd2524bcaeef80f8d5893fba6a89da9efe468 100644 (file)
@@ -23,7 +23,9 @@ public:
        ///
        MathBraceInset(MathArray const & ar);
        ///
-       virtual std::auto_ptr<InsetBase> clone() const;
+       std::auto_ptr<InsetBase> 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
index e612ae25640698d88081f36aa446d3d7bf6b9493..2a8f630119ed8dde94346256b0069d1825a91a4b 100644 (file)
 #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();
        }
 }
 
index 89c116cce35fa48b94458f7d6d17350092c99095..f9b58cc428ac7157ff1075187494f93a71fc1491 100644 (file)
@@ -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;
index 1177507bfc3d99af57ca724d03df65ee5a273b48..79f5cef64feef086064a735658f1c11339063df8 100644 (file)
@@ -23,7 +23,7 @@ public:
        ///
        explicit MathDotsInset(latexkeys const * l);
        ///
-       virtual std::auto_ptr<InsetBase> clone() const;
+       std::auto_ptr<InsetBase> clone() const;
        ///
        void metrics(MetricsInfo & mi, Dimension & dim) const;
        ///
index cc76614ab5e029c211a3ab5902fb989d929f50fa..ba2d1d35229ca5f0d3f3906e22a549ca9b16b0aa 100644 (file)
@@ -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));
 }
 
 
index cadde9f34bda057f1226e510555944be615db05e..bcacee79cf5b8fb46d6fe215f06b74b9975984e9 100644 (file)
@@ -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);
index fb5aa72d5d5241f63913a4c9c2e1dd77e68eda6b..ba0ebfb4deb4c396cb1937f71c1279e3e5a0d041 100644 (file)
@@ -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);
        ///
index 00f9c90124c2306a2641963cde4bc8d9b5e67311..d7fc527af1029b4a249a70294c49edaab5be4045 100644 (file)
@@ -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;
index 557cd9825fb2fdab2b93219ff3d7d69c9c9673b2..7e8365d05a71a791360b0408512a19cc3e9ea0d5 100644 (file)
@@ -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; }
index 8807f0ec5b52e6a8e0e947bdcc451af86eab2bbb..fa288ad55d52b75b05798bd961970f1428d2a54a 100644 (file)
@@ -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 ";
 }
 
 
index aa30e03bd92639571360f9a8eaeb0d3b73423111..3a3de3b7c45210e37e7867fb7c293fc16b7d824e 100644 (file)
@@ -28,7 +28,7 @@ public:
        ///
        explicit MathKernInset(std::string const & wid);
        ///
-       virtual std::auto_ptr<InsetBase> clone() const;
+       std::auto_ptr<InsetBase> clone() const;
        ///
        void metrics(MetricsInfo & mi, Dimension & dim) const;
        ///
index 50e30927e07598d1c5996be2eb8fce7406516023..d0d91646e1b48737faa63f8ed0ea3eca40dc7d15 100644 (file)
 #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<InsetBase> MathMacro::clone() const
 {
        return auto_ptr<InsetBase>(new MathMacro(*this));
@@ -49,136 +42,54 @@ auto_ptr<InsetBase> 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<char>(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();
+
 }
index 9351d8ea51f367552bd97932f22fd6f908ce6a6c..a1637a7607de4447a88cadbccd060dfc72c12128 100644 (file)
 #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<InsetBase> 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<InsetBase> 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_;
 };
 
 
index 655ff52932a50b0a160045c15928d5937c96056f..f6b720473b8b8e837ee09c015b63cec354253d6f 100644 (file)
@@ -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;
-}
index 0c4e440dd60271dc1c2ecb56e14b803d5515326d..434c3fd8dbeddb00007b5c74dc3a08e37f0955e3 100644 (file)
 #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<InsetBase> clone() const;
-       ///
-       bool isActive() const { return false; }
+       std::auto_ptr<InsetBase> 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
index a671319cc45940d4d050d356a4a2a8d13d743855..952b4e4861e1c85780fd294715680a65accd8891 100644 (file)
 
 #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 <boost/assert.hpp>
+#include "support/std_sstream.h"
 
+#include <boost/assert.hpp>
 
-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<MathMacroArgument*>(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;
 }
index b1433964c91dc2748acf82b5fd84d26b4dec3948..1dfac3d71751536f88e27a275dfe57e9fd62e7d1 100644 (file)
 #ifndef MATH_MACROTABLE_H
 #define MATH_MACROTABLE_H
 
-#include "math_atom.h"
-
 #include <map>
 #include <string>
+#include <vector>
 
+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<std::string, MathAtom> table_type;
-       //
-       static table_type macro_table;
+       typedef std::map<std::string, MacroData> table_type;
+
+       ///
+       table_type macros_;
 };
 
 #endif
index b24c59d0d5d03c14a76144114136eb2bf71677d1..708b554be8b557a26d8abfe913a839800a29310a 100644 (file)
 #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<InsetBase> MathMacroTemplate::clone() const
 {
-       //lyxerr << "cloning MacroTemplate!" << endl;
        return auto_ptr<InsetBase>(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)));
+}
index a246e904088ff60418c131938e8566ec5275828a..ff888046ae90db9dfc281692d6e7ad6be13faf12 100644 (file)
 #define MATH_MACROTEMPLATE_H
 
 #include "math_data.h"
+#include "math_macrotable.h"
 #include "math_nestinset.h"
 
-#include <string>
-
-
-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<InsetBase> clone() const;
+       std::auto_ptr<InsetBase> 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_;
        ///
index 9c6552c43feee5df4fd0e7952948cac64c475dee..e4d0cfb34c187dc0227352b7aa8b3adca2f51e31 100644 (file)
@@ -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())) {
index 7bb9f08f22e95e9e42625d971e7f2316dfa12a31..d315ef306aadd293837dfd0a08cad4c2c63c2fa0 100644 (file)
@@ -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
index eab9bbf56d21bf0f0460473ce9bcf2a2b6f40f74..f5fd3960691ea0190b722a019ed5b5dba84e9cf4 100644 (file)
@@ -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;
+}
+
+
+
index 90fc7bf20e2fb5d7a918240c450dcddbf829bc0a..1066db70110ff33210fb2460a5360f3b25c63aa6 100644 (file)
@@ -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
index 0175f0e7b2e5b7dc27b50874b0ea0c3c0f3d7d2c..60ba208a4faec2581d6abac2e82207c4163fe9e8 100644 (file)
 
 #include <config.h>
 
+#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 <boost/assert.hpp>
 
 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;
 }
index c421f567406faf0a3c36640aad45021d8de88b90..0e1dd01a901e277f4887228ccd02c7904428e792 100644 (file)
@@ -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);
 }
 
 
index 9821af99e953ddc5b32cf42f0fcb23759112474a..a9eb292e9deee4ae6349e4a0ef5329f3ab6b9948 100644 (file)
@@ -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?
 }
 
 
index a2f7b01560edd8fdda0efa344bdb3c78a0f17011..8f1c0b67991de48cd63deaa76230b29920fe31c8 100644 (file)
@@ -57,7 +57,7 @@
 #include "support/std_sstream.h"
 
 #include "mathed/math_hullinset.h"
-#include "mathed/formulamacro.h"
+#include "mathed/math_macrotemplate.h"
 
 #include <clocale>
 
@@ -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;