Enrico Forestieri wrote:

> 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).

Only a tiny bit was missing: The transformation of { and } to \{ and \},
respectively in MathNestInset::interpret. I am going to ccommit the
attached patch.


Georg

Log:
Make MathBigInset working
        * 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
Index: src/cursor.C
===================================================================
--- src/cursor.C	(Revision 13698)
+++ src/cursor.C	(Arbeitskopie)
@@ -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 13698)
+++ src/mathed/math_biginset.h	(Arbeitskopie)
@@ -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 13698)
+++ src/mathed/math_factory.C	(Arbeitskopie)
@@ -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 13698)
+++ src/mathed/math_parser.C	(Arbeitskopie)
@@ -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 13698)
+++ src/mathed/math_nestinset.C	(Arbeitskopie)
@@ -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 & 
 			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: src/mathed/math_biginset.C
===================================================================
--- src/mathed/math_biginset.C	(Revision 13698)
+++ src/mathed/math_biginset.C	(Arbeitskopie)
@@ -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,13 +72,23 @@ 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);
 }
 
 
@@ -75,3 +96,19 @@ void MathBigInset::normalize(NormalStrea
 {
 	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: src/mathed/math_support.C
===================================================================
--- src/mathed/math_support.C	(Revision 13698)
+++ src/mathed/math_support.C	(Arbeitskopie)
@@ -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: src/ParagraphParameters.C
===================================================================
--- src/ParagraphParameters.C	(Revision 13698)
+++ src/ParagraphParameters.C	(Arbeitskopie)
@@ -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 13698)
+++ src/support/lstrings.C	(Arbeitskopie)
@@ -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 13698)
+++ src/support/lstrings.h	(Arbeitskopie)
@@ -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 13698)
+++ lib/symbols	(Arbeitskopie)
@@ -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