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