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