mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 19:07:45 +00:00
Introduce the notion of math class
This done according to the TeXbook. This class replaces the individual isMathXXX() methods. The mathClass() method (currently unused) is provided for the following insets: * InsetMathChar (with a revised list of affected characters) * InsetMathSymbol: the class is given by the `extra' field Operators defined in lib/symbols (e.g. \log) are MC_OP * InsetMathFrac is MC_INNER (except nicefrac and units) * InsetDelimiters is MC_INNER * InsetStackrel is MC_REL * The class of InsetScript is the class of the last element of its nucleus (yes, it is a hack, but doing it right is more work). Remove the explicit spacing that was done in the different insets. The spacing will be reintroduced properly in a forthcoming commit.
This commit is contained in:
parent
0872bb78b4
commit
361bd53bc3
@ -447,14 +447,15 @@ SOURCEFILESMATHED = \
|
||||
mathed/InsetMathXArrow.cpp \
|
||||
mathed/InsetMathXYMatrix.cpp \
|
||||
mathed/InsetMathDiagram.cpp \
|
||||
mathed/MacroTable.cpp \
|
||||
mathed/MathAtom.cpp \
|
||||
mathed/MathAutoCorrect.cpp \
|
||||
mathed/MathClass.cpp \
|
||||
mathed/MathData.cpp \
|
||||
mathed/MathExtern.cpp \
|
||||
mathed/MathFactory.cpp \
|
||||
mathed/MathMacro.cpp \
|
||||
mathed/MathMacroArgument.cpp \
|
||||
mathed/MacroTable.cpp \
|
||||
mathed/MathMacroTemplate.cpp \
|
||||
mathed/MathParser.cpp \
|
||||
mathed/MathStream.cpp \
|
||||
@ -518,6 +519,7 @@ HEADERFILESMATHED = \
|
||||
mathed/InsetMathDiagram.h \
|
||||
mathed/MathAtom.h \
|
||||
mathed/MathAutoCorrect.h \
|
||||
mathed/MathClass.h \
|
||||
mathed/MathData.h \
|
||||
mathed/MathCompletionList.h \
|
||||
mathed/MathExtern.h \
|
||||
|
@ -49,6 +49,12 @@ MathData const & InsetMath::cell(idx_type) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMath::mathClass() const
|
||||
{
|
||||
return MC_ORD;
|
||||
}
|
||||
|
||||
|
||||
void InsetMath::dump() const
|
||||
{
|
||||
lyxerr << "---------------------------------------------" << endl;
|
||||
|
@ -13,6 +13,8 @@
|
||||
#ifndef MATH_INSET_H
|
||||
#define MATH_INSET_H
|
||||
|
||||
#include "MathClass.h"
|
||||
|
||||
#include "insets/Inset.h"
|
||||
|
||||
|
||||
@ -160,14 +162,11 @@ public:
|
||||
virtual InsetMathRef * asRefInset() { return 0; }
|
||||
virtual InsetMathSpecialChar const * asSpecialCharInset() const { return 0; }
|
||||
|
||||
/// The class of the math object (used primarily for spacing)
|
||||
virtual MathClass mathClass() const;
|
||||
|
||||
/// identifies things that can get scripts
|
||||
virtual bool isScriptable() const { return false; }
|
||||
/// identifies a binary operators (used for spacing)
|
||||
virtual bool isMathBin() const { return false; }
|
||||
/// identifies relational operators (used for spacing and splitting equations)
|
||||
virtual bool isMathRel() const { return false; }
|
||||
/// identifies punctuation (used for spacing)
|
||||
virtual bool isMathPunct() const { return false; }
|
||||
/// will this get written as a single block in {..}
|
||||
virtual bool extraBraces() const { return false; }
|
||||
|
||||
|
@ -121,8 +121,6 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim = fm.dimension(char_);
|
||||
kerning_ = fm.rbearing(char_) - dim.wid;
|
||||
}
|
||||
if (mathfont && isMathPunct())
|
||||
dim.wid += mathed_thinmuskip(mi.base.font);
|
||||
}
|
||||
|
||||
|
||||
@ -266,22 +264,19 @@ void InsetMathChar::htmlize(HtmlStream & ms) const
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathBin() const
|
||||
MathClass InsetMathChar::mathClass() const
|
||||
{
|
||||
return subst_ && subst_->extra == "mathbin";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathRel() const
|
||||
{
|
||||
return subst_ && subst_->extra == "mathrel";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathChar::isMathPunct() const
|
||||
{
|
||||
return support::contains(",;", static_cast<char>(char_))
|
||||
|| (subst_ && subst_->extra == "mathpunct");
|
||||
// this information comes from fontmath.ltx in LaTeX source.
|
||||
char const ch = static_cast<char>(char_);
|
||||
if (subst_)
|
||||
return string_to_class(subst_->extra);
|
||||
else if (support::contains(",;", ch))
|
||||
return MC_PUNCT;
|
||||
else if (support::contains("([", ch))
|
||||
return MC_OPEN;
|
||||
else if (support::contains(")]!?", ch))
|
||||
return MC_CLOSE;
|
||||
else return MC_ORD;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,11 +51,7 @@ public:
|
||||
///
|
||||
char_type getChar() const { return char_; }
|
||||
///
|
||||
bool isMathBin() const;
|
||||
///
|
||||
bool isMathRel() const;
|
||||
///
|
||||
bool isMathPunct() const;
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_CHAR_CODE; }
|
||||
|
||||
|
@ -115,7 +115,7 @@ void InsetMathDelim::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dw_ = 8;
|
||||
if (dw_ < 4)
|
||||
dw_ = 4;
|
||||
dim.wid = dim0.width() + 2 * dw_ + 2 * mathed_thinmuskip(mi.base.font);
|
||||
dim.wid = dim0.width() + 2 * dw_;
|
||||
dim.asc = max(a0, d0) + h0;
|
||||
dim.des = max(a0, d0) - h0;
|
||||
}
|
||||
@ -125,10 +125,9 @@ void InsetMathDelim::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
Dimension const dim = dimension(*pi.base.bv);
|
||||
int const b = y - dim.asc;
|
||||
int const skip = mathed_thinmuskip(pi.base.font);
|
||||
cell(0).draw(pi, x + dw_ + skip, y);
|
||||
mathed_draw_deco(pi, x + skip, b, dw_, dim.height(), left_);
|
||||
mathed_draw_deco(pi, x + dim.width() - dw_ - skip,
|
||||
cell(0).draw(pi, x + dw_, y);
|
||||
mathed_draw_deco(pi, x, b, dw_, dim.height(), left_);
|
||||
mathed_draw_deco(pi, x + dim.width() - dw_,
|
||||
b, dw_, dim.height(), right_);
|
||||
setPosCache(pi, x, y);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
InsetMathDelim * asDelimInset() { return this; }
|
||||
///
|
||||
InsetMathDelim const * asDelimInset() const { return this; }
|
||||
///
|
||||
MathClass mathClass() const { return MC_INNER; }
|
||||
/// is it (...)?
|
||||
bool isParenthesis() const;
|
||||
/// is it [...]?
|
||||
|
@ -123,6 +123,31 @@ bool InsetMathFrac::idxBackward(Cursor & cur) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathFrac::mathClass() const
|
||||
{
|
||||
// Generalized fractions are of inner class (see The TeXbook, p. 292)
|
||||
// But stuff from the unit/nicefrac packages are not real fractions.
|
||||
MathClass mc = MC_ORD;
|
||||
switch (kind_) {
|
||||
case ATOP:
|
||||
case OVER:
|
||||
case FRAC:
|
||||
case DFRAC:
|
||||
case TFRAC:
|
||||
case CFRAC:
|
||||
case CFRACLEFT:
|
||||
case CFRACRIGHT:
|
||||
mc = MC_INNER;
|
||||
break;
|
||||
case NICEFRAC:
|
||||
case UNITFRAC:
|
||||
case UNIT:
|
||||
break;
|
||||
}
|
||||
return mc;
|
||||
}
|
||||
|
||||
|
||||
void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim0, dim1, dim2;
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
///
|
||||
bool idxBackward(Cursor &) const;
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo &, int x, int y) const;
|
||||
@ -117,6 +119,8 @@ public:
|
||||
void write(WriteStream & os) const;
|
||||
///
|
||||
void normalize(NormalStream &) const;
|
||||
/// Generalized fractions are of inner class (see The TeXbook, p.292)
|
||||
MathClass mathClass() const { return MC_INNER; }
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
|
@ -108,7 +108,7 @@ namespace {
|
||||
size_t firstRelOp(MathData const & ar)
|
||||
{
|
||||
for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
|
||||
if ((*it)->isMathRel())
|
||||
if ((*it)->mathClass() == MC_REL)
|
||||
return it - ar.begin();
|
||||
return ar.size();
|
||||
}
|
||||
|
@ -273,6 +273,19 @@ int InsetMathScript::nker(BufferView const * bv) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathScript::mathClass() const
|
||||
{
|
||||
// FIXME: this is a hack, since the class will not be correct if
|
||||
// the nucleus has several elements.
|
||||
// The correct implementation would require to linearize the nucleus.
|
||||
if (nuc().empty())
|
||||
return MC_ORD;
|
||||
else
|
||||
// return the class of last element since this is the one that counts.
|
||||
return nuc().back()->mathClass();
|
||||
}
|
||||
|
||||
|
||||
void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim0;
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
///
|
||||
mode_type currentMode() const { return MATH_MODE; }
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
|
@ -52,6 +52,13 @@ bool InsetMathStackrel::idxUpDown(Cursor & cur, bool up) const
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathStackrel::mathClass() const
|
||||
{
|
||||
// FIXME: update this when/if \stackbin is supported
|
||||
return MC_REL;
|
||||
}
|
||||
|
||||
|
||||
void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dim1;
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
///
|
||||
bool idxUpDown(Cursor &, bool up) const;
|
||||
///
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
@ -35,7 +37,7 @@ public:
|
||||
void mathmlize(MathStream &) const;
|
||||
///
|
||||
void htmlize(HtmlStream &) const;
|
||||
///
|
||||
///
|
||||
void validate(LaTeXFeatures &) const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_STACKREL_CODE; }
|
||||
|
@ -70,7 +70,7 @@ void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.asc += h_;
|
||||
dim.des -= h_;
|
||||
}
|
||||
// set striptable_
|
||||
// set scriptable_
|
||||
scriptable_ = false;
|
||||
if (mi.base.style == LM_ST_DISPLAY)
|
||||
if (sym_->inset == "cmex" || sym_->inset == "esint" ||
|
||||
@ -92,30 +92,21 @@ InsetMath::mode_type InsetMathSymbol::currentMode() const
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathBin() const
|
||||
{
|
||||
return sym_->extra == "mathbin";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathRel() const
|
||||
{
|
||||
return sym_->extra == "mathrel";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isMathPunct() const
|
||||
{
|
||||
return sym_->extra == "mathpunct";
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isOrdAlpha() const
|
||||
{
|
||||
return sym_->extra == "mathord" || sym_->extra == "mathalpha";
|
||||
}
|
||||
|
||||
|
||||
MathClass InsetMathSymbol::mathClass() const
|
||||
{
|
||||
if (sym_->extra == "func" || sym_->extra == "funclim")
|
||||
return MC_OP;
|
||||
MathClass const mc = string_to_class(sym_->extra);
|
||||
return (mc == MC_UNKNOWN) ? MC_ORD : mc;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSymbol::isScriptable() const
|
||||
{
|
||||
return scriptable_;
|
||||
|
@ -40,11 +40,7 @@ public:
|
||||
///
|
||||
mode_type currentMode() const;
|
||||
///
|
||||
bool isMathRel() const;
|
||||
///
|
||||
bool isMathBin() const;
|
||||
///
|
||||
bool isMathPunct() const;
|
||||
MathClass mathClass() const;
|
||||
///
|
||||
bool isOrdAlpha() const;
|
||||
/// do we take scripts?
|
||||
|
82
src/mathed/MathClass.cpp
Normal file
82
src/mathed/MathClass.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* \file MathClass.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "MathClass.h"
|
||||
|
||||
#include "support/docstring.h"
|
||||
#include "support/lassert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
docstring const class_to_string(MathClass const mc)
|
||||
{
|
||||
string s;
|
||||
switch (mc) {
|
||||
case MC_ORD:
|
||||
s = "mathord";
|
||||
break;
|
||||
case MC_OP:
|
||||
s = "mathop";
|
||||
break;
|
||||
case MC_BIN:
|
||||
s = "mathbin";
|
||||
break;
|
||||
case MC_REL:
|
||||
s = "mathrel";
|
||||
break;
|
||||
case MC_OPEN:
|
||||
s = "mathopen";
|
||||
break;
|
||||
case MC_CLOSE:
|
||||
s = "mathclose";
|
||||
break;
|
||||
case MC_PUNCT:
|
||||
s = "mathpunct";
|
||||
break;
|
||||
case MC_INNER:
|
||||
s = "mathinner";
|
||||
break;
|
||||
case MC_UNKNOWN:
|
||||
LATTEST(false);
|
||||
s = "mathord";
|
||||
}
|
||||
return from_ascii(s);
|
||||
}
|
||||
|
||||
|
||||
MathClass string_to_class(docstring const &s)
|
||||
{
|
||||
if (s == "mathop")
|
||||
return MC_OP;
|
||||
else if (s == "mathbin")
|
||||
return MC_BIN;
|
||||
else if (s == "mathrel")
|
||||
return MC_REL;
|
||||
else if (s == "mathopen")
|
||||
return MC_OPEN;
|
||||
else if (s == "mathclose")
|
||||
return MC_CLOSE;
|
||||
else if (s == "mathpunct")
|
||||
return MC_PUNCT;
|
||||
else if (s == "mathinner")
|
||||
return MC_INNER;
|
||||
else if (s == "mathord")
|
||||
return MC_ORD;
|
||||
else
|
||||
return MC_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
64
src/mathed/MathClass.h
Normal file
64
src/mathed/MathClass.h
Normal file
@ -0,0 +1,64 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file MathClass.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef MATH_CLASS_H
|
||||
#define MATH_CLASS_H
|
||||
|
||||
#include "support/strfwd.h"
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
/* The TeXbook, p. 158:
|
||||
*
|
||||
* There are thirteen kinds of atoms, each of which might act
|
||||
* differently in a formula; for example, ‘(’ is an Open atom because
|
||||
* it comes from an opening. Here is a complete list of the different
|
||||
* kinds:
|
||||
|
||||
* + Ord: an ordinary atom like ‘x’
|
||||
* + Op: a large operator atom like ‘\sum’
|
||||
* + Bin: a binary operation atom like ‘+’
|
||||
* + Rel: a relation atom like ‘=’
|
||||
* + Open: an opening atom like ‘(’
|
||||
* + Close: a closing atom like ‘)’
|
||||
* + Punct: a punctuation atom like ‘,’
|
||||
* + Inner: an inner atom like ‘\frac{1}{2}’
|
||||
* + Over: an overline atom like ‘\overline{x}’
|
||||
* + Under: an underline atom like ‘\underline{x}’
|
||||
* + Acc: an accented atom like ‘\hat{x}’
|
||||
* + Rad: a radical atom like ‘\sqrt{2}’
|
||||
* + Vcent: a vbox to be centered, produced by \vcenter.
|
||||
*
|
||||
* Over, Under, Acc, Rad and Vcent are not considered in the enum
|
||||
* below. The relvant elements will be considered as Ord.
|
||||
*/
|
||||
enum MathClass {
|
||||
MC_ORD,
|
||||
MC_OP,
|
||||
MC_BIN,
|
||||
MC_REL,
|
||||
MC_OPEN,
|
||||
MC_CLOSE,
|
||||
MC_PUNCT,
|
||||
MC_INNER,
|
||||
MC_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
MathClass string_to_class(docstring const &);
|
||||
|
||||
docstring const class_to_string(MathClass);
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif
|
@ -671,13 +671,6 @@ void mathedSymbolDim(MetricsInfo & mi, Dimension & dim, latexkeys const * sym)
|
||||
std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
|
||||
Changer dummy = mi.base.changeFontSet(font);
|
||||
mathed_string_dim(mi.base.font, sym->draw, dim);
|
||||
// seperate things a bit
|
||||
if (sym->extra == "mathbin")
|
||||
dim.wid += 2 * mathed_medmuskip(mi.base.font);
|
||||
else if (sym->extra == "mathrel")
|
||||
dim.wid += 2 * mathed_thickmuskip(mi.base.font);
|
||||
else if (sym->extra == "mathpunct")
|
||||
dim.wid += mathed_thinmuskip(mi.base.font);
|
||||
}
|
||||
|
||||
|
||||
@ -693,10 +686,6 @@ void mathedSymbolDraw(PainterInfo & pi, int x, int y, latexkeys const * sym)
|
||||
sym->extra == "mathalpha" &&
|
||||
pi.base.fontname == "mathit";
|
||||
std::string const font = italic_upcase_greek ? "cmm" : sym->inset;
|
||||
if (sym->extra == "mathbin")
|
||||
x += mathed_medmuskip(pi.base.font);
|
||||
else if (sym->extra == "mathrel")
|
||||
x += mathed_thickmuskip(pi.base.font);
|
||||
|
||||
Changer dummy = pi.base.changeFontSet(font);
|
||||
pi.draw(x, y, sym->draw);
|
||||
|
Loading…
Reference in New Issue
Block a user