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
This commit is contained in:
Georg Baum 2006-04-20 09:55:45 +00:00
parent c9b081f6f9
commit 2bbe7e5b89
11 changed files with 166 additions and 25 deletions

View File

@ -41,6 +41,28 @@ dotso dots none
ldots dots none ldots dots none
vdots 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 # font changes
# name "font" math/text family series shape color # name "font" math/text family series shape color
# mathnormal should stay the first # mathnormal should stay the first

View File

@ -40,20 +40,11 @@ using std::string;
// anonym namespace // anonym namespace
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; return search_token == "default" ?
0 :
if (search_token != "default") { lyx::support::findToken(str, search_token);
while (str[i][0] && str[i] != search_token) {
++i;
}
if (!str[i][0]) {
i = -1;
}
}
return i;
} }
} }

View File

@ -35,10 +35,12 @@
#include "insets/insettabular.h" #include "insets/insettabular.h"
#include "insets/insettext.h" #include "insets/insettext.h"
#include "mathed/math_biginset.h"
#include "mathed/math_data.h" #include "mathed/math_data.h"
#include "mathed/math_inset.h" #include "mathed/math_inset.h"
#include "mathed/math_scriptinset.h" #include "mathed/math_scriptinset.h"
#include "mathed/math_macrotable.h" #include "mathed/math_macrotable.h"
#include "mathed/math_parser.h"
#include "support/limited_stack.h" #include "support/limited_stack.h"
@ -650,6 +652,22 @@ void LCursor::markErase()
void LCursor::plainInsert(MathAtom const & t) 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); cell().insert(pos(), t);
++pos(); ++pos();
} }

View File

@ -15,6 +15,8 @@
#include "math_mathmlstream.h" #include "math_mathmlstream.h"
#include "math_streamstr.h" #include "math_streamstr.h"
#include "support/lstrings.h"
using std::string; using std::string;
using std::auto_ptr; using std::auto_ptr;
@ -25,6 +27,12 @@ MathBigInset::MathBigInset(string const & name, string const & delim)
{} {}
string MathBigInset::name() const
{
return name_;
}
auto_ptr<InsetBase> MathBigInset::doClone() const auto_ptr<InsetBase> MathBigInset::doClone() const
{ {
return auto_ptr<InsetBase>(new MathBigInset(*this)); return auto_ptr<InsetBase>(new MathBigInset(*this));
@ -33,18 +41,21 @@ auto_ptr<InsetBase> MathBigInset::doClone() const
MathBigInset::size_type MathBigInset::size() 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 double MathBigInset::increase() const
{ {
switch (size()) { // The formula used in amsmath.sty is
case 1: return 0.2; // 1.2 * (1.0 + size() * 0.5) - 1.0.
case 2: return 0.44; // We use a smaller step and a bigger offset because our base size
case 3: return 0.7; // is different.
default: return 0.0; 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 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 void MathBigInset::write(WriteStream & os) const
{ {
os << '\\' << name_ << ' ' << delim_; os << '\\' << name_ << ' ' << delim_;
if (delim_[0] == '\\')
os.pendingSpace(true);
} }
@ -75,3 +96,19 @@ void MathBigInset::normalize(NormalStream & os) const
{ {
os << '[' << name_ << ' ' << delim_ << ']'; 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);
}

View File

@ -16,12 +16,14 @@
#include <string> #include <string>
/// Inset for \bigl & Co. /// Inset for \\bigl & Co.
class MathBigInset : public MathDimInset { class MathBigInset : public MathDimInset {
public: public:
/// ///
MathBigInset(std::string const & name, std::string const & delim); MathBigInset(std::string const & name, std::string const & delim);
/// ///
std::string name() const;
///
void metrics(MetricsInfo & mi, Dimension & dim) const; void metrics(MetricsInfo & mi, Dimension & dim) const;
/// ///
void draw(PainterInfo & pi, int x, int y) const; void draw(PainterInfo & pi, int x, int y) const;
@ -29,6 +31,8 @@ public:
void write(WriteStream & os) const; void write(WriteStream & os) const;
/// ///
void normalize(NormalStream & os) const; void normalize(NormalStream & os) const;
///
static bool isBigInsetDelim(std::string const &);
private: private:
virtual std::auto_ptr<InsetBase> doClone() const; virtual std::auto_ptr<InsetBase> doClone() const;
@ -37,9 +41,9 @@ private:
/// ///
double increase() const; double increase() const;
/// \bigl or what? /// \\bigl or what?
std::string const name_; std::string const name_;
/// ( or [ or Vert... /// ( or [ or \\Vert...
std::string const delim_; std::string const delim_;
}; };

View File

@ -276,6 +276,10 @@ MathAtom createMathInset(string const & s)
return MathAtom(new MathFontOldInset(l)); return MathAtom(new MathFontOldInset(l));
if (inset == "matrix") if (inset == "matrix")
return MathAtom(new MathAMSArrayInset(s)); 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)); return MathAtom(new MathSymbolInset(l));
} }

View File

@ -13,6 +13,7 @@
#include "math_nestinset.h" #include "math_nestinset.h"
#include "math_arrayinset.h" #include "math_arrayinset.h"
#include "math_biginset.h"
#include "math_boxinset.h" #include "math_boxinset.h"
#include "math_braceinset.h" #include "math_braceinset.h"
#include "math_colorinset.h" #include "math_colorinset.h"
@ -1144,6 +1145,36 @@ bool MathNestInset::interpret(LCursor & cur, char c)
return true; 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 // leave macro mode and try again if necessary
cur.macroModeClose(); cur.macroModeClose();
if (c == '{') if (c == '{')

View File

@ -40,6 +40,7 @@ following hack as starting point to write some macros:
#include "math_parser.h" #include "math_parser.h"
#include "math_arrayinset.h" #include "math_arrayinset.h"
#include "math_biginset.h"
#include "math_braceinset.h" #include "math_braceinset.h"
#include "math_charinset.h" #include "math_charinset.h"
#include "math_colorinset.h" #include "math_colorinset.h"
@ -256,6 +257,8 @@ public:
char character() const { return char_; } char character() const { return char_; }
/// ///
string asString() const { return cs_.size() ? cs_ : string(1, char_); } string asString() const { return cs_.size() ? cs_ : string(1, char_); }
///
string asInput() const { return cs_.size() ? '\\' + cs_ : string(1, char_); }
private: private:
/// ///
@ -1298,7 +1301,20 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
else if (t.cs().size()) { else if (t.cs().size()) {
latexkeys const * l = in_word_set(t.cs()); latexkeys const * l = in_word_set(t.cs());
if (l) { 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())); cell->push_back(createMathInset(t.cs()));
parse(cell->back().nucleus()->cell(0), parse(cell->back().nucleus()->cell(0),
FLAG_ITEM, asMode(mode, l->extra)); FLAG_ITEM, asMode(mode, l->extra));

View File

@ -283,6 +283,8 @@ named_deco_struct deco_table[] = {
{")", parenth, 2 }, {")", parenth, 2 },
{"{", brace, 0 }, {"{", brace, 0 },
{"}", brace, 2 }, {"}", brace, 2 },
{"lbrace", brace, 0 },
{"rbrace", brace, 2 },
{"[", brack, 0 }, {"[", brack, 0 },
{"]", brack, 2 }, {"]", brack, 2 },
{"|", vert, 0 }, {"|", vert, 0 },

View File

@ -534,6 +534,18 @@ string const getStringFromVector(vector<string> 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 #ifndef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES
#if USE_BOOST_FORMAT #if USE_BOOST_FORMAT

View File

@ -176,6 +176,10 @@ std::vector<std::string> const getVectorFromString(std::string const & str,
std::string const getStringFromVector(std::vector<std::string> const & vec, std::string const getStringFromVector(std::vector<std::string> const & vec,
std::string const & delim = std::string(",")); 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 #ifdef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES