mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Fix bug #1424: Native \sideset inset
The toolbar image is the one Uwe attached to the bug report. Note that \sideset works only for operators like \sum in the nucleus. LyX allows any content, so you might get a LaTeX error. I don't know how to prevent wrong content in the nucleus.
This commit is contained in:
parent
c0395333b2
commit
5261ae6a29
@ -1109,6 +1109,7 @@ dist_imagesmath_DATA = \
|
||||
images/math/shortparallel.png \
|
||||
images/math/shortrightarrow.png \
|
||||
images/math/shortuparrow.png \
|
||||
images/math/sideset.png \
|
||||
images/math/sigma.png \
|
||||
images/math/sigma2.png \
|
||||
images/math/sim.png \
|
||||
|
BIN
lib/images/math/sideset.png
Normal file
BIN
lib/images/math/sideset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 B |
@ -183,6 +183,7 @@ ToolbarSet
|
||||
Item "Insert sum" "math-insert \sum"
|
||||
Item "Insert integral" "math-insert \int"
|
||||
Item "Insert product" "math-insert \prod"
|
||||
Item "Insert side scripts" "math-insert \sideset"
|
||||
Separator
|
||||
Item "Insert ( )" "math-delim ( )"
|
||||
Item "Insert [ ]" "math-delim [ ]"
|
||||
|
@ -409,6 +409,7 @@ SOURCEFILESMATHED = \
|
||||
mathed/InsetMathRef.cpp \
|
||||
mathed/InsetMathRoot.cpp \
|
||||
mathed/InsetMathScript.cpp \
|
||||
mathed/InsetMathSideset.cpp \
|
||||
mathed/InsetMathSize.cpp \
|
||||
mathed/InsetMathSpace.cpp \
|
||||
mathed/InsetMathSpecialChar.cpp \
|
||||
@ -477,6 +478,7 @@ HEADERFILESMATHED = \
|
||||
mathed/InsetMathRef.h \
|
||||
mathed/InsetMathRoot.h \
|
||||
mathed/InsetMathScript.h \
|
||||
mathed/InsetMathSideset.h \
|
||||
mathed/InsetMathSize.h \
|
||||
mathed/InsetMathSpace.h \
|
||||
mathed/InsetMathSpecialChar.h \
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "FuncRequest.h"
|
||||
#include "FuncStatus.h"
|
||||
#include "InsetMathBrace.h"
|
||||
#include "InsetMathFont.h"
|
||||
#include "InsetMathScript.h"
|
||||
#include "InsetMathSymbol.h"
|
||||
#include "LaTeXFeatures.h"
|
||||
@ -28,7 +27,6 @@
|
||||
|
||||
#include "support/lassert.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -148,31 +146,6 @@ MathData & InsetMathScript::nuc()
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool isAlphaSymbol(MathAtom const & at)
|
||||
{
|
||||
if (at->asCharInset() ||
|
||||
(at->asSymbolInset() &&
|
||||
at->asSymbolInset()->isOrdAlpha()))
|
||||
return true;
|
||||
|
||||
if (at->asFontInset()) {
|
||||
MathData const & ar = at->asFontInset()->cell(0);
|
||||
for (size_t i = 0; i < ar.size(); ++i) {
|
||||
if (!(ar[i]->asCharInset() ||
|
||||
(ar[i]->asSymbolInset() &&
|
||||
ar[i]->asSymbolInset()->isOrdAlpha())))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
int InsetMathScript::dy01(BufferView const & bv, int asc, int des, int what) const
|
||||
{
|
||||
int dasc = 0;
|
||||
|
415
src/mathed/InsetMathSideset.cpp
Normal file
415
src/mathed/InsetMathSideset.cpp
Normal file
@ -0,0 +1,415 @@
|
||||
/**
|
||||
* \file InsetMathSideset.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author André Pönitz
|
||||
* \author Georg Baum
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "BufferView.h"
|
||||
#include "Cursor.h"
|
||||
#include "DispatchResult.h"
|
||||
#include "FuncRequest.h"
|
||||
#include "FuncStatus.h"
|
||||
#include "InsetMathSideset.h"
|
||||
#include "InsetMathSymbol.h"
|
||||
#include "LaTeXFeatures.h"
|
||||
#include "MathData.h"
|
||||
#include "MathStream.h"
|
||||
#include "MathSupport.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
|
||||
#include "support/lassert.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace {
|
||||
/// x spacing between the nucleus and the scripts
|
||||
int const dx = 2;
|
||||
}
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
InsetMathSideset::InsetMathSideset(Buffer * buf)
|
||||
: InsetMathNest(buf, 5)
|
||||
{}
|
||||
|
||||
|
||||
InsetMathSideset::InsetMathSideset(Buffer * buf, MathAtom const & at)
|
||||
: InsetMathNest(buf, 5)
|
||||
{
|
||||
nuc().push_back(at);
|
||||
}
|
||||
|
||||
|
||||
Inset * InsetMathSideset::clone() const
|
||||
{
|
||||
return new InsetMathSideset(*this);
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSideset::idxFirst(Cursor & cur) const
|
||||
{
|
||||
cur.idx() = 0;
|
||||
cur.pos() = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSideset::idxLast(Cursor & cur) const
|
||||
{
|
||||
cur.idx() = 0;
|
||||
cur.pos() = nuc().size();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) const
|
||||
{
|
||||
bool isCharBox = nuc().empty() ? false : isAlphaSymbol(nuc().back());
|
||||
int dasc = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
|
||||
int slevel = nuc().slevel();
|
||||
int ascdrop = dasc - slevel;
|
||||
int desdrop = isCharBox ? 0 : des + nuc().sshift();
|
||||
int mindes = nuc().mindes();
|
||||
des = max(desdrop, ascdrop);
|
||||
des = max(mindes, des);
|
||||
int minasc = nuc().minasc();
|
||||
ascdrop = isCharBox ? 0 : asc - min(tl().mindes(), tr().mindes());
|
||||
int udes = max(bl().dimension(bv).descent(), tr().dimension(bv).descent());
|
||||
asc = udes + nuc().sshift();
|
||||
asc = max(ascdrop, asc);
|
||||
asc = max(minasc, asc);
|
||||
int del = asc - udes - dasc;
|
||||
if (del + des <= 2) {
|
||||
int newdes = 2 - del;
|
||||
del = slevel - asc + udes;
|
||||
if (del > 0) {
|
||||
asc += del;
|
||||
newdes -= del;
|
||||
}
|
||||
des = max(des, newdes);
|
||||
}
|
||||
return top ? asc : des;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::dyb(BufferView const & bv) const
|
||||
{
|
||||
int nd = ndes(bv);
|
||||
int des = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
|
||||
int na = nasc(bv);
|
||||
des = dybt(bv, na, nd, false);
|
||||
return des;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::dyt(BufferView const & bv) const
|
||||
{
|
||||
int na = nasc(bv);
|
||||
int asc = max(tl().dimension(bv).descent(), tr().dimension(bv).descent());
|
||||
int nd = ndes(bv);
|
||||
asc = dybt(bv, na, nd, true);
|
||||
return asc;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::dxr(BufferView const & bv) const
|
||||
{
|
||||
return dxn(bv) + nwid(bv) + dx;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::dxn(BufferView const & bv) const
|
||||
{
|
||||
Dimension const dimb = bl().dimension(bv);
|
||||
Dimension const dimt = tl().dimension(bv);
|
||||
return max(dimb.width(), dimt.width()) + dx;
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::nwid(BufferView const & bv) const
|
||||
{
|
||||
return nuc().dimension(bv).width();
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::nasc(BufferView const & bv) const
|
||||
{
|
||||
return nuc().dimension(bv).ascent();
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::ndes(BufferView const & bv) const
|
||||
{
|
||||
return nuc().dimension(bv).descent();
|
||||
}
|
||||
|
||||
|
||||
int InsetMathSideset::nker(BufferView const * bv) const
|
||||
{
|
||||
int const kerning = nuc().kerning(bv);
|
||||
return max(kerning, 0);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
Dimension dimn;
|
||||
Dimension dimbl;
|
||||
Dimension dimtl;
|
||||
Dimension dimbr;
|
||||
Dimension dimtr;
|
||||
nuc().metrics(mi, dimn);
|
||||
ScriptChanger dummy(mi.base);
|
||||
bl().metrics(mi, dimbl);
|
||||
tl().metrics(mi, dimtl);
|
||||
br().metrics(mi, dimbr);
|
||||
tr().metrics(mi, dimtr);
|
||||
|
||||
BufferView & bv = *mi.base.bv;
|
||||
// FIXME: data copying... not very efficient.
|
||||
|
||||
dim.wid = nwid(bv) + nker(mi.base.bv) + 2 * dx;
|
||||
dim.wid += max(dimbl.width(), dimtl.width());
|
||||
dim.wid += max(dimbr.width(), dimtr.width());
|
||||
int na = nasc(bv);
|
||||
int asc = dyt(bv) + max(dimtl.ascent(), dimtr.ascent());
|
||||
dim.asc = max(na, asc);
|
||||
int nd = ndes(bv);
|
||||
int des = dyb(bv) + max(dimbl.descent(), dimbr.descent());
|
||||
dim.des = max(nd, des);
|
||||
metricsMarkers(dim);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
BufferView & bv = *pi.base.bv;
|
||||
nuc().draw(pi, x + dxn(bv), y);
|
||||
ScriptChanger dummy(pi.base);
|
||||
bl().draw(pi, x , y + dyb(bv));
|
||||
tl().draw(pi, x , y - dyt(bv));
|
||||
br().draw(pi, x + dxr(bv), y + dyb(bv));
|
||||
tr().draw(pi, x + dxr(bv), y - dyt(bv));
|
||||
drawMarkers(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
|
||||
{
|
||||
bl().metricsT(mi, dim);
|
||||
tl().metricsT(mi, dim);
|
||||
br().metricsT(mi, dim);
|
||||
tr().metricsT(mi, dim);
|
||||
nuc().metricsT(mi, dim);
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::drawT(TextPainter & pain, int x, int y) const
|
||||
{
|
||||
// FIXME: BROKEN
|
||||
nuc().drawT(pain, x + 1, y);
|
||||
bl().drawT(pain, x + 1, y + 1 /*dy0()*/);
|
||||
tl().drawT(pain, x + 1, y - 1 /*dy1()*/);
|
||||
br().drawT(pain, x + 1, y + 1 /*dy0()*/);
|
||||
tr().drawT(pain, x + 1, y - 1 /*dy1()*/);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool InsetMathSideset::idxForward(Cursor &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSideset::idxBackward(Cursor &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool InsetMathSideset::idxUpDown(Cursor & cur, bool up) const
|
||||
{
|
||||
// in nucleus?
|
||||
if (cur.idx() == 0) {
|
||||
// go up/down only if in the last position
|
||||
// or in the first position
|
||||
if (cur.pos() == cur.lastpos() || cur.pos() == 0) {
|
||||
if (cur.pos() == 0)
|
||||
cur.idx() = up ? 2 : 1;
|
||||
else
|
||||
cur.idx() = up ? 4 : 3;
|
||||
cur.pos() = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Are we 'up'?
|
||||
if (cur.idx() == 2 || cur.idx() == 4) {
|
||||
// can't go further up
|
||||
if (up)
|
||||
return false;
|
||||
// otherwise go to first or last position in the nucleus
|
||||
cur.idx() = 0;
|
||||
if (cur.idx() == 2)
|
||||
cur.pos() = 0;
|
||||
else
|
||||
cur.pos() = cur.lastpos();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Are we 'down'?
|
||||
if (cur.idx() == 1 || cur.idx() == 3) {
|
||||
// can't go further down
|
||||
if (!up)
|
||||
return false;
|
||||
// otherwise go to first or last position in the nucleus
|
||||
cur.idx() = 0;
|
||||
if (cur.idx() == 1)
|
||||
cur.pos() = 0;
|
||||
else
|
||||
cur.pos() = cur.lastpos();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::write(WriteStream & os) const
|
||||
{
|
||||
MathEnsurer ensurer(os);
|
||||
|
||||
os << "\\sideset";
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
os << '{';
|
||||
if (!cell(2*i+1).empty())
|
||||
os << "_{" << cell(2*i+1) << '}';
|
||||
if (!cell(2*i+2).empty())
|
||||
os << "^{" << cell(2*i+2) << '}';
|
||||
os << '}';
|
||||
}
|
||||
os << '{' << nuc() << '}';
|
||||
|
||||
if (lock_ && !os.latex())
|
||||
os << "\\lyxlock ";
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::normalize(NormalStream & os) const
|
||||
{
|
||||
os << "[sideset ";
|
||||
|
||||
if (!bl().empty())
|
||||
os << bl() << ' ';
|
||||
if (!tl().empty())
|
||||
os << tl() << ' ';
|
||||
|
||||
if (!nuc().empty())
|
||||
os << nuc() << ' ';
|
||||
else
|
||||
os << "[par]";
|
||||
|
||||
if (!br().empty())
|
||||
os << br() << ' ';
|
||||
if (!tr().empty())
|
||||
os << tr() << ' ';
|
||||
os << ']';
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::mathmlize(MathStream & os) const
|
||||
{
|
||||
os << MTag("mmultiscripts");
|
||||
|
||||
if (nuc().empty())
|
||||
os << "<mrow />";
|
||||
else
|
||||
os << MTag("mrow") << nuc() << ETag("mrow");
|
||||
|
||||
if (br().empty())
|
||||
os << "<none />";
|
||||
else
|
||||
os << MTag("mrow") << br() << ETag("mrow");
|
||||
if (tr().empty())
|
||||
os << "<none />";
|
||||
else
|
||||
os << MTag("mrow") << tr() << ETag("mrow");
|
||||
|
||||
if (bl().empty())
|
||||
os << "<none />";
|
||||
else
|
||||
os << MTag("mrow") << bl() << ETag("mrow");
|
||||
if (tl().empty())
|
||||
os << "<none />";
|
||||
else
|
||||
os << MTag("mrow") << tl() << ETag("mrow");
|
||||
|
||||
os << ETag("mmultiscripts");
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::htmlize(HtmlStream & os) const
|
||||
{
|
||||
bool const havebl = !bl().empty();
|
||||
bool const havetl = !tl().empty();
|
||||
bool const havebr = !br().empty();
|
||||
bool const havetr = !tr().empty();
|
||||
|
||||
if (havebl && havetl)
|
||||
os << MTag("span", "class='scripts'")
|
||||
<< MTag("span") << tl() << ETag("span")
|
||||
<< MTag("span") << bl() << ETag("span")
|
||||
<< ETag("span");
|
||||
else if (havebl)
|
||||
os << MTag("sub", "class='math'") << bl() << ETag("sub");
|
||||
else if (havetl)
|
||||
os << MTag("sup", "class='math'") << tl() << ETag("sup");
|
||||
|
||||
if (!nuc().empty())
|
||||
os << nuc();
|
||||
|
||||
if (havebr && havetr)
|
||||
os << MTag("span", "class='scripts'")
|
||||
<< MTag("span") << tr() << ETag("span")
|
||||
<< MTag("span") << br() << ETag("span")
|
||||
<< ETag("span");
|
||||
else if (havebr)
|
||||
os << MTag("sub", "class='math'") << br() << ETag("sub");
|
||||
else if (havetr)
|
||||
os << MTag("sup", "class='math'") << tr() << ETag("sup");
|
||||
}
|
||||
|
||||
|
||||
void InsetMathSideset::infoize(odocstream & os) const
|
||||
{
|
||||
os << "Sideset";
|
||||
}
|
||||
|
||||
|
||||
// the idea for dual scripts came from the eLyXer code
|
||||
void InsetMathSideset::validate(LaTeXFeatures & features) const
|
||||
{
|
||||
if (features.runparams().math_flavor == OutputParams::MathAsHTML)
|
||||
features.addCSSSnippet(
|
||||
"span.scripts{display: inline-block; vertical-align: middle; text-align:center; font-size: 75%;}\n"
|
||||
"span.scripts span {display: block;}\n"
|
||||
"sub.math{font-size: 75%;}\n"
|
||||
"sup.math{font-size: 75%;}");
|
||||
features.require("amsmath");
|
||||
InsetMathNest::validate(features);
|
||||
}
|
||||
|
||||
} // namespace lyx
|
113
src/mathed/InsetMathSideset.h
Normal file
113
src/mathed/InsetMathSideset.h
Normal file
@ -0,0 +1,113 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file InsetMathSideset.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author André Pönitz
|
||||
* \author Georg Baum
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef MATH_SIDESETINSET_H
|
||||
#define MATH_SIDESETINSET_H
|
||||
|
||||
#include "InsetMathNest.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
|
||||
/// An inset for amsmath \sideset. The 'nucleus' is always cell 0.
|
||||
/// cell(1) is the bottom left index, cell(2) is the top left index,
|
||||
/// cell(3) is the bottom right index, and cell(4) is top right index.
|
||||
class InsetMathSideset : public InsetMathNest {
|
||||
public:
|
||||
///
|
||||
InsetMathSideset(Buffer * buf);
|
||||
/// create inset with given nucleus
|
||||
InsetMathSideset(Buffer * buf, MathAtom const & at);
|
||||
///
|
||||
mode_type currentMode() const { return MATH_MODE; }
|
||||
///
|
||||
void metrics(MetricsInfo & mi, Dimension & dim) const;
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
void metricsT(TextMetricsInfo const & mi, Dimension & dim) const;
|
||||
///
|
||||
void drawT(TextPainter & pi, int x, int y) const;
|
||||
|
||||
/// move cursor backwards
|
||||
bool idxBackward(Cursor & cur) const;
|
||||
/// move cursor forward
|
||||
bool idxForward(Cursor & cur) const;
|
||||
/// move cursor up or down
|
||||
bool idxUpDown(Cursor & cur, bool up) const;
|
||||
/// Target pos when we enter the inset while moving forward
|
||||
bool idxFirst(Cursor & cur) const;
|
||||
/// Target pos when we enter the inset while moving backwards
|
||||
bool idxLast(Cursor & cur) const;
|
||||
|
||||
/// write LaTeX and Lyx code
|
||||
void write(WriteStream & os) const;
|
||||
/// write normalized content
|
||||
void normalize(NormalStream &) const;
|
||||
/// write content as MathML
|
||||
void mathmlize(MathStream &) const;
|
||||
/// write content as HTML
|
||||
void htmlize(HtmlStream &) const;
|
||||
|
||||
/// returns nucleus
|
||||
MathData const & nuc() const { return cell(0); };
|
||||
/// returns nucleus
|
||||
MathData & nuc() { return cell(0); };
|
||||
/// bottom left index
|
||||
MathData const & bl() const { return cell(1); }
|
||||
/// bottom left index
|
||||
MathData & bl() { return cell(1); }
|
||||
/// top left index
|
||||
MathData const & tl() const { return cell(2); }
|
||||
/// top left index
|
||||
MathData & tl() { return cell(2); }
|
||||
/// bottom right index
|
||||
MathData const & br() const { return cell(3); }
|
||||
/// bottom right index
|
||||
MathData & br() { return cell(3); }
|
||||
/// top right index
|
||||
MathData const & tr() const { return cell(4); }
|
||||
/// top right index
|
||||
MathData & tr() { return cell(4); }
|
||||
/// say that we have scripts
|
||||
void infoize(odocstream & os) const;
|
||||
///
|
||||
InsetCode lyxCode() const { return MATH_SCRIPT_CODE; }
|
||||
///
|
||||
void validate(LaTeXFeatures &features) const;
|
||||
private:
|
||||
virtual Inset * clone() const;
|
||||
/// returns x offset of nucleus
|
||||
int dxn(BufferView const & bv) const;
|
||||
/// returns width of nucleus if any
|
||||
int nwid(BufferView const &) const;
|
||||
/// returns y offset for either superscript or subscript
|
||||
int dybt(BufferView const &, int asc, int des, bool top) const;
|
||||
/// returns y offset for superscript
|
||||
int dyt(BufferView const &) const;
|
||||
/// returns y offset for subscript
|
||||
int dyb(BufferView const &) const;
|
||||
/// returns x offset for right subscript and superscript
|
||||
int dxr(BufferView const & bv) const;
|
||||
/// returns ascent of nucleus if any
|
||||
int nasc(BufferView const &) const;
|
||||
/// returns descent of nucleus if any
|
||||
int ndes(BufferView const &) const;
|
||||
/// returns subscript and superscript kerning of nucleus if any
|
||||
int nker(BufferView const * bv) const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif
|
@ -32,6 +32,7 @@
|
||||
#include "InsetMathPhantom.h"
|
||||
#include "InsetMathRef.h"
|
||||
#include "InsetMathRoot.h"
|
||||
#include "InsetMathSideset.h"
|
||||
#include "InsetMathSize.h"
|
||||
#include "InsetMathSpace.h"
|
||||
#include "InsetMathSpecialChar.h"
|
||||
@ -535,6 +536,8 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf)
|
||||
return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::mathrlap));
|
||||
if (s == "ensuremath")
|
||||
return MathAtom(new InsetMathEnsureMath(buf));
|
||||
if (s == "sideset")
|
||||
return MathAtom(new InsetMathSideset(buf));
|
||||
if (isSpecialChar(s))
|
||||
return MathAtom(new InsetMathSpecialChar(s));
|
||||
if (s == " ")
|
||||
|
@ -56,6 +56,7 @@ following hack as starting point to write some macros:
|
||||
#include "InsetMathRef.h"
|
||||
#include "InsetMathRoot.h"
|
||||
#include "InsetMathScript.h"
|
||||
#include "InsetMathSideset.h"
|
||||
#include "InsetMathSpace.h"
|
||||
#include "InsetMathSplit.h"
|
||||
#include "InsetMathSqrt.h"
|
||||
@ -1442,6 +1443,28 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
|
||||
parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
|
||||
}
|
||||
|
||||
else if (t.cs() == "sideset") {
|
||||
// Here allowed formats are \sideset{_{bl}^{tl}}{_{br}^{tr}}{operator}
|
||||
cell->push_back(MathAtom(new InsetMathSideset(buf)));
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
MathData ar;
|
||||
parse(ar, FLAG_ITEM, mode);
|
||||
if (!ar.empty()) {
|
||||
InsetMathScript * script = (ar.size() == 1) ?
|
||||
ar[0].nucleus()->asScriptInset() : 0;
|
||||
if (!script) {
|
||||
error("found invalid sideset argument");
|
||||
break;
|
||||
}
|
||||
if (script->hasDown())
|
||||
cell->back().nucleus()->cell(2 * i + 1) = script->down();
|
||||
if (script->hasUp())
|
||||
cell->back().nucleus()->cell(2 * i + 2) = script->up();
|
||||
}
|
||||
}
|
||||
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
|
||||
}
|
||||
|
||||
else if (t.cs() == "stackrel") {
|
||||
// Here allowed formats are \stackrel[subscript]{superscript}{operator}
|
||||
MathData ar;
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
#include "MathSupport.h"
|
||||
|
||||
#include "InsetMath.h"
|
||||
#include "InsetMathFont.h"
|
||||
#include "InsetMathSymbol.h"
|
||||
#include "MathData.h"
|
||||
#include "MathParser.h"
|
||||
#include "MathStream.h"
|
||||
@ -736,6 +737,27 @@ void augmentFont(FontInfo & font, docstring const & name)
|
||||
}
|
||||
|
||||
|
||||
bool isAlphaSymbol(MathAtom const & at)
|
||||
{
|
||||
if (at->asCharInset() ||
|
||||
(at->asSymbolInset() &&
|
||||
at->asSymbolInset()->isOrdAlpha()))
|
||||
return true;
|
||||
|
||||
if (at->asFontInset()) {
|
||||
MathData const & ar = at->asFontInset()->cell(0);
|
||||
for (size_t i = 0; i < ar.size(); ++i) {
|
||||
if (!(ar[i]->asCharInset() ||
|
||||
(ar[i]->asSymbolInset() &&
|
||||
ar[i]->asSymbolInset()->isOrdAlpha())))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
docstring asString(MathData const & ar)
|
||||
{
|
||||
odocstringstream os;
|
||||
|
@ -56,6 +56,8 @@ bool isMathFont(docstring const & name);
|
||||
|
||||
bool isTextFont(docstring const & name);
|
||||
|
||||
bool isAlphaSymbol(MathAtom const & at);
|
||||
|
||||
// converts single cell to string
|
||||
docstring asString(MathData const & ar);
|
||||
// converts single inset to string
|
||||
|
Loading…
Reference in New Issue
Block a user