Am Freitag, 14. April 2006 20:05 schrieb Enrico Forestieri:
> On Fri, Apr 14, 2006 at 07:33:52PM +0200, Georg Baum wrote:
> > Does src/mathed/math_biginset.[Ch] not work?
> 
> Seemingly it does not, as if in mathed I write
> 
>   \bigl(x\bigr)
> 
> I simply see "bigl" and "bigr" in red and not a bigger "(" and ")".

Yep, meanwhile I saw that it is unfinished and unused.

> I would expect to see a placeholder after \bigl, and typing "(" in
> it should produce a bigger "(".

Try the attached patch. It works for me, but I don't like that I needed to 
touch MathNestInset and LCursor in order to create a complete 
MathBigInset (with delimiter). Undo is completely ignored for now, and I 
did not create any menu entries or toolbar/math panel buttons.

The alternative to this approach (storing the delimiter as uneditable 
string) would be to make the delimiter a normal cell. The advantage of 
that is that MathNestInset and LCursor don't need to be touched, but the 
disadvantage would be that one would ned to disable a lot of stuff in the 
delimiter box. It would certainly be surprising for the user to see that 
normal characters where disabled in a normal looking math box.

Opinions? Should I polish this version, or do we want to do it 
differently?


Georg
Index: src/cursor.C
===================================================================
--- src/cursor.C	(Revision 13686)
+++ 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] =
+						createMathInset(prev, name);
+					return;
+				}
+			}
+		}
+	}
 	cell().insert(pos(), t);
 	++pos();
 }
Index: src/mathed/math_biginset.h
===================================================================
--- src/mathed/math_biginset.h	(Revision 13686)
+++ 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 13686)
+++ src/mathed/math_factory.C	(Arbeitskopie)
@@ -14,6 +14,7 @@
 #include "math_parser.h"
 #include "math_arrayinset.h"
 #include "math_amsarrayinset.h"
+#include "math_biginset.h"
 #include "math_binominset.h"
 #include "math_boxinset.h"
 #include "math_boxedinset.h"
@@ -241,7 +242,7 @@ latexkeys const * in_word_set(string con
 }
 
 
-MathAtom createMathInset(string const & s)
+MathAtom createMathInset(string const & s, string const & arg)
 {
 	//lyxerr << "creating inset with name: '" << s << '\'' << endl;
 	latexkeys const * l = in_word_set(s);
@@ -276,6 +277,11 @@ MathAtom createMathInset(string const & 
 			return MathAtom(new MathFontOldInset(l));
 		if (inset == "matrix")
 			return MathAtom(new MathAMSArrayInset(s));
+		if (inset == "big") {
+			if (MathBigInset::isBigInsetDelim(arg))
+				return MathAtom(new MathBigInset(s, arg));
+			return MathAtom(new MathUnknownInset(s + arg));
+		}
 		return MathAtom(new MathSymbolInset(l));
 	}
 
Index: src/mathed/math_factory.h
===================================================================
--- src/mathed/math_factory.h	(Revision 13686)
+++ src/mathed/math_factory.h	(Arbeitskopie)
@@ -18,7 +18,8 @@ class MathAtom;
 class MathArray;
 
 
-MathAtom createMathInset(std::string const &);
+MathAtom createMathInset(std::string const &,
+                         std::string const & = std::string());
 
 /** Fills ar with the contents of str.
  *  str is created by the frontend dialog's and returned to the LyX core.
Index: src/mathed/math_parser.C
===================================================================
--- src/mathed/math_parser.C	(Revision 13686)
+++ 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:
 	///
@@ -1080,6 +1083,14 @@ void Parser::parse1(MathGridInset & grid
 			return;
 		}
 
+		else if (latexkeys const * l = in_word_set(t.cs())) {
+			if (l->inset == "big") {
+				skipSpaces();
+				Token const & delim = getToken();
+				cell->push_back(createMathInset(t.cs(), delim.asInput()));
+			}
+		}
+
 		else if (t.cs() == "begin") {
 			string const name = getArg('{', '}');
 			environments_.push_back(name);
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C	(Revision 13686)
+++ 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,25 @@ 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 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 the second argument of
+				// createMathInset().
+				MathUnknownInset * p = cur.activeMacro();
+				p->finalize();
+				--cur.pos();
+				cur.cell().erase(cur.pos());
+				cur.plainInsert(createMathInset(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 13686)
+++ 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,7 +41,10 @@ auto_ptr<InsetBase> MathBigInset::doClon
 
 MathBigInset::size_type MathBigInset::size() const
 {
-	return name_.size() - 4;
+	// order: big Big bigg Bigg biggg Biggg
+	return name_[0] == 'B' ?
+		2 * (name_.size() - 4) + 1 :
+		2 * (name_.size() - 4);
 }
 
 
@@ -43,6 +54,10 @@ double MathBigInset::increase() const
 		case 1:  return 0.2;
 		case 2:  return 0.44;
 		case 3:  return 0.7;
+		case 4:  return 1.0;
+		case 5:  return 1.3;
+		case 6:  return 1.6;
+		case 7:  return 1.9;
 		default: return 0.0;
 	}
 }
@@ -61,13 +76,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 +100,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[] = {
+		"(", ")", "{", "}", "[", "]", "|", "/",
+		"\\|", "\\vert", "\\Vert", "'", "\\backslash",
+		"\\langle", "\\lceil", "\\lfloor",
+		"\\rangle", "\\rceil", "\\rfloor",
+		"\\downarrow", "\\Downarrow",
+		"\\uparrow", "\\Uparrow",
+		"\\updownarrow", "\\Updownarrow", ""
+	};
+	return lyx::support::findToken(delimiters, delim) >= 0;
+}
Index: src/ParagraphParameters.C
===================================================================
--- src/ParagraphParameters.C	(Revision 13686)
+++ 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 13686)
+++ 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 13686)
+++ 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 13686)
+++ lib/symbols	(Arbeitskopie)
@@ -41,6 +41,27 @@ 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 some font packages
+bigggl            big         none
+#bigggm            big         none
+bigggr            big         none
+Bigggl            big         none
+#Bigggm            big         none
+Bigggr            big         none
+
 # font changes
 # name           "font"       math/text family  series  shape  color
 # mathnormal should stay the first

Reply via email to