On Tue, Apr 18, 2006 at 07:06:10AM +0200, Enrico Forestieri wrote:

> On Mon, Apr 17, 2006 at 08:57:54PM +0200, Georg Baum wrote:
> 
> > Am Montag, 17. April 2006 18:24 schrieb Enrico Forestieri:
> 
> > > It would also be nice having a report in the status line about the
> > > size of the delimiter when the cursor is next to it.
> > 
> > That is not possible with this approach, since the status line info is 
> > only obtained if the cursor is inside an inset.
> 
> Ok, I think one can live with that.
> 
> > > However, even converting it to 1.4, I don't obtain correct results
> > > loading it in 1.5. I also attach here a test file test-1.4.lyx and
> > > the results I obtain with 1.4 (test-1.4.png) and 1.5 (test-1.5.png).
> > 
> > The reason was a stupid mistake I made. Please try the attached, updated 
> > patch. I intend to commit this unless I get objections regarding the 
> > general approach.
> 
> This patch works with both 1.4 and 1.5. However, there is a problem
> with brackets. Bigger "{" and "}" can be created on screen but the
> generated latex is wrong. For example one obtains "\Bigl {" and
> "\Bigr }" instead of the correct "\Bigl\{" and "\Bigr\}".
> Conversely, when loading a file containing "\Bigl\{", this is not
> rendered on screen.
> 
> Please, try the attached LyX document. I created the first two
> brackets with an unpatched version of LyX and added the second couple
> with a patched one.
> 
> Other constructs such as \bigl\Vert seem to work.
> 
> Thank you for your efforts Georg, I wish I could be more helpful here.

I can be of some help, perhaps ;-)

Please try the attached patch, updated from yours. I solved the
problem of loading a file containing "\Bigl\{" and solved the problem
of generating a bigger "{" or "}" within LyX, introducing "\lbrace"
and "\rbrace", which seemingly you forgot.

I am not able to generate a bigger "{" by "\bigl\{" in mathed (I must
use "\bigl\lbrace" for that) because I think that the code dealing
with \bigl has not a chance of viewing \{, being it transformed to {}.
This is currently beyond my capabilities (but I continue learning).

-- 
Enrico
Index: src/cursor.C
===================================================================
--- src/cursor.C        (revision 13692)
+++ src/cursor.C        (working copy)
@@ -35,10 +35,12 @@
 #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: src/mathed/math_biginset.h
===================================================================
--- src/mathed/math_biginset.h  (revision 13692)
+++ src/mathed/math_biginset.h  (working copy)
@@ -16,12 +16,14 @@
 
 #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: src/mathed/math_factory.C
===================================================================
--- src/mathed/math_factory.C   (revision 13692)
+++ src/mathed/math_factory.C   (working copy)
@@ -276,6 +276,10 @@ MathAtom createMathInset(string const & 
                        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: src/mathed/math_parser.C
===================================================================
--- src/mathed/math_parser.C    (revision 13692)
+++ src/mathed/math_parser.C    (working copy)
@@ -40,6 +40,7 @@ following hack as starting point to writ
 
 #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
                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: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C (revision 13692)
+++ src/mathed/math_nestinset.C (working copy)
@@ -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"
@@ -1142,6 +1143,25 @@ bool MathNestInset::interpret(LCursor & 
                                cur.niceInsert(createMathInset(string(1, 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 const delim = string(1, c);
+                       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
Index: src/mathed/math_biginset.C
===================================================================
--- src/mathed/math_biginset.C  (revision 13692)
+++ src/mathed/math_biginset.C  (working copy)
@@ -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 
 {}
 
 
+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::doClon
 
 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,17 +72,43 @@ void MathBigInset::metrics(MetricsInfo &
 
 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);
 }
 
 
 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[] = {
+               "(", ")", "\\{", "\\}", "[", "]", "|", "/",
+               "\\|", "\\vert", "\\Vert", "'", "\\backslash",
+               "\\langle", "\\lceil", "\\lfloor", "\\lbrace",
+               "\\rangle", "\\rceil", "\\rfloor", "\\rbrace",
+               "\\downarrow", "\\Downarrow",
+               "\\uparrow", "\\Uparrow",
+               "\\updownarrow", "\\Updownarrow", ""
+       };
+       return (lyx::support::findToken(delimiters, delim) >= 0);
 }
Index: src/mathed/math_support.C
===================================================================
--- src/mathed/math_support.C   (revision 13692)
+++ src/mathed/math_support.C   (working copy)
@@ -292,9 +292,11 @@ named_deco_struct deco_table[] = {
        {"'",              slash,      1 },
        {"backslash",      slash,      1 },
        {"langle",         angle,      0 },
+       {"lbrace",         brace,      0 },
        {"lceil",          corner,     0 },
        {"lfloor",         corner,     1 },
        {"rangle",         angle,      2 },
+       {"rbrace",         brace,      2 },
        {"rceil",          corner,     3 },
        {"rfloor",         corner,     2 },
        {"downarrow",      arrow,      2 },
Index: src/ParagraphParameters.C
===================================================================
--- src/ParagraphParameters.C   (revision 13692)
+++ src/ParagraphParameters.C   (working copy)
@@ -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: src/support/lstrings.C
===================================================================
--- src/support/lstrings.C      (revision 13692)
+++ src/support/lstrings.C      (working copy)
@@ -534,6 +534,18 @@ string const getStringFromVector(vector<
 }
 
 
+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: src/support/lstrings.h
===================================================================
--- src/support/lstrings.h      (revision 13692)
+++ src/support/lstrings.h      (working copy)
@@ -176,6 +176,10 @@ std::vector<std::string> const getVector
 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
 
Index: lib/symbols
===================================================================
--- lib/symbols (revision 13692)
+++ lib/symbols (working copy)
@@ -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

Reply via email to