]> git.lyx.org Git - features.git/commitdiff
Fix bug 5393
authorEnrico Forestieri <forenr@lyx.org>
Thu, 23 Oct 2008 00:48:06 +0000 (00:48 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Thu, 23 Oct 2008 00:48:06 +0000 (00:48 +0000)
http://bugzilla.lyx.org/show_bug.cgi?id=5393

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27044 a592a061-630c-0410-9148-cb99ea01b6c8

development/scons/scons_manifest.py
lib/symbols
src/Makefile.am
src/mathed/InsetMath.h
src/mathed/InsetMathNest.cpp
src/mathed/InsetMathSpecialChar.cpp [new file with mode: 0644]
src/mathed/InsetMathSpecialChar.h [new file with mode: 0644]
src/mathed/MathFactory.cpp
src/mathed/MathMacro.cpp
src/mathed/MathParser.cpp

index 70ca9fe8211ad0bb805f913bb11f0cfdba9e8390..f5471d57745fb4cb4d55739500f08b3f5c5f43ae 100644 (file)
@@ -462,6 +462,7 @@ src_mathed_header_files = Split('''
     InsetMathScript.h
     InsetMathSize.h
     InsetMathSpace.h
+    InsetMathSpecialChar.h
     InsetMathSplit.h
     InsetMathSqrt.h
     InsetMathStackrel.h
@@ -533,6 +534,7 @@ src_mathed_files = Split('''
     InsetMathScript.cpp
     InsetMathSize.cpp
     InsetMathSpace.cpp
+    InsetMathSpecialChar.cpp
     InsetMathSplit.cpp
     InsetMathSqrt.cpp
     InsetMathStackrel.cpp
index f28529c0d023c8863f0a272457944e2c972fd369..66b8be98be9a410247774dd5f7c2463859ba724c 100644 (file)
@@ -865,14 +865,6 @@ gcd                lyxblacktext  0   0 funclim  x
 deg                lyxblacktext  0   0 func     x
 bmod               lyxblacktext  0   0 func     x
 
-{                  mathrm        0   0 special  x
-}                  mathrm        0   0 special  x
-$                  mathrm        0   0 special  x
-%                  mathrm        0   0 special  x
-&                  mathrm        0   0 special  x
-## don't remove the space from the beginning of the next line
- #                 mathrm        0   0 special  x
-
 
 
 #
@@ -912,7 +904,6 @@ endif
 iffont msb
 \def\Join{\ltimes\kern-18.5mu\rtimes}
 endif
-\def\mathcircumflex{\mbox{\^{}}}{\^}
 # Fixme: latin-1 chars in text file
 \def\AA{\AA}{Å}
 \def\O{\O}{Ø}
index 2b00b6733f7eb3b7a7d1f849e970bbe63c2fcba6..a94f6c720c414cd1ccc361352f57b9a2ae7e2f74 100644 (file)
@@ -361,6 +361,7 @@ SOURCEFILESMATHED = \
        mathed/InsetMathScript.cpp \
        mathed/InsetMathSize.cpp \
        mathed/InsetMathSpace.cpp \
+       mathed/InsetMathSpecialChar.cpp \
        mathed/InsetMathSplit.cpp \
        mathed/InsetMathSqrt.cpp \
        mathed/InsetMathStackrel.cpp \
@@ -425,6 +426,7 @@ HEADERFILESMATHED = \
        mathed/InsetMathScript.h \
        mathed/InsetMathSize.h \
        mathed/InsetMathSpace.h \
+       mathed/InsetMathSpecialChar.h \
        mathed/InsetMathSplit.h \
        mathed/InsetMathSqrt.h \
        mathed/InsetMathStackrel.h \
index 2f91e9ede5e6f872d3b8fd753fc8b56205ebfed8..589f7b27e319b9f1d438e0818fd88932de244aab 100644 (file)
@@ -66,6 +66,7 @@ class InsetMathNest;
 class InsetMathScript;
 class InsetMathString;
 class InsetMathSpace;
+class InsetMathSpecialChar;
 class InsetMathSymbol;
 class InsetMathUnknown;
 
@@ -142,6 +143,7 @@ public:
        virtual InsetMathUnknown        * asUnknownInset()        { return 0; }
        virtual InsetMathUnknown const  * asUnknownInset() const  { return 0; }
        virtual InsetMathRef            * asRefInset()            { return 0; }
+       virtual InsetMathSpecialChar const * asSpecialCharInset() const { return 0; }
 
        /// identifies things that can get scripts
        virtual bool isScriptable() const { return false; }
index 591e3609e47f270ef065b6b1fa9ba7802b06bf00..ffde2ad45fba967544306d14f501f5548c13237b 100644 (file)
@@ -1435,6 +1435,9 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type c)
                                        cur.niceInsert(createInsetMath("textbackslash"));
                                else
                                        cur.niceInsert(createInsetMath("backslash"));
+                       } else if (c == '^' && currentMode() == InsetMath::MATH_MODE) {
+                               cur.backspace();
+                               cur.niceInsert(createInsetMath("mathcircumflex"));
                        } else if (c == '{') {
                                cur.backspace();
                                cur.niceInsert(MathAtom(new InsetMathBrace));
@@ -1564,7 +1567,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type c)
                return cur.pos() != cur.lastpos();
        }
 
-       // These shouldn't work in text mode:
+       // These should be treated differently when not in text mode:
        if (currentMode() != InsetMath::TEXT_MODE) {
                if (c == '_') {
                        script(cur, false, save_selection);
@@ -1578,10 +1581,19 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type c)
                        cur.niceInsert(createInsetMath("sim"));
                        return true;
                }
+       } else {
+               if (c == '^') {
+                       cur.niceInsert(createInsetMath("textasciicircum"));
+                       return true;
+               }
+               if (c == '~') {
+                       cur.niceInsert(createInsetMath("textasciitilde"));
+                       return true;
+               }
        }
 
        if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' ||
-           c == '%' || c == '_' || c == '^') {
+           c == '%' || c == '_') {
                cur.niceInsert(createInsetMath(docstring(1, c)));
                return true;
        }
diff --git a/src/mathed/InsetMathSpecialChar.cpp b/src/mathed/InsetMathSpecialChar.cpp
new file mode 100644 (file)
index 0000000..6157c79
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * \file InsetMathSpecialChar.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Enrico Forestieri
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "InsetMathSpecialChar.h"
+
+#include "MathSupport.h"
+#include "MathStream.h"
+#include "MetricsInfo.h"
+
+#include "Dimension.h"
+#include "LaTeXFeatures.h"
+#include "TextPainter.h"
+
+#include "frontends/FontMetrics.h"
+
+#include "support/lassert.h"
+
+
+namespace lyx {
+
+
+InsetMathSpecialChar::InsetMathSpecialChar(docstring name)
+       : name_(name), kerning_(0)
+{
+       if (name.size() != 1) {
+               if (name == from_ascii("textasciicircum")
+                   || name == from_ascii("mathcircumflex"))
+                       char_ = '^';
+               else if (name == from_ascii("textasciitilde"))
+                       char_ = '~';
+               else if (name == from_ascii("textbackslash"))
+                       char_ = '\\';
+               else
+                       LASSERT(false, /**/);
+       } else
+               char_ = name.at(0);
+}
+
+
+
+Inset * InsetMathSpecialChar::clone() const
+{
+       return new InsetMathSpecialChar(*this);
+}
+
+
+void InsetMathSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+       if (mi.base.fontname == "mathnormal") {
+               ShapeChanger dummy(mi.base.font, UP_SHAPE);
+               dim = theFontMetrics(mi.base.font).dimension(char_);
+       } else {
+               frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
+               dim = fm.dimension(char_);
+               kerning_ = fm.rbearing(char_) - dim.wid;
+       }
+}
+
+
+void InsetMathSpecialChar::draw(PainterInfo & pi, int x, int y) const
+{
+       if (pi.base.fontname == "mathnormal") {
+               ShapeChanger dummy(pi.base.font, UP_SHAPE);
+               pi.draw(x, y, char_);
+       } else {
+               pi.draw(x, y, char_);
+       }
+}
+
+
+void InsetMathSpecialChar::metricsT(TextMetricsInfo const &, Dimension & dim) const
+{
+       dim.wid = 1;
+       dim.asc = 1;
+       dim.des = 0;
+}
+
+
+void InsetMathSpecialChar::drawT(TextPainter & pain, int x, int y) const
+{
+       pain.draw(x, y, char_);
+}
+
+
+void InsetMathSpecialChar::write(WriteStream & os) const
+{
+       os << '\\' << name_;
+       if (name_.size() != 1)
+               os.pendingSpace(true);
+}
+
+
+void InsetMathSpecialChar::validate(LaTeXFeatures & features) const
+{
+       if (name_ == "mathcircumflex")
+               features.require("mathcircumflex");
+}
+
+
+void InsetMathSpecialChar::normalize(NormalStream & os) const
+{
+       os << "[char ";
+       os.os().put(char_);
+       os << " mathalpha]";
+}
+
+
+void InsetMathSpecialChar::maple(MapleStream & os) const
+{
+       os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::mathematica(MathematicaStream & os) const
+{
+       os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::octave(OctaveStream & os) const
+{
+       os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::mathmlize(MathStream & ms) const
+{
+       switch (char_) {
+       case '&':
+               ms << "&amp;";
+               break;
+       default:
+               ms.os().put(char_);
+               break;
+       }
+}
+
+
+} // namespace lyx
diff --git a/src/mathed/InsetMathSpecialChar.h b/src/mathed/InsetMathSpecialChar.h
new file mode 100644 (file)
index 0000000..7e2e808
--- /dev/null
@@ -0,0 +1,69 @@
+// -*- C++ -*-
+/**
+ * \file InsetMathSpecialChar.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Enrico Forestieri
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef MATH_SPECIALCHARINSET_H
+#define MATH_SPECIALCHARINSET_H
+
+#include "InsetMath.h"
+
+namespace lyx {
+
+/// The special character inset.
+class InsetMathSpecialChar : public InsetMath {
+public:
+       ///
+       explicit InsetMathSpecialChar(docstring name);
+       ///
+       void setBuffer(Buffer &) {}
+       ///
+       void metrics(MetricsInfo & mi, Dimension & dim) const;
+       ///
+       void draw(PainterInfo & pi, int x, int y) const;
+       ///
+       void metricsT(TextMetricsInfo const & mi, Dimension & dim) const;
+       ///
+       void drawT(TextPainter &, int x, int y) const;
+       ///
+       int kerning(BufferView const *) const { return kerning_; }
+       ///
+       void write(WriteStream & os) const;
+       ///
+       void validate(LaTeXFeatures & features) const;
+       ///
+       void normalize(NormalStream & ns) const;
+       ///
+       void octave(OctaveStream & os) const;
+       ///
+       void maple(MapleStream &) const;
+       ///
+       void mathematica(MathematicaStream &) const;
+       ///
+       void mathmlize(MathStream & ms) const;
+       /// identifies SpecialChar insets
+       InsetMathSpecialChar const * asSpecialCharInset() const { return this; }
+       ///
+       docstring name() const { return name_; }
+       ///
+       char_type getChar() const { return char_; }
+
+private:
+       virtual Inset * clone() const;
+       /// the latex name
+       docstring name_;
+       /// the displayed character
+       char_type char_;
+       /// cached kerning for superscript
+       mutable int kerning_;
+};
+
+} // namespace lyx
+
+#endif
index c8060086b9ac3abf248d4d2d98c62cdcceba1b44..8791b719a5478bac4a486ec6fde41825470c8471 100644 (file)
@@ -32,6 +32,7 @@
 #include "InsetMathRoot.h"
 #include "InsetMathSize.h"
 #include "InsetMathSpace.h"
+#include "InsetMathSpecialChar.h"
 #include "InsetMathSplit.h"
 #include "InsetMathSqrt.h"
 #include "InsetMathStackrel.h"
@@ -218,6 +219,20 @@ void initSymbols()
 }
 
 
+bool isSpecialChar(docstring name)
+{
+       if (name.size() != 1) {
+               string const s = to_ascii(name);
+               return  s == "textasciicircum" || s == "mathcircumflex" ||
+                       s == "textasciitilde"  || s == "textbackslash";
+       } else {
+               char_type const c = name.at(0);
+               return  c == '{' || c == '}' || c == '&' || c == '$' ||
+                       c == '#' || c == '%' || c == '_';
+       }
+}
+
+
 } // namespace anon
 
 MathWordList const & mathedWordList()
@@ -446,6 +461,8 @@ MathAtom createInsetMath(docstring const & s)
                return MathAtom(new InsetMathPhantom(InsetMathPhantom::vphantom));
        if (s == "ensuremath")
                return MathAtom(new InsetMathEnsureMath);
+       if (isSpecialChar(s))
+               return MathAtom(new InsetMathSpecialChar(s));
 
        return MathAtom(new MathMacro(s));
 }
index fb05c7182e428f92681da14f584e4a012011e7ba..c90b7188f40932cb3ed052d58a483182c5a72cbc 100644 (file)
@@ -518,8 +518,8 @@ void MathMacro::validate(LaTeXFeatures & features) const
        if (!requires_.empty())
                features.require(requires_);
 
-       if (name() == "binom" || name() == "mathcircumflex")
-               features.require(to_utf8(name()));
+       if (name() == "binom")
+               features.require("binom");
        
        // validate the cells and the definition
        if (displayMode() == DISPLAY_NORMAL) {
index 56fdf23c81db936e223f1483e967ddcd9b8ebe40..7494a2906cb261ecacb9b5da01326c0603a4ed21 100644 (file)
@@ -100,11 +100,16 @@ bool stared(docstring const & s)
 }
 
 
-docstring escapeSpecialChars(docstring const & str)
+docstring escapeSpecialChars(docstring const & str, bool textmode)
 {
+       docstring const backslash = textmode ? from_ascii("\\textbackslash ")
+                                            : from_ascii("\\backslash ");
+       docstring const caret = textmode ? from_ascii("\\textasciicircum ")
+                                        : from_ascii("\\mathcircumflex ");
+
        return subst(subst(subst(subst(subst(subst(subst(subst(subst(str,
-                       from_ascii("\\"), from_ascii("\\backslash ")),
-                       from_ascii("^"), from_ascii("\\mathcircumflex ")),
+                       from_ascii("\\"), backslash),
+                       from_ascii("^"), caret),
                        from_ascii("_"), from_ascii("\\_")),
                        from_ascii("$"), from_ascii("\\$")),
                        from_ascii("#"), from_ascii("\\#")),
@@ -540,8 +545,9 @@ void Parser::tokenize(istream & is)
 
 void Parser::tokenize(docstring const & buffer)
 {
-       idocstringstream is(mode_ & Parse::VERBATIM ?
-               escapeSpecialChars(buffer) : buffer, ios::in | ios::binary);
+       idocstringstream is(mode_ & Parse::VERBATIM
+                       ? escapeSpecialChars(buffer, mode_ & Parse::TEXTMODE)
+                       : buffer, ios::in | ios::binary);
 
        char_type c;
        while (is.get(c)) {