]> git.lyx.org Git - features.git/commitdiff
Make MathBigInset working
authorGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Thu, 20 Apr 2006 09:55:45 +0000 (09:55 +0000)
committerGeorg Baum <Georg.Baum@post.rwth-aachen.de>
Thu, 20 Apr 2006 09:55:45 +0000 (09:55 +0000)
        * src/cursor.C
        (LCursor::plainInsert): combine the previous math atom with the new
        one to a MathBigInset if possible

        * src/mathed/math_biginset.[Ch]
        (MathBigInset::name): implement
        (MathBigInset::isBigInsetDelim): new, test whether a given token is
        a valid MathBigInset delimiter

        * src/mathed/math_biginset.C
        (MathBigInset::size): handle Big, Bigg and Biggg
        (MathBigInset::increase): ditto
        (MathBigInset::draw): fix deco drawing
        (MathBigInset::write): append space if necessary

        * src/mathed/math_factory.C
        (createMathInset): handle l->inset == "big"

        * src/mathed/math_parser.C
        (Token::asInput): return a token as input, stolen from tex2lyx
        (void Parser::parse1): Create a MathBigInset when needed

* src/mathed/math_support.C:
(deco_table): add lbrace and rbrace

        * src/mathed/math_nestinset.C
        (MathNestInset::interpret): combine the previous math atom with the
        new character to a MathBigInset if possible

        * src/ParagraphParameters.C
        (findToken): move from here

        * src/support/lstrings.[Ch]
        (findToken): to here

        * lib/symbols: add MathBigInset symbols

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

lib/symbols
src/ParagraphParameters.C
src/cursor.C
src/mathed/math_biginset.C
src/mathed/math_biginset.h
src/mathed/math_factory.C
src/mathed/math_nestinset.C
src/mathed/math_parser.C
src/mathed/math_support.C
src/support/lstrings.C
src/support/lstrings.h

index 4bc306d62f86e280fb996f0ea64bfef8a1bc4911..2d18e9ceafbd3e6f6184da43f3ce87d5cf6df3f2 100644 (file)
@@ -41,6 +41,28 @@ dotso             dots        none
 ldots             dots        none
 vdots             dots        none
 
+# big delimiters
+bigl              big         none
+bigm              big         none
+bigr              big         none
+Bigl              big         none
+Bigm              big         none
+Bigr              big         none
+biggl             big         none
+biggm             big         none
+biggr             big         none
+Biggl             big         none
+Biggm             big         none
+Biggr             big         none
+# The following are not standard LaTeX, but defined in the lucida font
+# packages. No 'm' versions!
+# See lucidabr.dtx for a possible implementation if you want to use these
+# with other fonts.
+bigggl            big         none
+bigggr            big         none
+Bigggl            big         none
+Bigggr            big         none
+
 # font changes
 # name           "font"       math/text family  series  shape  color
 # mathnormal should stay the first
index 1f5da6720a93de1cb22715edf5508c2a1a17f7d3..6fead69a332123b26c7acb2c1ef84f13fd8f42b6 100644 (file)
@@ -40,20 +40,11 @@ using std::string;
 
 // anonym namespace
 namespace {
-int findToken(char const * const str[], string const search_token)
+int findToken(char const * const str[], string const search_token)
 {
-       int i = 0;
-
-       if (search_token != "default") {
-               while (str[i][0] && str[i] != search_token) {
-                       ++i;
-               }
-               if (!str[i][0]) {
-                       i = -1;
-               }
-       }
-
-       return i;
+       return search_token == "default" ?
+               0 :
+               lyx::support::findToken(str, search_token);
 }
 
 }
index 0ca25c2d20af868b2824c792038cd73367919867..45ba966efdbb36772317905909488a4db3993830 100644 (file)
 #include "insets/insettabular.h"
 #include "insets/insettext.h"
 
+#include "mathed/math_biginset.h"
 #include "mathed/math_data.h"
 #include "mathed/math_inset.h"
 #include "mathed/math_scriptinset.h"
 #include "mathed/math_macrotable.h"
+#include "mathed/math_parser.h"
 
 #include "support/limited_stack.h"
 
@@ -650,6 +652,22 @@ void LCursor::markErase()
 
 void LCursor::plainInsert(MathAtom const & t)
 {
+       // Create a MathBigInset from cell()[pos() - 1] and t if possible
+       if (!empty() && pos() > 0 && cell()[pos() - 1]->asUnknownInset()) {
+               string const name = asString(t);
+               if (MathBigInset::isBigInsetDelim(name)) {
+                       string prev = asString(cell()[pos() - 1]);
+                       if (prev[0] == '\\') {
+                               prev = prev.substr(1);
+                               latexkeys const * l = in_word_set(prev);
+                               if (l && l->inset == "big") {
+                                       cell()[pos() - 1] =
+                                               MathAtom(new MathBigInset(prev, name));
+                                       return;
+                               }
+                       }
+               }
+       }
        cell().insert(pos(), t);
        ++pos();
 }
index ade63c123b3c9671fcb3e54c6be67ed3021e3e15..2580fadbb5e04e17b55811fc838cb730b9cd4b95 100644 (file)
@@ -15,6 +15,8 @@
 #include "math_mathmlstream.h"
 #include "math_streamstr.h"
 
+#include "support/lstrings.h"
+
 
 using std::string;
 using std::auto_ptr;
@@ -25,6 +27,12 @@ MathBigInset::MathBigInset(string const & name, string const & delim)
 {}
 
 
+string MathBigInset::name() const
+{
+       return name_;
+}
+
+
 auto_ptr<InsetBase> MathBigInset::doClone() const
 {
        return auto_ptr<InsetBase>(new MathBigInset(*this));
@@ -33,18 +41,21 @@ auto_ptr<InsetBase> MathBigInset::doClone() const
 
 MathBigInset::size_type MathBigInset::size() const
 {
-       return name_.size() - 4;
+       // order: big Big bigg Bigg biggg Biggg
+       //        0   1   2    3    4     5
+       return name_[0] == 'B' ?
+               2 * (name_.size() - 4) + 1:
+               2 * (name_.size() - 4);
 }
 
 
 double MathBigInset::increase() const
 {
-       switch (size()) {
-               case 1:  return 0.2;
-               case 2:  return 0.44;
-               case 3:  return 0.7;
-               default: return 0.0;
-       }
+       // The formula used in amsmath.sty is
+       // 1.2 * (1.0 + size() * 0.5) - 1.0.
+       // We use a smaller step and a bigger offset because our base size
+       // is different.
+       return (size() + 1) * 0.3;
 }
 
 
@@ -61,13 +72,23 @@ void MathBigInset::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void MathBigInset::draw(PainterInfo & pi, int x, int y) const
 {
-       mathed_draw_deco(pi, x + 1, y - dim_.ascent(), 4, dim_.height(), delim_);
+       // mathed_draw_deco does not use the leading backslash, so remove it.
+       // Replace \| by \Vert (equivalent in LaTeX), since mathed_draw_deco
+       // would treat it as |.
+       string const delim = (delim_ == "\\|") ?
+               "Vert" :
+               lyx::support::ltrim(delim_, "\\");
+       mathed_draw_deco(pi, x + 1, y - dim_.ascent(), 4, dim_.height(),
+                        delim);
+       setPosCache(pi, x, y);
 }
 
 
 void MathBigInset::write(WriteStream & os) const
 {
        os << '\\' << name_ << ' ' << delim_;
+       if (delim_[0] == '\\')
+               os.pendingSpace(true);
 }
 
 
@@ -75,3 +96,19 @@ void MathBigInset::normalize(NormalStream & os) const
 {
        os << '[' << name_ << ' ' <<  delim_ << ']';
 }
+
+
+bool MathBigInset::isBigInsetDelim(string const & delim)
+{
+       // mathed_draw_deco must handle these
+       static char const * const delimiters[] = {
+               "(", ")", "\\{", "\\}", "\\lbrace", "\\rbrace", "[", "]",
+               "|", "/", "\\|", "\\vert", "\\Vert", "'", "\\backslash",
+               "\\langle", "\\lceil", "\\lfloor",
+               "\\rangle", "\\rceil", "\\rfloor",
+               "\\downarrow", "\\Downarrow",
+               "\\uparrow", "\\Uparrow",
+               "\\updownarrow", "\\Updownarrow", ""
+       };
+       return (lyx::support::findToken(delimiters, delim) >= 0);
+}
index f9547cc469e848e58f9ab8b32db861eac4580f09..abdf10407f84de973cc65d8fe3b501e29a639ba9 100644 (file)
 
 #include <string>
 
-/// Inset for \bigl & Co.
+/// Inset for \\bigl & Co.
 class MathBigInset : public MathDimInset {
 public:
        ///
        MathBigInset(std::string const & name, std::string const & delim);
        ///
+       std::string name() const;
+       ///
        void metrics(MetricsInfo & mi, Dimension & dim) const;
        ///
        void draw(PainterInfo & pi, int x, int y) const;
@@ -29,6 +31,8 @@ public:
        void write(WriteStream & os) const;
        ///
        void normalize(NormalStream & os) const;
+       ///
+       static bool isBigInsetDelim(std::string const &);
 
 private:
        virtual std::auto_ptr<InsetBase> doClone() const;
@@ -37,9 +41,9 @@ private:
        ///
        double increase() const;
 
-       /// \bigl or what?
+       /// \\bigl or what?
        std::string const name_;
-       /// ( or [ or Vert...
+       /// ( or [ or \\Vert...
        std::string const delim_;
 };
 
index ac97f36154871f51e6712d61fae3e5d4d41d44df..d55fc094db0997fe82e6664a67a7bf4295e75fc9 100644 (file)
@@ -276,6 +276,10 @@ MathAtom createMathInset(string const & s)
                        return MathAtom(new MathFontOldInset(l));
                if (inset == "matrix")
                        return MathAtom(new MathAMSArrayInset(s));
+               if (inset == "big")
+                       // we can't create a MathBigInset, since the argument
+                       // is missing.
+                       return MathAtom(new MathUnknownInset(s));
                return MathAtom(new MathSymbolInset(l));
        }
 
index 90fb8e9e742c3f3095afa6f71aa60b274d53717f..d5d4305e99de85df71fa18b94166421bcd8ad8ba 100644 (file)
@@ -13,6 +13,7 @@
 #include "math_nestinset.h"
 
 #include "math_arrayinset.h"
+#include "math_biginset.h"
 #include "math_boxinset.h"
 #include "math_braceinset.h"
 #include "math_colorinset.h"
@@ -1144,6 +1145,36 @@ bool MathNestInset::interpret(LCursor & cur, char c)
                        return true;
                }
 
+               // One character big delimiters. The others are handled in
+               // LCursor::plainInsert.
+               latexkeys const * l = in_word_set(name.substr(1));
+               if (name[0] == '\\' && l && l->inset == "big") {
+                       string delim;
+                       switch (c) {
+                       case '{':
+                               delim = "\\{";
+                               break;
+                       case '}':
+                               delim = "\\}";
+                               break;
+                       default:
+                               delim = string(1, c);
+                               break;
+                       }
+                       if (MathBigInset::isBigInsetDelim(delim)) {
+                               // name + delim ared a valid MathBigInset.
+                               // We can't use cur.macroModeClose() because
+                               // it does not handle delim.
+                               MathUnknownInset * p = cur.activeMacro();
+                               p->finalize();
+                               --cur.pos();
+                               cur.cell().erase(cur.pos());
+                               cur.plainInsert(MathAtom(
+                                       new MathBigInset(name.substr(1), delim)));
+                               return true;
+                       }
+               }
+
                // leave macro mode and try again if necessary
                cur.macroModeClose();
                if (c == '{')
index 2eb3ae40e5a320112fec154090d08c4f65810c8a..6aea310a37bc79f210f0d323ff6bd1f082c30d2e 100644 (file)
@@ -40,6 +40,7 @@ following hack as starting point to write some macros:
 
 #include "math_parser.h"
 #include "math_arrayinset.h"
+#include "math_biginset.h"
 #include "math_braceinset.h"
 #include "math_charinset.h"
 #include "math_colorinset.h"
@@ -256,6 +257,8 @@ public:
        char character() const { return char_; }
        ///
        string asString() const { return cs_.size() ? cs_ : string(1, char_); }
+       ///
+       string asInput() const { return cs_.size() ? '\\' + cs_ : string(1, char_); }
 
 private:
        ///
@@ -1298,7 +1301,20 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
                else if (t.cs().size()) {
                        latexkeys const * l = in_word_set(t.cs());
                        if (l) {
-                               if (l->inset == "font") {
+                               if (l->inset == "big") {
+                                       skipSpaces();
+                                       string const delim = getToken().asInput();
+                                       if (MathBigInset::isBigInsetDelim(delim))
+                                               cell->push_back(MathAtom(
+                                                       new MathBigInset(t.cs(), delim)));
+                                       else {
+                                               cell->push_back(createMathInset(t.cs()));
+                                               cell->push_back(createMathInset(
+                                                               delim.substr(1)));
+                                       }
+                               }
+
+                               else if (l->inset == "font") {
                                        cell->push_back(createMathInset(t.cs()));
                                        parse(cell->back().nucleus()->cell(0),
                                                FLAG_ITEM, asMode(mode, l->extra));
index 59618ea053a7bd410e48fcda766a863b4b388995..0b8c139ddb9039e6858aa2c2fd8b350474f84cb3 100644 (file)
@@ -283,6 +283,8 @@ named_deco_struct deco_table[] = {
        {")",              parenth,    2 },
        {"{",              brace,      0 },
        {"}",              brace,      2 },
+       {"lbrace",         brace,      0 },
+       {"rbrace",         brace,      2 },
        {"[",              brack,      0 },
        {"]",              brack,      2 },
        {"|",              vert,       0 },
index 7d58d73b54a3f4a7aa3f8b5603a36ef2e6890922..b4b70f0f0c5f7488abf2e40ad23ada02bca8143a 100644 (file)
@@ -534,6 +534,18 @@ string const getStringFromVector(vector<string> const & vec,
 }
 
 
+int findToken(char const * const str[], string const & search_token)
+{
+       int i = 0;
+
+       while (str[i][0] && str[i] != search_token)
+               ++i;
+       if (!str[i][0])
+               i = -1;
+       return i;
+}
+
+
 #ifndef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES
 #if USE_BOOST_FORMAT
 
index 995d96b0809c15c815931fb3a2b24d5b11e24425..0ef0806edd97c22c2d0289457d6425b24864b1c9 100644 (file)
@@ -176,6 +176,10 @@ std::vector<std::string> const getVectorFromString(std::string const & str,
 std::string const getStringFromVector(std::vector<std::string> const & vec,
                                 std::string const & delim = std::string(","));
 
+/// Search \p search_token in \p str and return the position if it is
+/// found, else -1. The last item in \p str must be "".
+int findToken(char const * const str[], std::string const & search_token);
+
 
 #ifdef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES