- revive 1.1.6 eqnarray behaviour when pressing <Del> in the last position of a

cell.
- allow additional argument to math-macros for drawing purposes


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3823 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2002-03-25 12:11:25 +00:00
parent 67fbbc0fb2
commit 4366ef931c
28 changed files with 3059 additions and 132 deletions

View File

@ -54,6 +54,8 @@ libmathed_la_SOURCES = \
math_exintinset.h \
math_factory.C \
math_factory.h \
math_fontinset.C \
math_fontinset.h \
math_fracinset.C \
math_fracinset.h \
math_fracbase.C \

File diff suppressed because it is too large Load Diff

View File

@ -278,16 +278,17 @@ Inset * InsetFormula::clone(Buffer const &, bool) const
}
void InsetFormula::write(Buffer const * buf, ostream & os) const
void InsetFormula::write(Buffer const *, ostream & os) const
{
os << "Formula ";
latex(buf, os, false, false);
WriteStream wi(os, false, false);
par_->write(wi);
}
int InsetFormula::latex(Buffer const *, ostream & os, bool fragil, bool) const
int InsetFormula::latex(Buffer const *, ostream & os, bool fragile, bool) const
{
WriteStream wi(os, fragil);
WriteStream wi(os, fragile, true);
par_->write(wi);
return wi.line();
}

View File

@ -933,7 +933,7 @@ void mathDispatchMathMacro(BufferView * bv, string const & arg)
if (arg.empty())
bv->owner()->getLyXFunc()->setErrorMessage(N_("Missing argument"));
else {
string s(arg);
string s = arg;
string const s1 = token(s, ' ', 1);
int const na = s1.empty() ? 0 : lyx::atoi(s1);
openNewInset(bv, new InsetFormulaMacro(token(s, ' ', 0), na));

View File

@ -71,7 +71,7 @@ Inset * InsetFormulaMacro::clone(Buffer const &, bool) const
void InsetFormulaMacro::write(Buffer const *, ostream & os) const
{
os << "FormulaMacro ";
WriteStream wi(os, false);
WriteStream wi(os, false, false);
par()->write(wi);
}
@ -79,7 +79,7 @@ void InsetFormulaMacro::write(Buffer const *, ostream & os) const
int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile,
bool /*free_spacing*/) const
{
WriteStream wi(os, fragile);
WriteStream wi(os, fragile, true);
par()->write(wi);
return 2;
}
@ -87,7 +87,7 @@ int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile,
int InsetFormulaMacro::ascii(Buffer const *, ostream & os, int) const
{
WriteStream wi(os, false);
WriteStream wi(os, false, true);
par()->write(wi);
return 0;
}

View File

@ -133,15 +133,25 @@ struct Selection
cursor.insert(data_.cell(0));
} else {
// mulitple cells
idx_type idx;
idx_type idx; // index of upper left cell
MathGridInset * p = cursor.enclosingGrid(idx);
col_type const numcols = min(data_.ncols(), p->ncols() - p->col(idx));
row_type const numrows = min(data_.nrows(), p->nrows() - p->row(idx));
for (row_type row = 0; row < numrows; ++row)
for (row_type row = 0; row < numrows; ++row) {
for (col_type col = 0; col < numcols; ++col) {
idx_type i = p->index(row + p->row(idx), col + p->col(idx));
p->cell(i).push_back(data_.cell(data_.index(row, col)));
}
// append the left over horizontal cells to the last column
idx_type i = p->index(row + p->row(idx), p->ncols() - 1);
for (col_type col = numcols; col < data_.ncols(); ++col)
p->cell(i).push_back(data_.cell(data_.index(row, col)));
}
// append the left over vertical cells to the last _cell_
idx_type i = p->nargs() - 1;
for (row_type row = numrows; row < data_.nrows(); ++row)
for (col_type col = 0; col < data_.ncols(); ++col)
p->cell(i).push_back(data_.cell(data_.index(row, col)));
}
}
@ -537,19 +547,17 @@ void MathCursor::erase()
return;
}
// delete empty cells if necessary
if (array().empty()) {
bool popit;
bool removeit;
par()->idxDelete(idx(), popit, removeit);
if (popit && popLeft() && removeit)
plainErase();
// delete empty cells if possible
if (array().empty())
if (par()->idxDelete(idx()))
return;
// old behaviour when in last position of cell
if (pos() == size()) {
par()->idxGlue(idx());
return;
}
if (pos() == size())
return;
MathScriptInset * p = nextAtom()->asScriptInset();
if (p) {
p->removeScript(p->hasUp());
@ -957,7 +965,7 @@ void MathCursor::normalize()
lyxerr << "this should not really happen - 2: "
<< pos() << " " << size() << " in idx: " << idx()
<< " in atom: '";
WriteStream wi(lyxerr, false);
WriteStream wi(lyxerr, false, true);
par()->write(wi);
lyxerr << "\n";
dump("error 4");

View File

@ -204,6 +204,17 @@ bool extractNumber(MathArray const & ar, int & i)
}
bool extractNumber(MathArray const & ar, double & i)
{
string s;
MathTextCodes c;
charSequence(ar.begin(), ar.end(), s, c);
istringstream is(s.c_str());
is >> i;
return is;
}
bool testString(MathInset * p, const string & str)
{
string s;

View File

@ -14,4 +14,7 @@ void maplize(MathArray const &, MapleStream &);
void mathmlize(MathArray const &, MathMLStream &);
void octavize(MathArray const &, OctaveStream &);
bool extractNumber(MathArray const & ar, int & i);
bool extractNumber(MathArray const & ar, double & i);
#endif

View File

@ -52,8 +52,6 @@ MathAtom createMathInset(latexkeys const * l)
return MathAtom(new MathStackrelInset);
case LM_TK_UNDERSET:
return MathAtom(new MathUndersetInset);
case LM_TK_KERN:
return MathAtom(new MathKernInset);
case LM_TK_BINOM:
case LM_TK_CHOOSE:
return MathAtom(new MathBinomInset);
@ -98,6 +96,9 @@ MathAtom createMathInset(string const & s)
&& s[2] >= '1' && s[2] <= '9')
return MathAtom(new MathMacroArgument(s[2] - '0'));
if (s == "lyxkern")
return MathAtom(new MathKernInset);
if (s == "xymatrix")
return MathAtom(new MathXYMatrixInset);

View File

@ -697,19 +697,16 @@ bool MathGridInset::idxEnd(idx_type & idx, pos_type & pos) const
}
void MathGridInset::idxDelete(idx_type & idx, bool & popit, bool & deleteit)
bool MathGridInset::idxDelete(idx_type & idx)
{
popit = false;
deleteit = false;
// nothing to do if we are in the middle of the last row of the inset
if (idx + ncols() > nargs())
return;
return false;
// try to delete entire sequence of ncols() empty cells if possible
for (idx_type i = idx; i < idx + ncols(); ++i)
if (cell(i).size())
return;
return false;
// move cells if necessary
for (idx_type i = index(row(idx), 0); i < idx; ++i)
@ -723,6 +720,29 @@ void MathGridInset::idxDelete(idx_type & idx, bool & popit, bool & deleteit)
// undo effect of Ctrl-Tab (i.e. pull next cell)
//if (idx + 1 != nargs())
// cell(idx).swap(cell(idx + 1));
// we handled the event..
return true;
}
// reimplement old behaviour when pressing Delete in the last position
// of a cell
void MathGridInset::idxGlue(idx_type idx)
{
col_type c = col(idx);
if (c + 1 == ncols()) {
if (row(idx) + 1 != nrows()) {
for (col_type cc = 0; cc < ncols(); ++cc)
cell(idx).push_back(cell(idx + cc + 1));
delRow(row(idx) + 1);
}
} else {
cell(idx).push_back(cell(idx + 1));
for (col_type cc = c + 2; cc < ncols(); ++cc)
cell(idx - c + cc - 1) = cell(idx - c + cc);
cell(idx - c + ncols() - 1).erase();
}
}

View File

@ -130,7 +130,9 @@ public:
///
bool idxEnd(idx_type &, pos_type &) const;
///
void idxDelete(idx_type &, bool &, bool &);
bool idxDelete(idx_type &);
/// pulls cell after pressing erase
void idxGlue(idx_type idx);
///
virtual void addRow(row_type);

View File

@ -84,7 +84,6 @@ key_type wordlist_array[] =
{"inf", LM_TK_FUNCLIM, 0},
{"it", LM_TK_OLDFONT, LM_TC_IT},
{"ker", LM_TK_FUNC, 0},
{"kern", LM_TK_KERN, 0},
{"label", LM_TK_LABEL, 0},
{"lefteqn", LM_TK_LEFTEQN, 1},
{"ldots", LM_TK_DOTS, 0},
@ -97,6 +96,7 @@ key_type wordlist_array[] =
{"ln", LM_TK_FUNC, 0},
{"log", LM_TK_FUNC, 0},
{"lyxbox", LM_TK_BOX, 0},
{"lyxnegspace", LM_TK_SPACE, 6},
{"mathbb", LM_TK_FONT, LM_TC_BB},
{"mathbf", LM_TK_FONT, LM_TC_BF},
{"mathcal", LM_TK_FONT, LM_TC_CAL},

View File

@ -40,7 +40,7 @@ int MathInset::height() const
ostream & operator<<(ostream & os, MathInset const & inset)
{
WriteStream wi(os, false);
WriteStream wi(os, false, false);
inset.write(wi);
return os;
}
@ -149,17 +149,10 @@ bool MathInset::idxEnd(idx_type &, pos_type &) const
}
void MathInset::idxDelete(idx_type &, bool & popit, bool & deleteit)
{
popit = false;
deleteit = false;
}
void MathInset::normalize(NormalStream & os) const
{
os << "[unknown ";
WriteStream wi(os.os(), false);
WriteStream wi(os.os(), false, true);
write(wi);
os << "] ";
}
@ -168,7 +161,7 @@ void MathInset::normalize(NormalStream & os) const
void MathInset::dump() const
{
lyxerr << "---------------------------------------------\n";
WriteStream wi(lyxerr, false);
WriteStream wi(lyxerr, false, true);
write(wi);
lyxerr << "\n---------------------------------------------\n";
}

View File

@ -145,9 +145,9 @@ public:
virtual bool idxEnd(idx_type & idx, pos_type & pos) const;
/// Delete a cell and move cursor
// the return value indicates whether the cursor should leave the inset
// and/or the whole inset should be deleted
virtual void idxDelete(idx_type & idx, bool & popit, bool & deleteit);
virtual bool idxDelete(idx_type &) { return false; }
/// pulls cell after pressing erase
virtual void idxGlue(idx_type) {}
// returns list of cell indices that are "between" from and to for
// selection purposes
virtual std::vector<idx_type> idxBetween(idx_type from, idx_type to) const;

View File

@ -5,23 +5,15 @@
#endif
#include "math_kerninset.h"
#include "math_extern.h"
#include "math_mathmlstream.h"
#include "math_streamstr.h"
#include "math_support.h"
#include "lyxrc.h"
#include "font.h"
MathKernInset::MathKernInset()
{}
MathKernInset::MathKernInset(LyXLength const & w)
: wid_(w)
{}
MathKernInset::MathKernInset(string const & s)
: wid_(s)
: MathNestInset(1)
{}
@ -31,31 +23,29 @@ MathInset * MathKernInset::clone() const
}
void MathKernInset::metrics(MathMetricsInfo const & mi) const
{
LyXFont font;
whichFont(font, LM_TC_TEXTRM, mi);
double t;
extractNumber(cell(0), t);
width_ = int(t * lyxfont::width('m', font));
ascent_ = 0;
descent_ = 0;
}
void MathKernInset::draw(Painter &, int, int) const
{}
void MathKernInset::metrics(MathMetricsInfo const &) const
{
ascent_ = 0;
descent_ = 0;
#ifdef WITH_WARNINGS
#warning fix this once the interface to LyXLength has improved
#endif
// this uses the numerical valu in pixels, even if the unit is cm or ex!
width_ = static_cast<int>(wid_.value());
width_ = (width_*static_cast<int>(lyxrc.zoom))/150;
//cerr << "handling kern of width " << wid_.value() << "\n";
}
void MathKernInset::write(WriteStream & os) const
{
os << "\\kern" << wid_.asLatexString() << " ";
os << "\\lyxkern" << cell(0) << "em ";
}
void MathKernInset::normalize(NormalStream & os) const
{
os << "[kern " << wid_.asLatexString() << "]";
os << "[lyxkern " << cell(0) << "em]";
}

View File

@ -2,36 +2,27 @@
#ifndef MATH_CHEATINSET_H
#define MATH_CHEATINSET_H
#include "math_diminset.h"
#include "vspace.h"
#include "LString.h"
#include "math_nestinset.h"
#ifdef __GNUG__
#pragma interface
#endif
/// The \kern primitive
/// Some hack for visual effects
class MathKernInset : public MathDimInset {
class MathKernInset : public MathNestInset {
public:
///
MathKernInset();
///
explicit MathKernInset(LyXLength const & wid);
///
explicit MathKernInset(string const & wid);
///
MathInset * clone() const;
///
void draw(Painter &, int x, int y) const;
///
void write(WriteStream & os) const;
///
void normalize(NormalStream &) const;
void normalize(NormalStream & ns) const;
///
void metrics(MathMetricsInfo const & st) const;
private:
/// width in em
LyXLength wid_;
void metrics(MathMetricsInfo const &cwmist) const;
};
#endif

View File

@ -66,6 +66,12 @@ bool MathMacro::defining() const
}
void MathMacro::expand() const
{
expanded_ = tmplate_->xcell(tmplate_->cell(1).empty() ? 0 : 1);
}
void MathMacro::metrics(MathMetricsInfo const & mi) const
{
whichFont(font_, LM_TC_TEX, mi);
@ -77,7 +83,7 @@ void MathMacro::metrics(MathMetricsInfo const & mi) const
}
if (editing()) {
expanded_ = tmplate_->xcell(0);
expand();
expanded_.metrics(mi_);
width_ = expanded_.width() + 4;
ascent_ = expanded_.ascent() + 2;
@ -100,7 +106,7 @@ void MathMacro::metrics(MathMetricsInfo const & mi) const
return;
}
expanded_ = tmplate_->xcell(0);
expand();
expanded_.data_.substitute(*this);
expanded_.metrics(mi_);
width_ = expanded_.width();
@ -232,6 +238,6 @@ void MathMacro::write(WriteStream & os) const
void MathMacro::updateExpansion() const
{
expanded_ = tmplate_->xcell(0);
expand();
expanded_.data_.substitute(*this);
}

View File

@ -84,6 +84,8 @@ private:
bool defining() const;
///
void updateExpansion() const;
///
void expand() const;
///
MathAtom & tmplate_;

View File

@ -56,10 +56,12 @@ void MathMacroTable::create(string const & name, int na, string const & text)
void MathMacroTable::create(string const & name, int na, MathArray const & ar)
void MathMacroTable::create
(string const & name, int na, MathArray const & ar1, MathArray const & ar2)
{
MathAtom t(new MathMacroTemplate(name, na));
t->cell(0) = ar;
t->cell(0) = ar1;
t->cell(1) = ar2;
macro_table[name] = t;
}

View File

@ -18,7 +18,7 @@ public:
///
static void create(string const &, int, string const &);
///
static void create(string const &, int, MathArray const &);
static void create(string const &, int, MathArray const &, MathArray const &);
///
static MathAtom & provide(string const &);
///

View File

@ -8,20 +8,17 @@
#include "debug.h"
using std::endl;
MathMacroTemplate::MathMacroTemplate()
: MathNestInset(1), numargs_(0), name_()
: MathNestInset(2), numargs_(0), name_()
{}
MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs)
: MathNestInset(1), numargs_(numargs), name_(nm)
: MathNestInset(2), numargs_(numargs), name_(nm)
{
if (numargs_ > 9)
lyxerr << "MathMacroTemplate::MathMacroTemplate: wrong # of arguments: "
<< numargs_ << endl;
<< numargs_ << std::endl;
}
@ -53,23 +50,39 @@ string const & MathMacroTemplate::name() const
void MathMacroTemplate::metrics(MathMetricsInfo const & mi) const
{
xcell(0).metrics(mi);
width_ = xcell(0).width() + 4;
ascent_ = xcell(0).ascent() + 2;
descent_ = xcell(0).descent() + 2;
xcell(1).metrics(mi);
width_ = xcell(0).width() + xcell(1).width() + 10;
ascent_ = std::max(xcell(0).ascent(), xcell(1).ascent()) + 2;
descent_ = std::max(xcell(0).descent(), xcell(1).descent()) + 2;
}
void MathMacroTemplate::draw(Painter & pain, int x, int y) const
{
int const w0 = xcell(0).width();
int const w1 = xcell(1).width();
xcell(0).draw(pain, x + 2, y + 1);
pain.rectangle(x, y - ascent(), width(), height(), LColor::blue);
pain.rectangle(x, y - ascent() + 1, w0 + 4, height(), LColor::blue);
xcell(1).draw(pain, x + 8 + w0, y + 1);
pain.rectangle(x + w0 + 6 , y - ascent() + 1, w1 + 4, height(), LColor::blue);
}
void MathMacroTemplate::write(WriteStream & os) const
{
os << "\n\\newcommand{\\" << name_.c_str() << '}';
if (numargs_ > 0)
os << '[' << numargs_ << ']';
os << '{' << cell(0) << "}\n";
if (os.latex()) {
os << "\n\\newcommand{\\" << name_.c_str() << '}';
if (numargs_ > 0)
os << '[' << numargs_ << ']';
os << '{' << cell(0) << "}\n";
} else {
// writing .lyx
os << "\n\\newcommand{\\" << name_.c_str() << '}';
if (numargs_ > 0)
os << '[' << numargs_ << ']';
os << '{' << cell(0) << '}';
// write special .tex export only if necessary
if (!cell(1).empty())
os << "\n{" << cell(1) << '}';
}
}

View File

@ -187,13 +187,13 @@ NormalStream & operator<<(NormalStream & ns, char c)
//////////////////////////////////////////////////////////////////////
WriteStream::WriteStream(ostream & os, bool fragile)
: os_(os), fragile_(fragile), firstitem_(false), line_(0)
WriteStream::WriteStream(ostream & os, bool fragile, bool latex)
: os_(os), fragile_(fragile), latex_(latex), firstitem_(false), line_(0)
{}
WriteStream::WriteStream(ostream & os)
: os_(os), fragile_(false), firstitem_(false), line_(0)
: os_(os), fragile_(false), latex_(false), firstitem_(false), line_(0)
{}

View File

@ -160,7 +160,7 @@ OctaveStream & operator<<(OctaveStream &, char);
class WriteStream {
public:
///
WriteStream(std::ostream & os, bool fragile);
WriteStream(std::ostream & os, bool fragile, bool latex);
///
explicit WriteStream(std::ostream & os_);
///
@ -168,6 +168,8 @@ public:
///
bool fragile() const { return fragile_; }
///
bool latex() const { return latex_; }
///
std::ostream & os() { return os_; }
///
bool & firstitem() { return firstitem_; }
@ -178,6 +180,8 @@ private:
std::ostream & os_;
///
bool fragile_;
/// are we writing to .tex?
int latex_;
/// are we at the beginning of an MathArray?
bool firstitem_;
///

View File

@ -757,18 +757,21 @@ bool Parser::parse_macro(string & name)
return false;
}
MathArray ar;
parse_into(ar, FLAG_BRACE_LAST);
MathArray ar1;
parse_into(ar1, FLAG_BRACE_LAST);
// we cannot handle recursive stuff at all
MathArray test;
test.push_back(createMathInset(name));
if (ar.contains(test)) {
if (ar1.contains(test)) {
lyxerr << "we cannot handle recursive macros at all.\n";
return false;
}
MathMacroTable::create(name, narg, ar);
MathArray ar2;
parse_into(ar2, FLAG_ITEM);
MathMacroTable::create(name, narg, ar1, ar2);
return true;
}
@ -1109,6 +1112,7 @@ void Parser::parse_into1(MathArray & array, unsigned flags, MathTextCodes code)
lyxerr << "unknow math inset begin '" << name << "'\n";
}
/*
else if (t.cs() == "kern") {
#ifdef WITH_WARNINGS
#warning A hack...
@ -1125,6 +1129,12 @@ void Parser::parse_into1(MathArray & array, unsigned flags, MathTextCodes code)
break;
}
array.push_back(MathAtom(new MathKernInset(s)));
*/
else if (t.cs() == "lyxkern") {
MathAtom p = createMathInset(t.cs());
parse_into(p->cell(0), flags, code);
array.push_back(p);
}
else if (t.cs() == "label") {

View File

@ -108,8 +108,6 @@ enum MathTokenEnum
///
LM_TK_NOT,
///
LM_TK_KERN,
///
LM_TK_UNDERSET,
///
LM_TK_STACK

View File

@ -9,6 +9,11 @@
#include "math_mathmlstream.h"
char const * latex_mathspace[] = {
"!", ",", ":", ";", "quad", "qquad", "lyxnegspace"
};
MathSpaceInset::MathSpaceInset(int sp)
: space_(sp)
@ -23,12 +28,16 @@ MathInset * MathSpaceInset::clone() const
void MathSpaceInset::metrics(MathMetricsInfo const &) const
{
width_ = space_ ? space_ * 2 : 2;
if (space_ > 3)
width_ *= 2;
if (space_ == 5)
width_ *= 2;
width_ += 4;
switch (space_) {
case 0: width_ = 6; break;
case 1: width_ = 6; break;
case 2: width_ = 8; break;
case 3: width_ = 10; break;
case 4: width_ = 20; break;
case 5: width_ = 40; break;
case 6: width_ = -2; break;
default: width_ = 6; break;
}
ascent_ = 4;
descent_ = 0;
}
@ -37,9 +46,10 @@ void MathSpaceInset::metrics(MathMetricsInfo const &) const
void MathSpaceInset::draw(Painter & pain, int x, int y) const
{
// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
// Sadly, HP-UX CC can't handle that kind of initialization.
// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
if (space_ == 6)
return;
int xp[4];
int yp[4];
@ -79,6 +89,6 @@ void MathSpaceInset::normalize(NormalStream & os) const
void MathSpaceInset::write(WriteStream & os) const
{
if (space_ >= 0 && space_ < 6)
if (space_ >= 0 && space_ < 7)
os << '\\' << latex_mathspace[space_] << ' ';
}

View File

@ -730,12 +730,6 @@ void math_font_max_dim(LyXFont const & font, int & asc, int & des)
}
char const * latex_mathspace[] = {
"!", ",", ":", ";", "quad", "qquad"
};
char const * math_font_name(MathTextCodes code)
{
static char const * theFontNames[] = {

View File

@ -13,8 +13,6 @@ class MathMetricsInfo;
class MathInset;
class LyXFont;
extern char const * latex_mathspace[];
void mathed_char_dim(LyXFont const &, unsigned char c,
int & asc, int & des, int & wid);
int mathed_char_width(LyXFont const &, unsigned char c);