]> git.lyx.org Git - features.git/commitdiff
Fix HTML output of \gg, \ll and \ne (bug #9372)
authorGeorg Baum <baum@lyx.org>
Tue, 30 Dec 2014 12:39:52 +0000 (13:39 +0100)
committerGeorg Baum <baum@lyx.org>
Tue, 30 Dec 2014 12:39:52 +0000 (13:39 +0100)
The fix consists of three parts: The fix for \ll and \gg, the needed
infrastructure to assign HTML entities to global math macros, and the actual
fix for \ne and \neq.

lib/symbols
src/mathed/InsetMathNest.cpp
src/mathed/InsetMathSymbol.cpp
src/mathed/MacroTable.cpp
src/mathed/MacroTable.h
src/mathed/MathFactory.cpp
src/mathed/MathMacro.cpp
src/mathed/MathParser.cpp
src/mathed/MathParser.h
status.21x

index 2b5aea2febda97964281a37cbf2358a8d72ff531..b9b21b945c77b1b6a5c9a905f7272100c4511492 100644 (file)
@@ -289,7 +289,7 @@ diamondsuit        cmsy        125 168 mathord  &#x2662;
 heartsuit          cmsy        126 169 mathord  &#x2661;
 spadesuit          cmsy        127 170 mathord  &spades;
 # We define lyxnot as mathrel in order to have proper alignment
-lyxnot             cmsy         54  47 mathrel  &ssetmn;
+lyxnot             cmsy         54  47 mathrel  /
 iffont cmsy
 # 9mu = 0.5em which is the extra space added to relation operators
 \def\not{\lyxnot\kern-9mu}
@@ -373,8 +373,8 @@ subseteq           cmsy        181 205 mathrel  &sube;
 in                 cmsy         50 206 mathrel  &isin;
 ni                 cmsy         51  39 mathrel  &ni;
 owns               cmsy         51  39 mathrel  &ni;
-gg                 cmsy        192   0 mathrel  &gt;
-ll                 cmsy        191   0 mathrel  &lt;
+gg                 cmsy        192   0 mathrel  &gg;
+ll                 cmsy        191   0 mathrel  &ll;
 leftrightarrow     cmsy         36 171 mathrel  &harr;
 leftarrow          cmsy        195 172 mathrel  &larr;
 gets               cmsy        195 172 mathrel  &larr;
@@ -1120,8 +1120,8 @@ pod                lyxblacktext  0   0 func     x     amsmath
 # pre-defined macros
 #
 
-\def\neq{\not=}
-\def\ne{\not=}
+\def\neq{\not=}                                                 mathrel &ne;
+\def\ne{\not=}                                                  mathrel &ne;
 \def\notin{\not\in}
 \def\slash{/}
 
index 83e49c43b824b77263e36f436f7126f32ebcf017..2e32bbb0ac3328a9ddbdb2b7577ae0d60f8aca24 100644 (file)
@@ -1029,7 +1029,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_REGEXP_MODE: {
                InsetMath * im = cur.inset().asInsetMath();
                if (im) {
-                       InsetMathHull * i = im->asHullInset();          
+                       InsetMathHull * i = im->asHullInset();
                        if (i && i->getType() == hullRegexp) {
                                cur.message(_("Already in regular expression mode"));
                                break;
@@ -1092,7 +1092,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                        && name != "Bmatrix" && name != "vmatrix"
                        && name != "Vmatrix" && name != "matrix")
                        name = from_ascii("matrix");
-               
+
                cur.niceInsert(
                        MathAtom(new InsetMathAMSArray(buffer_, name, m, n)));
                break;
@@ -1279,7 +1279,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
                        cur.recordUndoSelection();
                        cur.insert(ar);
-                       cur.forceBufferUpdate();                        
+                       cur.forceBufferUpdate();
                } else
                        cur.undispatched();
                break;
@@ -1455,7 +1455,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_CAPTION_INSERT:
                flag.setEnabled(false);
                break;
-       
+
        case LFUN_SPACE_INSERT: {
                docstring const & name = cmd.argument();
                if (name == "visible")
@@ -1635,9 +1635,8 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                }
 
                // do not finish macro for known * commands
-               MathWordList const & mwl = mathedWordList();
                bool star_macro = c == '*'
-                       && (mwl.find(name.substr(1) + "*") != mwl.end()
+                       && (in_word_set(name.substr(1) + '*')
                            || cur.buffer()->getMacro(name.substr(1) + "*", cur, true));
                if (isAlphaASCII(c) || star_macro) {
                        cur.activeMacro()->setName(name + docstring(1, c));
@@ -1730,7 +1729,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                cur.autocorrect() = false;
                cur.message(_("Autocorrect Off ('!' to enter)"));
                return true;
-       } 
+       }
        if (lyxrc.autocorrection_math && c == '!' && !cur.autocorrect()) {
                cur.autocorrect() = true;
                cur.message(_("Autocorrect On (<space> to exit)"));
@@ -2183,8 +2182,11 @@ MathCompletionList::MathCompletionList(Cursor const & cur)
        MathWordList::const_iterator it2;
        //lyxerr << "Globals completion commands: ";
        for (it2 = words.begin(); it2 != words.end(); ++it2) {
-               globals.push_back("\\" + (*it2).first);
-               //lyxerr << "\\" + (*it2).first << " ";
+               if (it2->second.inset != "macro") {
+                       // macros are already read from MacroTable::globalMacros()
+                       globals.push_back('\\' + it2->first);
+                       //lyxerr << '\\' + it2->first << ' ';
+               }
        }
        //lyxerr << std::endl;
        sort(globals.begin(), globals.end());
index 1999846729868998005b1f628e392481e63257d1..97c7aea1b66baf85b0d57b3a32bee24c454fb829 100644 (file)
@@ -185,22 +185,13 @@ void InsetMathSymbol::mathematica(MathematicaStream & os) const
 }
 
 
-// FIXME This will likely need some work.
-char const * MathMLtype(docstring const & s)
-{
-       if (s == "mathord")
-               return "mi";
-       return "mo";
-}
-
-
 void InsetMathSymbol::mathmlize(MathStream & os) const
 {
-       // FIXME We may need to do more interesting things 
+       // FIXME We may need to do more interesting things
        // with MathMLtype.
-       char const * type = MathMLtype(sym_->extra);
+       char const * type = sym_->MathMLtype();
        os << '<' << type << "> ";
-       if (sym_->xmlname == "x") 
+       if (sym_->xmlname == "x")
                // unknown so far
                os << name();
        else
@@ -211,15 +202,15 @@ void InsetMathSymbol::mathmlize(MathStream & os) const
 
 void InsetMathSymbol::htmlize(HtmlStream & os, bool spacing) const
 {
-       // FIXME We may need to do more interesting things 
+       // FIXME We may need to do more interesting things
        // with MathMLtype.
-       char const * type = MathMLtype(sym_->extra);
+       char const * type = sym_->MathMLtype();
        bool op = (std::string(type) == "mo");
-       
-       if (sym_->xmlname == "x") 
+
+       if (sym_->xmlname == "x")
                // unknown so far
                os << ' ' << name() << ' ';
-       else if (op && spacing) 
+       else if (op && spacing)
                os << ' ' << sym_->xmlname << ' ';
        else
                os << sym_->xmlname;
index 4af30d4c5438c25e0d3e332b3223a49471dc6237..3ac42929b60cd685ddaacf4917a71ea381c66b07 100644 (file)
@@ -14,6 +14,7 @@
 #include "MacroTable.h"
 #include "MathMacroTemplate.h"
 #include "MathMacroArgument.h"
+#include "MathParser.h"
 #include "MathStream.h"
 #include "MathSupport.h"
 #include "InsetMathNest.h"
@@ -41,13 +42,13 @@ namespace lyx {
 /////////////////////////////////////////////////////////////////////
 
 MacroData::MacroData(Buffer * buf)
-       : buffer_(buf), queried_(true), numargs_(0), optionals_(0), lockCount_(0),
-         redefinition_(false), type_(MacroTypeNewcommand)
+       : buffer_(buf), queried_(true), numargs_(0), sym_(0), optionals_(0),
+         lockCount_(0), redefinition_(false), type_(MacroTypeNewcommand)
 {}
 
 
 MacroData::MacroData(Buffer * buf, DocIterator const & pos)
-       : buffer_(buf), pos_(pos), queried_(false), numargs_(0),
+       : buffer_(buf), pos_(pos), queried_(false), numargs_(0), sym_(0),
          optionals_(0), lockCount_(0), redefinition_(false),
          type_(MacroTypeNewcommand)
 {
@@ -55,8 +56,8 @@ MacroData::MacroData(Buffer * buf, DocIterator const & pos)
 
 
 MacroData::MacroData(Buffer * buf, MathMacroTemplate const & macro)
-       : buffer_(buf), queried_(false), numargs_(0), optionals_(0), lockCount_(0),
-         redefinition_(false), type_(MacroTypeNewcommand)
+       : buffer_(buf), queried_(false), numargs_(0), sym_(0), optionals_(0),
+         lockCount_(0), redefinition_(false), type_(MacroTypeNewcommand)
 {
        queryData(macro);
 }
@@ -110,6 +111,28 @@ vector<docstring> const & MacroData::defaults() const
 }
 
 
+string const MacroData::requires() const
+{
+       if (sym_)
+               return to_utf8(sym_->requires);
+       return string();
+}
+
+
+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_;
@@ -210,12 +233,11 @@ MacroTable::insert(docstring const & name, MacroData const & data)
 
 
 MacroTable::iterator
-MacroTable::insert(Buffer * buf, docstring const & def, string const & requires)
+MacroTable::insert(Buffer * buf, docstring const & def)
 {
        //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl;
        MathMacroTemplate mac(buf, def);
        MacroData data(buf, mac);
-       data.requires() = requires;
        return insert(mac.name(), data);
 }
 
index 0f9f60dc41b74f8a67301f555fba3296cda6aafe..97029a3df00f52a004026668597d952cb63f5ce4 100644 (file)
@@ -27,6 +27,7 @@ class Buffer;
 class MathData;
 class MathMacroTemplate;
 class Paragraph;
+class latexkeys;
 
 enum MacroType {
        MacroTypeNewcommand,
@@ -59,9 +60,13 @@ public:
        ///
        std::vector<docstring> const & defaults() const;
        ///
-       std::string const & requires() const { return requires_; }
+       std::string const requires() const;
        ///
-       std::string & requires() { return requires_; }
+       docstring const xmlname() const;
+       ///
+       char const * MathMLtype() const;
+       ///
+       void setSymbol(latexkeys const * sym) { sym_ = sym; }
 
        /// lock while being drawn to avoid recursions
        int lock() const { return ++lockCount_; }
@@ -86,7 +91,7 @@ public:
                return definition_ == x.definition_
                        && numargs_ == x.numargs_
                        && display_ == x.display_
-                       && requires_ == x.requires_
+                       && sym_ == x.sym_
                        && optionals_ == x.optionals_
                        && defaults_ == x.defaults_;
        }
@@ -118,7 +123,7 @@ private:
        ///
        mutable docstring display_;
        ///
-       std::string requires_;
+       latexkeys const * sym_;
        ///
        mutable size_t optionals_;
        ///
@@ -149,7 +154,7 @@ class MacroTable : public std::map<docstring, MacroData>
 {
 public:
        /// Parse full "\\def..." or "\\newcommand..." or ...
-       iterator insert(Buffer * buf, docstring const & definition, std::string const &);
+       iterator insert(Buffer * buf, docstring const & definition);
        /// Insert pre-digested macro definition
        iterator insert(docstring const & name, MacroData const & data);
        ///
index 961e70e9f459250191b717d16e5d228d006c76b1..f4c5773c7a2fa19cfad3c4de8ea4ba132c4ab005 100644 (file)
@@ -175,18 +175,50 @@ void initSymbols()
                // special case of pre-defined macros
                if (line.size() > 8 && line.substr(0, 5) == "\\def\\") {
                        //lyxerr << "macro definition: '" << line << '\'' << endl;
+                       // syntax: Either
+                       // \def\macroname{definition}
+                       // or
+                       // \def\macroname{definition} requires
+                       // or
+                       // \def\macroname{definition} extra xmlname requires
                        istringstream is(line);
                        string macro;
                        string requires;
+                       string extra;
+                       string xmlname;
                        is >> macro >> requires;
+                       if ((is >> xmlname)) {
+                               extra = requires;
+                               if (!(is >> requires))
+                                       requires = "";
+                       } else
+                               xmlname = "";
                        MacroTable::iterator it = MacroTable::globalMacros().insert(
-                                       0, from_utf8(macro), requires);
+                                       0, from_utf8(macro));
+                       if (!extra.empty() || !xmlname.empty() || !requires.empty()) {
+                               MathWordList::iterator wit = theMathWordList.find(it->first);
+                               if (wit != theMathWordList.end())
+                                       LYXERR(Debug::MATHED, "readSymbols: inset "
+                                               << to_utf8(it->first) << " already exists.");
+                               else {
+                                       latexkeys tmp;
+                                       tmp.inset = from_ascii("macro");
+                                       tmp.name = it->first;
+                                       tmp.extra = from_utf8(extra);
+                                       tmp.xmlname = from_utf8(xmlname);
+                                       tmp.requires = from_utf8(requires);
+                                       theMathWordList[it->first] = tmp;
+                                       wit = theMathWordList.find(it->first);
+                                       it->second.setSymbol(&(wit->second));
+                               }
+                       }
                        // If you change the following output, please adjust
                        // development/tools/generate_symbols_images.py.
                        LYXERR(Debug::MATHED, "read symbol '" << to_utf8(it->first)
                                << "  inset: macro"
                                << "  draw: 0"
-                               << "  extra: "
+                               << "  extra: " << extra
+                               << "  xml: " << xmlname
                                << "  requires: " << requires << '\'');
                        continue;
                }
@@ -270,6 +302,7 @@ void initSymbols()
                        << "  inset: " << to_utf8(tmp.inset)
                        << "  draw: " << int(tmp.draw.empty() ? 0 : tmp.draw[0])
                        << "  extra: " << to_utf8(tmp.extra)
+                       << "  xml: " << to_utf8(tmp.xmlname)
                        << "  requires: " << to_utf8(tmp.requires) << '\'');
        }
        docstring tmp = from_ascii("cmm");
@@ -354,7 +387,11 @@ int ensureMode(WriteStream & os, InsetMath::mode_type mode,
 latexkeys const * in_word_set(docstring const & str)
 {
        MathWordList::iterator it = theMathWordList.find(str);
-       return it != theMathWordList.end() ? &(it->second) : 0;
+       if (it == theMathWordList.end())
+               return 0;
+       if (it->second.inset == "macro")
+               return 0;
+       return &(it->second);
 }
 
 
index 941e29aee2437585e93ce815f29b77500017b258..745b12bcf5ca632924c7bba8e1e7c35b4ef6b3fd 100644 (file)
@@ -52,11 +52,11 @@ namespace lyx {
 class ArgumentProxy : public InsetMath {
 public:
        ///
-       ArgumentProxy(MathMacro & mathMacro, size_t idx) 
+       ArgumentProxy(MathMacro & mathMacro, size_t idx)
                : mathMacro_(mathMacro), idx_(idx) {}
        ///
-       ArgumentProxy(MathMacro & mathMacro, size_t idx, docstring const & def) 
-               : mathMacro_(mathMacro), idx_(idx) 
+       ArgumentProxy(MathMacro & mathMacro, size_t idx, docstring const & def)
+               : mathMacro_(mathMacro), idx_(idx)
        {
                        asArray(def, def_);
        }
@@ -81,13 +81,13 @@ public:
        ///
        void draw(PainterInfo & pi, int x, int y) const {
                if (mathMacro_.editMetrics(pi.base.bv)) {
-                       // The only way a ArgumentProxy can appear is in a cell of the 
-                       // MathMacro. Moreover the cells are only drawn in the DISPLAY_FOLDED 
-                       // mode and then, if the macro is edited the monochrome 
+                       // The only way a ArgumentProxy can appear is in a cell of the
+                       // MathMacro. Moreover the cells are only drawn in the DISPLAY_FOLDED
+                       // mode and then, if the macro is edited the monochrome
                        // mode is entered by the MathMacro before calling the cells' draw
                        // method. Then eventually this code is reached and the proxy leaves
-                       // monochrome mode temporarely. Hence, if it is not in monochrome 
-                       // here (and the assert triggers in pain.leaveMonochromeMode()) 
+                       // monochrome mode temporarely. Hence, if it is not in monochrome
+                       // here (and the assert triggers in pain.leaveMonochromeMode())
                        // it's a bug.
                        pi.pain.leaveMonochromeMode();
                        mathMacro_.cell(idx_).draw(pi, x, y);
@@ -102,17 +102,17 @@ public:
        size_t idx() const { return idx_; }
        ///
        int kerning(BufferView const * bv) const
-       { 
+       {
                if (mathMacro_.editMetrics(bv)
                    || !mathMacro_.cell(idx_).empty())
-                       return mathMacro_.cell(idx_).kerning(bv); 
+                       return mathMacro_.cell(idx_).kerning(bv);
                else
                        return def_.kerning(bv);
        }
 
 private:
        ///
-       Inset * clone() const 
+       Inset * clone() const
        {
                return new ArgumentProxy(*this);
        }
@@ -215,7 +215,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
                dim.asc = max(bsdim.ascent(), dim.ascent());
                dim.des = max(bsdim.descent(), dim.descent());
                metricsMarkers(dim);
-       } else if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST 
+       } else if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST
                   && editing_[mi.base.bv]) {
                // Macro will be edited in a old-style list mode here:
 
@@ -223,7 +223,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
                Dimension fontDim;
                FontInfo labelFont = sane_font;
                math_font_max_dim(labelFont, fontDim.asc, fontDim.des);
-               
+
                // get dimension of components of list view
                Dimension nameDim;
                nameDim.wid = mathed_string_width(mi.base.font, from_ascii("Macro \\") + name() + ": ");
@@ -234,22 +234,22 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
                argDim.wid = mathed_string_width(labelFont, from_ascii("#9: "));
                argDim.asc = fontDim.asc;
                argDim.des = fontDim.des;
-               
+
                Dimension defDim;
                definition_.metrics(mi, defDim);
-               
+
                // add them up
                dim.wid = nameDim.wid + defDim.wid;
                dim.asc = max(nameDim.asc, defDim.asc);
                dim.des = max(nameDim.des, defDim.des);
-               
+
                for (idx_type i = 0; i < nargs(); ++i) {
                        Dimension cdim;
                        cell(i).metrics(mi, cdim);
                        dim.des += max(argDim.height(), cdim.height()) + 1;
                        dim.wid = max(dim.wid, argDim.wid + cdim.wid);
                }
-               
+
                // make space for box and markers, 2 pixels
                dim.asc += 1;
                dim.des += 1;
@@ -273,7 +273,7 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
                macro_->unlock();
 
                // calculate dimension with label while editing
-               if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX 
+               if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX
                    && editing_[mi.base.bv]) {
                        FontInfo font = mi.base.font;
                        augmentFont(font, from_ascii("lyxtex"));
@@ -288,7 +288,6 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const
                        dim.asc += 1 + namedim.height() + 1;
                        dim.des += 2;
                }
-        
        }
 }
 
@@ -301,10 +300,10 @@ int MathMacro::kerning(BufferView const * bv) const {
 }
 
 
-void MathMacro::updateMacro(MacroContext const & mc) 
+void MathMacro::updateMacro(MacroContext const & mc)
 {
        if (validName()) {
-               macro_ = mc.get(name());    
+               macro_ = mc.get(name());
                if (macro_ && macroBackup_ != *macro_) {
                        macroBackup_ = *macro_;
                        needsUpdate_ = true;
@@ -343,22 +342,22 @@ void MathMacro::updateRepresentation(Cursor * cur, MacroContext const & mc,
 
        // update requires
        requires_ = macro_->requires();
-       
+
        if (!needsUpdate_
                // non-normal mode? We are done!
                || (displayMode_ != DISPLAY_NORMAL))
                return;
 
        needsUpdate_ = false;
-       
+
        // get default values of macro
        vector<docstring> const & defaults = macro_->defaults();
-       
+
        // create MathMacroArgumentValue objects pointing to the cells of the macro
        vector<MathData> values(nargs());
        for (size_t i = 0; i < nargs(); ++i) {
                ArgumentProxy * proxy;
-               if (i < defaults.size()) 
+               if (i < defaults.size())
                        proxy = new ArgumentProxy(*this, i, defaults[i]);
                else
                        proxy = new ArgumentProxy(*this, i);
@@ -388,7 +387,7 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
        int expx = x;
        int expy = y;
 
-       if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_INTERACTIVE_INIT) {         
+       if (displayMode_ == DISPLAY_INIT || displayMode_ == DISPLAY_INTERACTIVE_INIT) {
                FontSetChanger dummy(pi.base, "lyxtex");
                pi.pain.text(x, y, from_ascii("\\") + name(), pi.base.font);
        } else if (displayMode_ == DISPLAY_UNFOLDED) {
@@ -400,17 +399,17 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
        } else if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST
                   && editing_[pi.base.bv]) {
                // Macro will be edited in a old-style list mode here:
-               
+
                CoordCache const & coords = pi.base.bv->coordCache();
                FontInfo const & labelFont = sane_font;
-               
+
                // markers and box needs two pixels
                x += 2;
-               
+
                // get maximal font height
                Dimension fontDim;
                math_font_max_dim(pi.base.font, fontDim.asc, fontDim.des);
-               
+
                // draw label
                docstring label = from_ascii("Macro \\") + name() + from_ascii(": ");
                pi.pain.text(x, y, label, labelFont);
@@ -420,38 +419,38 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
                definition_.draw(pi, x, y);
                Dimension const & defDim = coords.getArrays().dim(&definition_);
                y += max(fontDim.des, defDim.des);
-                               
+
                // draw parameters
                docstring str = from_ascii("#9");
                int strw1 = mathed_string_width(labelFont, from_ascii("#9"));
                int strw2 = mathed_string_width(labelFont, from_ascii(": "));
-               
+
                for (idx_type i = 0; i < nargs(); ++i) {
                        // position of label
                        Dimension const & cdim = coords.getArrays().dim(&cell(i));
                        x = expx + 2;
                        y += max(fontDim.asc, cdim.asc) + 1;
-                       
+
                        // draw label
                        str[1] = '1' + i;
                        pi.pain.text(x, y, str, labelFont);
                        x += strw1;
                        pi.pain.text(x, y, from_ascii(":"), labelFont);
                        x += strw2;
-                       
+
                        // draw paramter
                        cell(i).draw(pi, x, y);
-                       
+
                        // next line
                        y += max(fontDim.des, cdim.des);
                }
-               
-               pi.pain.rectangle(expx + 1, expy - dim.asc + 1, dim.wid - 3, 
+
+               pi.pain.rectangle(expx + 1, expy - dim.asc + 1, dim.wid - 3,
                                  dim.height() - 2, Color_mathmacroframe);
                drawMarkers2(pi, expx, expy);
        } else {
                bool drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX;
-               
+
                // warm up cells
                for (size_t i = 0; i < nargs(); ++i)
                        cell(i).setXY(*pi.base.bv, x, y);
@@ -476,7 +475,7 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const
                        pi.pain.leaveMonochromeMode();
 
                        if (drawBox)
-                               pi.pain.rectangle(x, y - dim.asc, dim.wid, 
+                               pi.pain.rectangle(x, y - dim.asc, dim.wid,
                                                  dim.height(), Color_mathmacroframe);
                } else
                        expanded_.cell(0).draw(pi, expx, expy);
@@ -501,7 +500,7 @@ void MathMacro::drawSelection(PainterInfo & pi, int x, int y) const
 
 void MathMacro::setDisplayMode(MathMacro::DisplayMode mode, int appetite)
 {
-       if (displayMode_ != mode) {             
+       if (displayMode_ != mode) {
                // transfer name if changing from or to DISPLAY_UNFOLDED
                if (mode == DISPLAY_UNFOLDED) {
                        cells_.resize(1);
@@ -514,7 +513,7 @@ void MathMacro::setDisplayMode(MathMacro::DisplayMode mode, int appetite)
                displayMode_ = mode;
                needsUpdate_ = true;
        }
-       
+
        // the interactive init mode is non-greedy by default
        if (appetite == -1)
                appetite_ = (mode == DISPLAY_INTERACTIVE_INIT) ? 0 : 9;
@@ -549,7 +548,7 @@ bool MathMacro::validName() const
        for (size_t i = 0; i<n.size(); ++i) {
                if (!(n[i] >= 'a' && n[i] <= 'z')
                    && !(n[i] >= 'A' && n[i] <= 'Z')
-                   && n[i] != '*') 
+                   && n[i] != '*')
                        return false;
        }
 
@@ -564,7 +563,7 @@ void MathMacro::validate(LaTeXFeatures & features) const
 
        if (name() == "binom")
                features.require("binom");
-       
+
        // validate the cells and the definition
        if (displayMode() == DISPLAY_NORMAL) {
                definition_.validate(features);
@@ -585,7 +584,7 @@ Inset * MathMacro::editXY(Cursor & cur, int x, int y)
        // We may have 0 arguments, but InsetMathNest requires at least one.
        if (nargs() > 0) {
                cur.screenUpdateFlags(Update::SinglePar);
-               return InsetMathNest::editXY(cur, x, y);                
+               return InsetMathNest::editXY(cur, x, y);
        } else
                return this;
 }
@@ -654,14 +653,14 @@ void MathMacro::attachArguments(vector<MathData> const & args, size_t arity, int
 }
 
 
-bool MathMacro::idxFirst(Cursor & cur) const 
+bool MathMacro::idxFirst(Cursor & cur) const
 {
        cur.screenUpdateFlags(Update::SinglePar);
        return InsetMathNest::idxFirst(cur);
 }
 
 
-bool MathMacro::idxLast(Cursor & cur) const 
+bool MathMacro::idxLast(Cursor & cur) const
 {
        cur.screenUpdateFlags(Update::SinglePar);
        return InsetMathNest::idxLast(cur);
@@ -738,10 +737,10 @@ void MathMacro::write(WriteStream & os) const
        // Always protect macros in a fragile environment
        if (os.fragile())
                os << "\\protect";
-       
+
        os << "\\" << name();
        bool first = true;
-       
+
        // Optional arguments:
        // First find last non-empty optional argument
        idx_type emptyOptFrom = 0;
@@ -750,19 +749,19 @@ void MathMacro::write(WriteStream & os) const
                if (!cell(i).empty())
                        emptyOptFrom = i + 1;
        }
-       
+
        // print out optionals
        for (i=0; i < cells_.size() && i < emptyOptFrom; ++i) {
                first = false;
                os << "[" << cell(i) << "]";
        }
-       
+
        // skip the tailing empty optionals
        i = optionals_;
-       
+
        // Print remaining arguments
        for (; i < cells_.size(); ++i) {
-               if (cell(i).size() == 1 
+               if (cell(i).size() == 1
                        && cell(i)[0].nucleus()->asCharInset()
                        && isASCII(cell(i)[0].nucleus()->asCharInset()->getChar())) {
                        if (first)
@@ -787,6 +786,16 @@ void MathMacro::maple(MapleStream & os) const
 
 void MathMacro::mathmlize(MathStream & os) const
 {
+       LATTEST(macro_);
+       if (macro_) {
+               docstring const xmlname = macro_->xmlname();
+               if (!xmlname.empty()) {
+                       char const * type = macro_->MathMLtype();
+                       os << '<' << type << "> " << xmlname << " /<"
+                          << type << '>';
+                       return;
+               }
+       }
        MathData const & data = expanded_.cell(0);
        if (data.empty()) {
                // this means that we do not recognize the macro
@@ -798,6 +807,14 @@ void MathMacro::mathmlize(MathStream & os) const
 
 void MathMacro::htmlize(HtmlStream & os) const
 {
+       LATTEST(macro_);
+       if (macro_) {
+               docstring const xmlname = macro_->xmlname();
+               if (!xmlname.empty()) {
+                       os << ' ' << xmlname << ' ';
+                       return;
+               }
+       }
        MathData const & data = expanded_.cell(0);
        if (data.empty()) {
                // this means that we do not recognize the macro
@@ -865,7 +882,7 @@ bool MathMacro::automaticPopupCompletion() const
 }
 
 
-CompletionList const * 
+CompletionList const *
 MathMacro::createCompletionList(Cursor const & cur) const
 {
        if (displayMode() != DISPLAY_UNFOLDED)
@@ -882,7 +899,7 @@ docstring MathMacro::completionPrefix(Cursor const & cur) const
 
        if (!completionSupported(cur))
                return docstring();
-       
+
        return "\\" + name();
 }
 
@@ -901,14 +918,14 @@ bool MathMacro::insertCompletion(Cursor & cur, docstring const & s,
        asArray(newName, cell(0));
        cur.bv().cursor().pos() = name().size();
        cur.screenUpdateFlags(Update::SinglePar);
-       
+
        // finish macro
        if (finished) {
                cur.bv().cursor().pop();
                ++cur.bv().cursor().pos();
                cur.screenUpdateFlags(Update::SinglePar);
        }
-       
+
        return true;
 }
 
@@ -918,14 +935,14 @@ void MathMacro::completionPosAndDim(Cursor const & cur, int & x, int & y,
 {
        if (displayMode() != DISPLAY_UNFOLDED)
                InsetMathNest::completionPosAndDim(cur, x, y, dim);
-       
+
        // get inset dimensions
        dim = cur.bv().coordCache().insets().dim(this);
        // FIXME: these 3 are no accurate, but should depend on the font.
        // Now the popup jumps down if you enter a char with descent > 0.
        dim.des += 3;
        dim.asc += 3;
-       
+
        // and position
        Point xy
        = cur.bv().coordCache().insets().xy(this);
index 1c7f2ff0ad3abc79a452d187f29378c3eb4d7a15..e740d23db84eb6ea443e56195ed5984a598c3f1a 100644 (file)
@@ -1039,10 +1039,10 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                         t.cs() == "def") {
                        if (t.cs() == "global")
                                getToken();
-                       
+
                        // get name
                        docstring name = getToken().cs();
-                       
+
                        // read parameters
                        int nargs = 0;
                        docstring pars;
@@ -1051,17 +1051,17 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                ++nargs;
                        }
                        nargs /= 2;
-                       
+
                        // read definition
                        MathData def;
                        parse(def, FLAG_ITEM, InsetMath::UNDECIDED_MODE);
-                       
+
                        // is a version for display attached?
                        skipSpaces();
                        MathData display;
                        if (nextToken().cat() == catBegin)
                                parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
-                       
+
                        cell->push_back(MathAtom(new MathMacroTemplate(buf,
                                name, nargs, 0, MacroTypeDef,
                                vector<MathData>(), def, display)));
@@ -1069,7 +1069,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        if (buf && (mode_ & Parse::TRACKMACRO))
                                buf->usermacros.insert(name);
                }
-               
+
                else if (t.cs() == "newcommand" ||
                         t.cs() == "renewcommand" ||
                         t.cs() == "newlyxcommand") {
@@ -1083,13 +1083,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                error("'}' in \\newcommand expected");
                                return success_;
                        }
-                               
+
                        // get arity
                        docstring const arg = getArg('[', ']');
                        int nargs = 0;
                        if (!arg.empty())
                                nargs = convert<int>(arg);
-                               
+
                        // optional argument given?
                        skipSpaces();
                        int optionals = 0;
@@ -1100,16 +1100,16 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                parse(optionalValues[optionals], FLAG_BRACK_LAST, mode);
                                ++optionals;
                        }
-                       
+
                        MathData def;
                        parse(def, FLAG_ITEM, InsetMath::UNDECIDED_MODE);
-                       
+
                        // is a version for display attached?
                        skipSpaces();
                        MathData display;
                        if (nextToken().cat() == catBegin)
                                parse(display, FLAG_ITEM, InsetMath::MATH_MODE);
-                       
+
                        cell->push_back(MathAtom(new MathMacroTemplate(buf,
                                name, nargs, optionals, MacroTypeNewcommand,
                                optionalValues, def, display)));
@@ -1117,7 +1117,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                        if (buf && (mode_ & Parse::TRACKMACRO))
                                buf->usermacros.insert(name);
                }
-               
+
                else if (t.cs() == "newcommandx" ||
                         t.cs() == "renewcommandx") {
                        // \newcommandx{\foo}[2][usedefault, addprefix=\global,1=default]{#1,#2}
@@ -1132,7 +1132,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                }
                        } else
                                name = getToken().cs();
-                               
+
                        // get arity
                        docstring const arg = getArg('[', ']');
                        if (arg.empty()) {
@@ -1140,14 +1140,14 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                return success_;
                        }
                        int nargs = convert<int>(arg);
-                       
+
                        // get options
                        int optionals = 0;
                        vector<MathData> optionalValues;
                        if (nextToken().character() == '[') {
                                // skip '['
                                getToken();
-                                       
+
                                // handle 'opt=value' options, separated by ','.
                                skipSpaces();
                                while (nextToken().character() != ']' && good()) {
@@ -1160,14 +1160,14 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                                              "for given optional parameter.");
                                                        return success_;
                                                }
-                                               
+
                                                // skip '='
                                                if (getToken().character() != '=') {
                                                        error("'=' and optional parameter value "
                                                              "expected for \\newcommandx");
                                                        return success_;
                                                }
-                                               
+
                                                // get value
                                                int optNum = max(size_t(n), optionalValues.size());
                                                optionalValues.resize(optNum);
@@ -1182,12 +1182,12 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                        } else if (nextToken().cat() == catLetter) {
                                                // we in fact ignore every non-optional
                                                // parameter
-                                               
+
                                                // get option name
                                                docstring opt;
                                                while (nextToken().cat() == catLetter)
                                                        opt += getChar();
-                                       
+
                                                // value?
                                                skipSpaces();
                                                MathData value;
@@ -1195,14 +1195,14 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                                        getToken();
                                                        while (nextToken().character() != ']'
                                                                && nextToken().character() != ',')
-                                                               parse(value, FLAG_ITEM, 
+                                                               parse(value, FLAG_ITEM,
                                                                      InsetMath::UNDECIDED_MODE);
                                                }
                                        } else {
                                                error("option for \\newcommandx expected");
                                                return success_;
                                        }
-                                       
+
                                        // skip komma
                                        skipSpaces();
                                        if (nextToken().character() == ',') {
@@ -1214,7 +1214,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                                                return success_;
                                        }
                                }
-                               
+
                                // skip ']'
                                if (!good())
                                        return success_;
@@ -1434,7 +1434,7 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
                else if (t.cs() == "cfrac") {
                        // allowed formats are \cfrac[pos]{num}{denom}
                        docstring const arg = getArg('[', ']');
-                       //lyxerr << "got so far: '" << arg << "'" << endl;                              
+                       //lyxerr << "got so far: '" << arg << "'" << endl;
                                if (arg == "l")
                                        cell->push_back(MathAtom(new InsetMathFrac(buf, InsetMathFrac::CFRACLEFT)));
                                else if (arg == "r")
@@ -1534,13 +1534,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 
                else if (t.cs() == "begin") {
                        docstring const name = getArg('{', '}');
-                       
+
                        if (name.empty()) {
                                success_ = false;
                                error("found invalid environment");
                                return success_;
                        }
-                       
+
                        environments_.push_back(name);
 
                        if (name == "array" || name == "subarray") {
@@ -2089,6 +2089,15 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
 } // anonymous namespace
 
 
+// FIXME This will likely need some work.
+char const * latexkeys::MathMLtype() const
+{
+       if (extra == "mathord")
+               return "mi";
+       return "mo";
+}
+
+
 bool mathed_parse_cell(MathData & ar, docstring const & str, Parse::flags f)
 {
        return Parser(str, f, ar.buffer()).parse(ar, 0, f & Parse::TEXTMODE ?
index 745b038d2a58af88868b639deee38f20e913ab82..63e1be259805ba96de904448c572a9a023d715fb 100644 (file)
@@ -30,6 +30,8 @@ class Lexer;
 ///
 class latexkeys {
 public:
+       ///
+       char const * MathMLtype() const;
        /// name of the macro or primitive
        docstring name;
        /// name of a inset that handles that macro
index cfe41f8ff8f05264300f96ad44a588d2bcf761a2..d83eb4b660917ab5f19b227945cd00a9a6aa1035 100644 (file)
@@ -176,6 +176,8 @@ What's new
 
 * LYXHTML
 
+- Fix export of \ll, \gg, \ne and \neq in math formulas (bug 9372).
+
 
 
 * TEX2LYX