2003-08-19 13:00:56 +00:00
|
|
|
/**
|
2007-04-25 03:01:35 +00:00
|
|
|
* \file InsetMathSpace.cpp
|
2003-08-19 13:00:56 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2003-08-19 13:00:56 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathSpace.h"
|
2007-04-26 16:05:57 +00:00
|
|
|
#include "MathData.h"
|
2008-12-22 18:12:32 +00:00
|
|
|
#include "MathFactory.h"
|
2006-10-22 10:15:23 +00:00
|
|
|
#include "MathStream.h"
|
2008-12-22 18:12:32 +00:00
|
|
|
#include "MathSupport.h"
|
2004-11-07 10:13:59 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
#include "BufferView.h"
|
|
|
|
#include "Cursor.h"
|
|
|
|
#include "FuncRequest.h"
|
|
|
|
#include "FuncStatus.h"
|
2002-09-20 12:36:36 +00:00
|
|
|
#include "LaTeXFeatures.h"
|
2016-06-04 08:41:13 +00:00
|
|
|
#include "MetricsInfo.h"
|
2001-02-13 13:28:32 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
#include "insets/InsetSpace.h"
|
|
|
|
|
|
|
|
#include "frontends/Application.h"
|
2004-11-07 10:13:59 +00:00
|
|
|
#include "frontends/Painter.h"
|
2003-10-06 15:43:21 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
#include "support/lassert.h"
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2002-06-25 13:19:50 +00:00
|
|
|
|
2007-04-22 08:41:50 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
struct SpaceInfo {
|
|
|
|
string name;
|
|
|
|
int width;
|
|
|
|
InsetSpaceParams::Kind kind;
|
|
|
|
bool negative;
|
|
|
|
bool visible;
|
|
|
|
bool custom;
|
2011-10-23 20:19:49 +00:00
|
|
|
bool escape; ///< whether a backslash needs to be added for writing
|
2008-12-22 18:12:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
SpaceInfo space_info[] = {
|
2011-10-23 20:19:49 +00:00
|
|
|
// name width kind negative visible custom escape
|
|
|
|
{"!", 6, InsetSpaceParams::NEGTHIN, true, true, false, true},
|
|
|
|
{"negthinspace", 6, InsetSpaceParams::NEGTHIN, true, true, false, true},
|
|
|
|
{"negmedspace", 8, InsetSpaceParams::NEGMEDIUM, true, true, false, true},
|
|
|
|
{"negthickspace", 10, InsetSpaceParams::NEGTHICK, true, true, false, true},
|
|
|
|
{",", 6, InsetSpaceParams::THIN, false, true, false, true},
|
|
|
|
{"thinspace", 6, InsetSpaceParams::THIN, false, true, false, true},
|
|
|
|
{":", 8, InsetSpaceParams::MEDIUM, false, true, false, true},
|
|
|
|
{"medspace", 8, InsetSpaceParams::MEDIUM, false, true, false, true},
|
|
|
|
{";", 10, InsetSpaceParams::THICK, false, true, false, true},
|
|
|
|
{"thickspace", 10, InsetSpaceParams::THICK, false, true, false, true},
|
|
|
|
{"enskip", 10, InsetSpaceParams::ENSKIP, false, true, false, true},
|
|
|
|
{"enspace", 10, InsetSpaceParams::ENSPACE, false, true, false, true},
|
|
|
|
{"quad", 20, InsetSpaceParams::QUAD, false, true, false, true},
|
|
|
|
{"qquad", 40, InsetSpaceParams::QQUAD, false, true, false, true},
|
|
|
|
{"lyxnegspace", -2, InsetSpaceParams::NEGTHIN, true, false, false, true},
|
|
|
|
{"lyxposspace", 2, InsetSpaceParams::THIN, false, false, false, true},
|
|
|
|
{"hfill", 80, InsetSpaceParams::HFILL, false, true, false, true},
|
|
|
|
{"hspace*{\\fill}", 80, InsetSpaceParams::HFILL_PROTECTED, false, true, false, true},
|
|
|
|
{"hspace*", 0, InsetSpaceParams::CUSTOM_PROTECTED,false, true, true, true},
|
|
|
|
{"hspace", 0, InsetSpaceParams::CUSTOM, false, true, true, true},
|
|
|
|
{" ", 10, InsetSpaceParams::NORMAL, false, true, false, true},
|
|
|
|
{"~", 10, InsetSpaceParams::PROTECTED, false, true, false, false},
|
2002-03-25 12:11:25 +00:00
|
|
|
};
|
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
int const nSpace = sizeof(space_info)/sizeof(SpaceInfo);
|
|
|
|
int const defaultSpace = 4;
|
2001-08-09 10:48:50 +00:00
|
|
|
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace
|
2002-06-25 13:19:50 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
InsetMathSpace::InsetMathSpace()
|
|
|
|
: space_(defaultSpace)
|
|
|
|
{
|
2001-02-28 11:56:36 +00:00
|
|
|
}
|
|
|
|
|
2007-04-22 08:26:06 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
InsetMathSpace::InsetMathSpace(string const & name, string const & length)
|
|
|
|
: space_(defaultSpace)
|
2007-04-22 08:26:06 +00:00
|
|
|
{
|
2008-12-22 18:12:32 +00:00
|
|
|
for (int i = 0; i < nSpace; ++i)
|
|
|
|
if (space_info[i].name == name) {
|
|
|
|
space_ = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (space_info[space_].custom) {
|
|
|
|
length_ = Length(length);
|
|
|
|
if (length_.zero() || length_.empty()) {
|
|
|
|
length_.value(1.0);
|
|
|
|
length_.unit(Length::EM);
|
|
|
|
}
|
|
|
|
}
|
2007-04-22 08:26:06 +00:00
|
|
|
}
|
|
|
|
|
2001-02-28 11:56:36 +00:00
|
|
|
|
2011-08-29 14:07:30 +00:00
|
|
|
InsetMathSpace::InsetMathSpace(Length const & length, bool const prot)
|
2008-12-22 18:12:32 +00:00
|
|
|
: space_(defaultSpace), length_(length)
|
2004-04-08 15:55:50 +00:00
|
|
|
{
|
2007-04-22 08:26:06 +00:00
|
|
|
for (int i = 0; i < nSpace; ++i)
|
2011-08-29 14:07:30 +00:00
|
|
|
if ((prot && space_info[i].name == "hspace*")
|
|
|
|
|| (!prot && space_info[i].name == "hspace")) {
|
2007-04-22 08:26:06 +00:00
|
|
|
space_ = i;
|
2008-12-22 18:12:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-30 18:03:17 +00:00
|
|
|
Inset * InsetMathSpace::clone() const
|
2002-03-21 17:42:56 +00:00
|
|
|
{
|
2007-08-30 18:03:17 +00:00
|
|
|
return new InsetMathSpace(*this);
|
2004-04-08 15:55:50 +00:00
|
|
|
}
|
|
|
|
|
2002-03-21 17:42:56 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
void InsetMathSpace::metrics(MetricsInfo & mi, Dimension & dim) const
|
2004-04-08 15:55:50 +00:00
|
|
|
{
|
2016-11-22 10:26:15 +00:00
|
|
|
Changer dummy = mi.base.changeEnsureMath();
|
2008-12-22 18:12:32 +00:00
|
|
|
dim.asc = 4;
|
|
|
|
dim.des = 0;
|
|
|
|
if (space_info[space_].custom)
|
2018-01-05 18:59:31 +00:00
|
|
|
dim.wid = abs(mi.base.inPixels(length_));
|
2008-12-22 18:12:32 +00:00
|
|
|
else
|
|
|
|
dim.wid = space_info[space_].width;
|
2004-04-08 15:55:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::draw(PainterInfo & pi, int x, int y) const
|
2004-04-08 15:55:50 +00:00
|
|
|
{
|
2016-11-22 10:26:15 +00:00
|
|
|
Changer dummy = pi.base.changeEnsureMath();
|
2004-04-08 15:55:50 +00:00
|
|
|
// 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}};
|
2008-12-22 18:12:32 +00:00
|
|
|
if (!space_info[space_].visible)
|
2002-03-25 12:11:25 +00:00
|
|
|
return;
|
2002-03-21 17:42:56 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
Dimension const dim = dimension(*pi.base.bv);
|
2001-10-22 15:37:49 +00:00
|
|
|
int xp[4];
|
|
|
|
int yp[4];
|
2008-12-22 18:12:32 +00:00
|
|
|
int w = dim.wid;
|
2002-03-21 17:42:56 +00:00
|
|
|
|
2004-04-08 15:55:50 +00:00
|
|
|
xp[0] = ++x; yp[0] = y - 3;
|
|
|
|
xp[1] = x; yp[1] = y;
|
|
|
|
xp[2] = x + w - 2; yp[2] = y;
|
|
|
|
xp[3] = x + w - 2; yp[3] = y - 3;
|
2002-03-21 17:42:56 +00:00
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
pi.pain.lines(xp, yp, 4,
|
|
|
|
space_info[space_].custom ?
|
|
|
|
Color_special :
|
|
|
|
(isNegative() ? Color_latex : Color_math));
|
2001-10-22 15:37:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::incSpace()
|
2001-02-13 19:10:18 +00:00
|
|
|
{
|
2008-12-22 18:12:32 +00:00
|
|
|
int const oldwidth = space_info[space_].width;
|
|
|
|
do
|
|
|
|
space_ = (space_ + 1) % nSpace;
|
|
|
|
while ((space_info[space_].width == oldwidth && !space_info[space_].custom) ||
|
|
|
|
!space_info[space_].visible);
|
|
|
|
if (space_info[space_].custom && (length_.zero() || length_.empty())) {
|
|
|
|
length_.value(1.0);
|
|
|
|
length_.unit(Length::EM);
|
|
|
|
}
|
2001-02-13 19:10:18 +00:00
|
|
|
}
|
2001-11-15 14:14:37 +00:00
|
|
|
|
2003-03-11 09:25:47 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::validate(LaTeXFeatures & features) const
|
2002-09-20 12:36:36 +00:00
|
|
|
{
|
2008-12-22 18:12:32 +00:00
|
|
|
if (space_info[space_].name == "negmedspace" ||
|
|
|
|
space_info[space_].name == "negthickspace")
|
|
|
|
features.require("amsmath");
|
2002-09-20 12:36:36 +00:00
|
|
|
}
|
|
|
|
|
2001-11-15 14:14:37 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::maple(MapleStream & os) const
|
2001-11-15 14:14:37 +00:00
|
|
|
{
|
|
|
|
os << ' ';
|
|
|
|
}
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::mathematica(MathematicaStream & os) const
|
2002-07-01 11:17:14 +00:00
|
|
|
{
|
|
|
|
os << ' ';
|
|
|
|
}
|
|
|
|
|
2001-11-15 14:14:37 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::octave(OctaveStream & os) const
|
2001-11-15 14:14:37 +00:00
|
|
|
{
|
|
|
|
os << ' ';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-26 19:02:46 +00:00
|
|
|
void InsetMathSpace::mathmlize(MathMLStream & ms) const
|
2009-11-14 21:38:28 +00:00
|
|
|
{
|
|
|
|
SpaceInfo const & si = space_info[space_];
|
|
|
|
if (si.negative || !si.visible)
|
2009-12-31 15:46:39 +00:00
|
|
|
return;
|
2009-11-14 21:38:28 +00:00
|
|
|
string l;
|
|
|
|
if (si.custom)
|
|
|
|
l = length_.asHTMLString();
|
2022-12-26 19:35:26 +00:00
|
|
|
else if (si.kind != InsetSpaceParams::MEDIUM)
|
|
|
|
l = to_string(si.width) + "px";
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2021-05-25 01:29:20 +00:00
|
|
|
std::string attr;
|
2009-11-14 21:38:28 +00:00
|
|
|
if (!l.empty())
|
2021-05-25 01:29:20 +00:00
|
|
|
attr = "width=\"" + l + "\"";
|
|
|
|
|
|
|
|
ms << CTag("mspace", attr);
|
2009-11-14 21:38:28 +00:00
|
|
|
}
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2010-03-31 20:47:55 +00:00
|
|
|
void InsetMathSpace::htmlize(HtmlStream & ms) const
|
|
|
|
{
|
|
|
|
SpaceInfo const & si = space_info[space_];
|
|
|
|
switch (si.kind) {
|
|
|
|
case InsetSpaceParams::THIN:
|
2023-07-17 15:14:50 +00:00
|
|
|
ms << from_ascii(" "); // HTML:  
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
case InsetSpaceParams::MEDIUM:
|
2022-12-23 01:16:08 +00:00
|
|
|
ms << from_ascii(" ");
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
case InsetSpaceParams::THICK:
|
2022-12-26 19:35:26 +00:00
|
|
|
ms << from_ascii(" "); // HTML:  
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
case InsetSpaceParams::ENSKIP:
|
2011-08-29 14:07:30 +00:00
|
|
|
case InsetSpaceParams::ENSPACE:
|
2022-12-26 19:35:26 +00:00
|
|
|
ms << from_ascii(" "); // HTML:  
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
case InsetSpaceParams::QUAD:
|
2022-12-26 19:35:26 +00:00
|
|
|
ms << from_ascii(" "); // HTML:  
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
case InsetSpaceParams::QQUAD:
|
2022-12-26 19:35:26 +00:00
|
|
|
ms << from_ascii("  "); // HTML:   
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
2011-08-29 14:07:30 +00:00
|
|
|
case InsetSpaceParams::HFILL:
|
|
|
|
case InsetSpaceParams::HFILL_PROTECTED:
|
|
|
|
// FIXME: is there a useful HTML entity?
|
|
|
|
break;
|
|
|
|
case InsetSpaceParams::CUSTOM:
|
|
|
|
case InsetSpaceParams::CUSTOM_PROTECTED: {
|
2010-03-31 20:47:55 +00:00
|
|
|
string l = length_.asHTMLString();
|
2017-07-03 17:53:14 +00:00
|
|
|
ms << MTag("span", "width='" + l + "'")
|
2022-12-23 01:16:08 +00:00
|
|
|
<< from_ascii(" ") << ETag("span");
|
2010-03-31 20:47:55 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-10-23 20:19:49 +00:00
|
|
|
case InsetSpaceParams::NORMAL:
|
|
|
|
case InsetSpaceParams::PROTECTED:
|
2022-12-23 01:16:08 +00:00
|
|
|
ms << from_ascii(" ");
|
2011-10-23 20:19:49 +00:00
|
|
|
break;
|
2010-03-31 20:47:55 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathSpace::normalize(NormalStream & os) const
|
2001-11-15 14:14:37 +00:00
|
|
|
{
|
2002-08-22 13:02:14 +00:00
|
|
|
os << "[space " << int(space_) << "] ";
|
2001-11-15 14:14:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-26 19:04:36 +00:00
|
|
|
void InsetMathSpace::write(TeXMathStream & os) const
|
2001-11-15 14:14:37 +00:00
|
|
|
{
|
2016-09-10 16:32:44 +00:00
|
|
|
// All kinds work in text and math mode, so simply suspend
|
|
|
|
// writing a possibly pending mode closing brace.
|
|
|
|
MathEnsurer ensurer(os, false);
|
2011-10-23 20:19:49 +00:00
|
|
|
if (space_info[space_].escape)
|
|
|
|
os << '\\';
|
|
|
|
os << space_info[space_].name.c_str();
|
2008-12-22 18:12:32 +00:00
|
|
|
if (space_info[space_].custom)
|
|
|
|
os << '{' << length_.asLatexString().c_str() << '}';
|
2014-11-04 20:36:10 +00:00
|
|
|
else if (space_info[space_].escape && space_info[space_].name.length() > 1)
|
2002-08-22 10:04:11 +00:00
|
|
|
os.pendingSpace(true);
|
2008-12-22 18:12:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-21 09:28:33 +00:00
|
|
|
InsetSpaceParams InsetMathSpace::params() const
|
2008-12-22 18:12:32 +00:00
|
|
|
{
|
|
|
|
InsetSpaceParams isp(true);
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(space_info[space_].visible, return isp);
|
2008-12-22 18:12:32 +00:00
|
|
|
isp.kind = space_info[space_].kind;
|
2009-07-21 11:51:43 +00:00
|
|
|
isp.length = GlueLength(length_);
|
2010-02-21 09:28:33 +00:00
|
|
|
return isp;
|
2008-12-22 18:12:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-29 14:48:55 +00:00
|
|
|
string InsetMathSpace::contextMenuName() const
|
2008-12-22 18:12:32 +00:00
|
|
|
{
|
2011-10-29 14:48:55 +00:00
|
|
|
return "context-mathspace";
|
2008-12-22 18:12:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
|
|
|
|
FuncStatus & status) const
|
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2008-12-22 18:12:32 +00:00
|
|
|
// we handle these
|
|
|
|
case LFUN_INSET_MODIFY:
|
|
|
|
case LFUN_INSET_DIALOG_UPDATE:
|
|
|
|
case LFUN_MOUSE_RELEASE:
|
|
|
|
status.setEnabled(true);
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
bool retval = InsetMath::getStatus(cur, cmd, status);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetMathSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
|
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2008-12-22 18:12:32 +00:00
|
|
|
case LFUN_INSET_MODIFY:
|
|
|
|
if (cmd.getArg(0) == "mathspace") {
|
|
|
|
MathData ar;
|
|
|
|
if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
|
2021-01-05 23:22:09 +00:00
|
|
|
Buffer * buf = buffer_;
|
2010-11-29 09:47:46 +00:00
|
|
|
cur.recordUndo();
|
2008-12-22 18:12:32 +00:00
|
|
|
*this = *ar[0].nucleus()->asSpaceInset();
|
2018-12-13 09:27:20 +00:00
|
|
|
buffer_ = buf;
|
2008-12-22 18:12:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_MOUSE_RELEASE:
|
2017-02-18 22:03:53 +00:00
|
|
|
if (cmd.button() == mouse_button::button1 && !cur.selection()) {
|
2010-02-21 09:28:33 +00:00
|
|
|
showInsetDialog(&cur.bv());
|
2008-12-22 18:12:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
InsetMath::doDispatch(cur, cmd);
|
|
|
|
break;
|
2002-08-22 10:04:11 +00:00
|
|
|
}
|
2001-11-15 14:14:37 +00:00
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2008-12-22 18:12:32 +00:00
|
|
|
bool InsetMathSpace::isNegative() const
|
|
|
|
{
|
|
|
|
if (space_info[space_].custom)
|
|
|
|
return length_.value() < 0;
|
|
|
|
return space_info[space_].negative;
|
|
|
|
}
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|