X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathChar.cpp;h=03bda07cf60475c4ebaae4584ea401c613fccc12;hb=6de3c19fd63f810eed90ef3bc4469faf28e949c2;hp=9349663200618671fa836a71cbf64b69eac8d9fc;hpb=696b5d29b5d5822845eabe42bfc064c4271ade76;p=lyx.git diff --git a/src/mathed/InsetMathChar.cpp b/src/mathed/InsetMathChar.cpp index 9349663200..03bda07cf6 100644 --- a/src/mathed/InsetMathChar.cpp +++ b/src/mathed/InsetMathChar.cpp @@ -4,7 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Alejandro Aguilar Sierra - * \author André Pönitz + * \author André Pönitz * * Full author contact details are available in file CREDITS. */ @@ -12,35 +12,37 @@ #include #include "InsetMathChar.h" + #include "MathSupport.h" #include "MathStream.h" +#include "MetricsInfo.h" -#include "debug.h" #include "Dimension.h" +#include "BufferEncodings.h" +#include "LaTeXFeatures.h" #include "TextPainter.h" -#include "support/lstrings.h" - #include "frontends/FontMetrics.h" +#include "support/debug.h" +#include "support/lstrings.h" +#include "support/textutils.h" + namespace lyx { extern bool has_math_fonts; -namespace { - - bool isBinaryOp(char_type c) - { - return support::contains("+-<>=/*", static_cast(c)); - } +static bool isBinaryOp(char_type c) +{ + return support::contains("+-<>=/*", static_cast(c)); +} - bool slanted(char_type c) - { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - } +static bool slanted(char_type c) +{ + return isAlphaASCII(c) || Encodings::isMathAlpha(c); } @@ -66,7 +68,7 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const FontSetChanger dummy(mi.base, "cmm"); dim = theFontMetrics(mi.base.font).dimension(char_); } else if (!slanted(char_) && mi.base.fontname == "mathnormal") { - ShapeChanger dummy(mi.base.font, Font::UP_SHAPE); + ShapeChanger dummy(mi.base.font, UP_SHAPE); dim = theFontMetrics(mi.base.font).dimension(char_); } else { frontend::FontMetrics const & fm = theFontMetrics(mi.base.font); @@ -85,9 +87,6 @@ void InsetMathChar::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid += 2 * theFontMetrics(font_).width(' '); lyxerr << "InsetMathChar::metrics: " << dim << endl; #endif - // Cache the inset dimension. - // FIXME: put the resulting dim in BufferView. - dim_ = dim; } @@ -107,7 +106,7 @@ void InsetMathChar::draw(PainterInfo & pi, int x, int y) const FontSetChanger dummy(pi.base, "cmm"); pi.draw(x, y, char_); } else if (!slanted(char_) && pi.base.fontname == "mathnormal") { - ShapeChanger dummy(pi.base.font, Font::UP_SHAPE); + ShapeChanger dummy(pi.base.font, UP_SHAPE); pi.draw(x, y, char_); } else { pi.draw(x, y, char_); @@ -139,6 +138,13 @@ void InsetMathChar::write(WriteStream & os) const } +void InsetMathChar::validate(LaTeXFeatures & features) const +{ + if (!isASCII(char_)) + BufferEncodings::validate(char_, features, true); +} + + void InsetMathChar::normalize(NormalStream & os) const { os << "[char "; @@ -153,14 +159,80 @@ void InsetMathChar::octave(OctaveStream & os) const } +// We have a bit of a problem here. MathML wants to know whether the +// character represents an "identifier" or an "operator", and we have +// no general way of telling. So we shall guess: If it's alpha or +// mathalpha, then we'll treat it as an identifier, otherwise as an +// operator. +// Worst case: We get bad spacing, or bad italics. void InsetMathChar::mathmlize(MathStream & ms) const { + std::string entity; + switch (char_) { + case '<': entity = "<"; break; + case '>': entity = ">"; break; + case '&': entity = "&"; break; + case ' ': { + ms << from_ascii(" "); + return; + } + default: break; + } + + if (ms.inText()) { + if (entity.empty()) + ms.os().put(char_); + else + ms << from_ascii(entity); + return; + } + + if (!entity.empty()) { + ms << "" << from_ascii(entity) << ""; + return; + } + + char const * type = + (isAlphaASCII(char_) || Encodings::isMathAlpha(char_)) + ? "mi" : "mo"; + // we don't use MTag and ETag because we do not want the spacing + ms << "<" << type << ">" << char_type(char_) << ""; +} + + +void InsetMathChar::htmlize(HtmlStream & ms) const +{ + std::string entity; switch (char_) { - case '<': ms << "<"; break; - case '>': ms << ">"; break; - case '&': ms << "&"; break; - default: ms.os().put(char_); break; + case '<': entity = "<"; break; + case '>': entity = ">"; break; + case '&': entity = "&"; break; + case ' ': entity = " "; break; + default: break; + } + + bool have_entity = !entity.empty(); + + if (ms.inText()) { + if (have_entity) + ms << from_ascii(entity); + else + ms.os().put(char_); + return; } + + if (have_entity) { + // an operator, so give some space + ms << ' ' << from_ascii(entity) << ' '; + return; + } + + if (isAlphaASCII(char_) || Encodings::isMathAlpha(char_)) + // we don't use MTag and ETag because we do not want the spacing + ms << MTag("i") << char_type(char_) << ETag("i"); + else + // an operator, so give some space + ms << " " << char_type(char_) << " "; }