X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMacroTable.cpp;h=d279bdb84490c0c0efe4214905f117316babb610;hb=ebe6612e2661f49dcfae6103f056c27afd47751f;hp=7dea5f93413dec02a11f085e437594d96c8b30a5;hpb=9abb7db46800e554f57e865a3e768602ffd9d6f1;p=lyx.git diff --git a/src/mathed/MacroTable.cpp b/src/mathed/MacroTable.cpp index 7dea5f9341..d279bdb844 100644 --- a/src/mathed/MacroTable.cpp +++ b/src/mathed/MacroTable.cpp @@ -3,26 +3,30 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author André Pönitz + * \author André Pönitz * * Full author contact details are available in file CREDITS. */ #include +#include "InsetMathSqrt.h" #include "MacroTable.h" -#include "MathMacroTemplate.h" -#include "MathMacroArgument.h" +#include "InsetMathMacroTemplate.h" +#include "InsetMathMacroArgument.h" +#include "MathParser.h" +#include "MathStream.h" #include "MathSupport.h" -#include "InsetMathSqrt.h" - #include "InsetMathNest.h" -#include "Buffer.h" -#include "support/debug.h" +#include "Buffer.h" #include "DocIterator.h" +#include "InsetList.h" +#include "Text.h" -#include +#include "support/debug.h" +#include "support/gettext.h" +#include "support/lassert.h" #include @@ -37,64 +41,168 @@ namespace lyx { // ///////////////////////////////////////////////////////////////////// -MacroData::MacroData() - : numargs_(0), lockCount_(0), redefinition_(false) +MacroData::MacroData(Buffer * buf) + : buffer_(buf), queried_(true), numargs_(0), sym_(0), optionals_(0), + lockCount_(0), redefinition_(false), type_(MacroTypeNewcommand) {} -MacroData::MacroData(docstring const & definition, - vector const & defaults, - int numargs, int optionals, docstring const & display, - string const & requires) - : definition_(definition), numargs_(numargs), display_(display), - requires_(requires), lockCount_(0), redefinition_(false), - optionals_(optionals), defaults_(defaults) +MacroData::MacroData(Buffer * buf, DocIterator const & pos) + : buffer_(buf), pos_(pos), queried_(false), numargs_(0), sym_(0), + optionals_(0), lockCount_(0), redefinition_(false), + type_(MacroTypeNewcommand) { - defaults_.resize(optionals); } -void MacroData::expand(vector const & args, MathData & to) const +MacroData::MacroData(Buffer * buf, InsetMathMacroTemplate const & macro) + : buffer_(buf), queried_(false), numargs_(0), sym_(0), optionals_(0), + lockCount_(0), redefinition_(false), type_(MacroTypeNewcommand) { - InsetMathSqrt inset; // Hack. Any inset with a cell would do. - // FIXME UNICODE - asArray(display_.empty() ? definition_ : display_, inset.cell(0)); + queryData(macro); +} + + +bool MacroData::expand(vector const & args, MathData & to) const +{ + updateData(); + + // Hack. Any inset with a cell would do. + InsetMathSqrt inset(const_cast(buffer_)); + + docstring const & definition(display_.empty() ? definition_ : display_); + asArray(definition, inset.cell(0), Parse::QUIET | Parse::MACRODEF); //lyxerr << "MathData::expand: args: " << args << endl; - //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl; - for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) { + //LYXERR0("MathData::expand: ar: " << inset.cell(0)); + for (DocIterator it = doc_iterator_begin(buffer_, &inset); it; it.forwardChar()) { if (!it.nextInset()) continue; - if (it.nextInset()->lyxCode() != MATHMACROARG_CODE) + if (it.nextInset()->lyxCode() != MATH_MACROARG_CODE) continue; //it.cell().erase(it.pos()); //it.cell().insert(it.pos(), it.nextInset()->asInsetMath() - size_t n = static_cast(it.nextInset())->number(); + size_t n = static_cast(it.nextInset())->number(); if (n <= args.size()) { it.cell().erase(it.pos()); it.cell().insert(it.pos(), args[n - 1]); } } - //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl; + //LYXERR0("MathData::expand: res: " << inset.cell(0)); to = inset.cell(0); + // If the result is equal to the definition then we either have a + // recursive loop, or the definition did not contain any macro in the + // first place. + return asString(to) != definition; } size_t MacroData::optionals() const { + updateData(); return optionals_; } -vector const & MacroData::defaults() const +vector const & MacroData::defaults() const { + updateData(); return defaults_; } +string const MacroData::requires() const +{ + if (sym_) + return sym_->requires; + return string(); +} + + +bool MacroData::hidden() const +{ + if (sym_) + return sym_->hidden; + return false; +} + + +docstring const MacroData::xmlname() const +{ + if (sym_) + return sym_->xmlname; + return docstring(); +} + + +char const * MacroData::MathMLtype() const +{ + return sym_ ? sym_->MathMLtype() : 0; +} + + void MacroData::unlock() const { --lockCount_; - BOOST_ASSERT(lockCount_ >= 0); + LASSERT(lockCount_ >= 0, lockCount_ = 0); +} + + +void MacroData::queryData(InsetMathMacroTemplate const & macro) const +{ + if (queried_) + return; + + queried_ = true; + definition_ = macro.definition(); + numargs_ = macro.numArgs(); + display_ = macro.displayDefinition(); + redefinition_ = macro.redefinition(); + type_ = macro.type(); + optionals_ = macro.numOptionals(); + + macro.getDefaults(defaults_); +} + + +void MacroData::updateData() const +{ + if (queried_) + return; + + LBUFERR(buffer_); + + // Try to fix position DocIterator. Should not do anything in theory. + pos_.fixIfBroken(); + + // find macro template + Inset * inset = pos_.nextInset(); + if (inset == 0 || inset->lyxCode() != MATHMACRO_CODE) { + lyxerr << "BUG: No macro template found by MacroData" << endl; + return; + } + + // query the data from the macro template + queryData(static_cast(*inset)); +} + + +int MacroData::write(odocstream & os, bool overwriteRedefinition) const +{ + updateData(); + + // find macro template + Inset * inset = pos_.nextInset(); + if (inset == 0 || inset->lyxCode() != MATHMACRO_CODE) { + lyxerr << "BUG: No macro template found by MacroData" << endl; + return 0; + } + + // output template + InsetMathMacroTemplate const & tmpl = + static_cast(*inset); + otexrowstream ots(os); + WriteStream wi(ots, false, true, WriteStream::wsDefault); + return tmpl.write(wi, overwriteRedefinition); } @@ -111,34 +219,43 @@ MacroTable & MacroTable::globalMacros() } -bool MacroTable::has(docstring const & name) const +MacroData const * MacroTable::get(docstring const & name) const { - return find(name) != end(); + const_iterator it = find(name); + return it == end() ? 0 : &it->second; } -MacroData const & MacroTable::get(docstring const & name) const +MacroTable::iterator +MacroTable::insert(docstring const & name, MacroData const & data) { - const_iterator it = find(name); - BOOST_ASSERT(it != end()); - return it->second; + //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl; + iterator it = find(name); + if (it == end()) + it = map::insert( + make_pair(name, data)).first; + else + it->second = data; + return it; } -void MacroTable::insert(docstring const & name, MacroData const & data) +MacroTable::iterator +MacroTable::insert(Buffer * buf, docstring const & def) { - //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl; - operator[](name) = data; + //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl; + InsetMathMacroTemplate mac(buf); + mac.fromString(def); + MacroData data(buf, mac); + return insert(mac.name(), data); } -void MacroTable::insert(docstring const & def, string const & requires) +void MacroTable::getMacroNames(std::set & names, bool gethidden) const { - //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl; - MathMacroTemplate mac(def); - MacroData data = mac.asMacroData(); - data.requires() = requires; - insert(mac.name(), data); + for (const_iterator it = begin(); it != end(); ++it) + if (gethidden || !it->second.hidden()) + names.insert(it->first); } @@ -154,38 +271,21 @@ void MacroTable::dump() } -MacroContext::MacroContext(Buffer const & buf, Paragraph const & par) - : buf_(buf), par_(par) -{ -} - - -bool MacroContext::has(docstring const & name) const -{ - // check if it's a local macro - if (macros_.has(name)) - return true; - - // otherwise ask the buffer - return buf_.hasMacro(name, par_); -} - +///////////////////////////////////////////////////////////////////// +// +// MacroContext +// +///////////////////////////////////////////////////////////////////// -MacroData const & MacroContext::get(docstring const & name) const +MacroContext::MacroContext(Buffer const * buf, DocIterator const & pos) + : buf_(buf), pos_(pos) { - // check if it's a local macro - if (macros_.has(name)) - return macros_.get(name); - - // ask the buffer for its macros - return buf_.getMacro(name, par_); } -void MacroContext::insert(docstring const & name, MacroData const & data) +MacroData const * MacroContext::get(docstring const & name) const { - macros_.insert(name, data); + return buf_->getMacro(name, pos_); } - } // namespace lyx