From: Georg Baum Date: Thu, 20 Apr 2006 09:55:45 +0000 (+0000) Subject: Make MathBigInset working X-Git-Tag: 1.6.10~13319 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=2bbe7e5b89238d050fd9f5cfede3091b5315f449;p=features.git 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 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13700 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/lib/symbols b/lib/symbols index 4bc306d62f..2d18e9ceaf 100644 --- a/lib/symbols +++ b/lib/symbols @@ -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 diff --git a/src/ParagraphParameters.C b/src/ParagraphParameters.C index 1f5da6720a..6fead69a33 100644 --- a/src/ParagraphParameters.C +++ b/src/ParagraphParameters.C @@ -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); } } diff --git a/src/cursor.C b/src/cursor.C index 0ca25c2d20..45ba966efd 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -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(); } diff --git a/src/mathed/math_biginset.C b/src/mathed/math_biginset.C index ade63c123b..2580fadbb5 100644 --- a/src/mathed/math_biginset.C +++ b/src/mathed/math_biginset.C @@ -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 & name, string const & delim) {} +string MathBigInset::name() const +{ + return name_; +} + + auto_ptr MathBigInset::doClone() const { return auto_ptr(new MathBigInset(*this)); @@ -33,18 +41,21 @@ auto_ptr MathBigInset::doClone() const 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 & mi, Dimension & dim) const 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(NormalStream & os) const { 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); +} diff --git a/src/mathed/math_biginset.h b/src/mathed/math_biginset.h index f9547cc469..abdf10407f 100644 --- a/src/mathed/math_biginset.h +++ b/src/mathed/math_biginset.h @@ -16,12 +16,14 @@ #include -/// 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 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_; }; diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index ac97f36154..d55fc094db 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -276,6 +276,10 @@ MathAtom createMathInset(string const & s) 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)); } diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 90fb8e9e74..d5d4305e99 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -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 & cur, char 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 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 == '{') diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index 2eb3ae40e5..6aea310a37 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -40,6 +40,7 @@ following hack as starting point to write some macros: #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, unsigned flags, 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)); diff --git a/src/mathed/math_support.C b/src/mathed/math_support.C index 59618ea053..0b8c139ddb 100644 --- a/src/mathed/math_support.C +++ b/src/mathed/math_support.C @@ -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 }, diff --git a/src/support/lstrings.C b/src/support/lstrings.C index 7d58d73b54..b4b70f0f0c 100644 --- a/src/support/lstrings.C +++ b/src/support/lstrings.C @@ -534,6 +534,18 @@ string const getStringFromVector(vector const & vec, } +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 diff --git a/src/support/lstrings.h b/src/support/lstrings.h index 995d96b080..0ef0806edd 100644 --- a/src/support/lstrings.h +++ b/src/support/lstrings.h @@ -176,6 +176,10 @@ std::vector const getVectorFromString(std::string const & str, std::string const getStringFromVector(std::vector 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