InsetMathScript.h
InsetMathSize.h
InsetMathSpace.h
+ InsetMathSpecialChar.h
InsetMathSplit.h
InsetMathSqrt.h
InsetMathStackrel.h
InsetMathScript.cpp
InsetMathSize.cpp
InsetMathSpace.cpp
+ InsetMathSpecialChar.cpp
InsetMathSplit.cpp
InsetMathSqrt.cpp
InsetMathStackrel.cpp
deg lyxblacktext 0 0 func x
bmod lyxblacktext 0 0 func x
-{ mathrm 0 0 special x
-} mathrm 0 0 special x
-$ mathrm 0 0 special x
-% mathrm 0 0 special x
-& mathrm 0 0 special x
-## don't remove the space from the beginning of the next line
- # mathrm 0 0 special x
-
#
iffont msb
\def\Join{\ltimes\kern-18.5mu\rtimes}
endif
-\def\mathcircumflex{\mbox{\^{}}}{\^}
# Fixme: latin-1 chars in text file
\def\AA{\AA}{Å}
\def\O{\O}{Ø}
mathed/InsetMathScript.cpp \
mathed/InsetMathSize.cpp \
mathed/InsetMathSpace.cpp \
+ mathed/InsetMathSpecialChar.cpp \
mathed/InsetMathSplit.cpp \
mathed/InsetMathSqrt.cpp \
mathed/InsetMathStackrel.cpp \
mathed/InsetMathScript.h \
mathed/InsetMathSize.h \
mathed/InsetMathSpace.h \
+ mathed/InsetMathSpecialChar.h \
mathed/InsetMathSplit.h \
mathed/InsetMathSqrt.h \
mathed/InsetMathStackrel.h \
class InsetMathScript;
class InsetMathString;
class InsetMathSpace;
+class InsetMathSpecialChar;
class InsetMathSymbol;
class InsetMathUnknown;
virtual InsetMathUnknown * asUnknownInset() { return 0; }
virtual InsetMathUnknown const * asUnknownInset() const { return 0; }
virtual InsetMathRef * asRefInset() { return 0; }
+ virtual InsetMathSpecialChar const * asSpecialCharInset() const { return 0; }
/// identifies things that can get scripts
virtual bool isScriptable() const { return false; }
cur.niceInsert(createInsetMath("textbackslash"));
else
cur.niceInsert(createInsetMath("backslash"));
+ } else if (c == '^' && currentMode() == InsetMath::MATH_MODE) {
+ cur.backspace();
+ cur.niceInsert(createInsetMath("mathcircumflex"));
} else if (c == '{') {
cur.backspace();
cur.niceInsert(MathAtom(new InsetMathBrace));
return cur.pos() != cur.lastpos();
}
- // These shouldn't work in text mode:
+ // These should be treated differently when not in text mode:
if (currentMode() != InsetMath::TEXT_MODE) {
if (c == '_') {
script(cur, false, save_selection);
cur.niceInsert(createInsetMath("sim"));
return true;
}
+ } else {
+ if (c == '^') {
+ cur.niceInsert(createInsetMath("textasciicircum"));
+ return true;
+ }
+ if (c == '~') {
+ cur.niceInsert(createInsetMath("textasciitilde"));
+ return true;
+ }
}
if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' ||
- c == '%' || c == '_' || c == '^') {
+ c == '%' || c == '_') {
cur.niceInsert(createInsetMath(docstring(1, c)));
return true;
}
--- /dev/null
+/**
+ * \file InsetMathSpecialChar.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Enrico Forestieri
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "InsetMathSpecialChar.h"
+
+#include "MathSupport.h"
+#include "MathStream.h"
+#include "MetricsInfo.h"
+
+#include "Dimension.h"
+#include "LaTeXFeatures.h"
+#include "TextPainter.h"
+
+#include "frontends/FontMetrics.h"
+
+#include "support/lassert.h"
+
+
+namespace lyx {
+
+
+InsetMathSpecialChar::InsetMathSpecialChar(docstring name)
+ : name_(name), kerning_(0)
+{
+ if (name.size() != 1) {
+ if (name == from_ascii("textasciicircum")
+ || name == from_ascii("mathcircumflex"))
+ char_ = '^';
+ else if (name == from_ascii("textasciitilde"))
+ char_ = '~';
+ else if (name == from_ascii("textbackslash"))
+ char_ = '\\';
+ else
+ LASSERT(false, /**/);
+ } else
+ char_ = name.at(0);
+}
+
+
+
+Inset * InsetMathSpecialChar::clone() const
+{
+ return new InsetMathSpecialChar(*this);
+}
+
+
+void InsetMathSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ if (mi.base.fontname == "mathnormal") {
+ ShapeChanger dummy(mi.base.font, UP_SHAPE);
+ dim = theFontMetrics(mi.base.font).dimension(char_);
+ } else {
+ frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
+ dim = fm.dimension(char_);
+ kerning_ = fm.rbearing(char_) - dim.wid;
+ }
+}
+
+
+void InsetMathSpecialChar::draw(PainterInfo & pi, int x, int y) const
+{
+ if (pi.base.fontname == "mathnormal") {
+ ShapeChanger dummy(pi.base.font, UP_SHAPE);
+ pi.draw(x, y, char_);
+ } else {
+ pi.draw(x, y, char_);
+ }
+}
+
+
+void InsetMathSpecialChar::metricsT(TextMetricsInfo const &, Dimension & dim) const
+{
+ dim.wid = 1;
+ dim.asc = 1;
+ dim.des = 0;
+}
+
+
+void InsetMathSpecialChar::drawT(TextPainter & pain, int x, int y) const
+{
+ pain.draw(x, y, char_);
+}
+
+
+void InsetMathSpecialChar::write(WriteStream & os) const
+{
+ os << '\\' << name_;
+ if (name_.size() != 1)
+ os.pendingSpace(true);
+}
+
+
+void InsetMathSpecialChar::validate(LaTeXFeatures & features) const
+{
+ if (name_ == "mathcircumflex")
+ features.require("mathcircumflex");
+}
+
+
+void InsetMathSpecialChar::normalize(NormalStream & os) const
+{
+ os << "[char ";
+ os.os().put(char_);
+ os << " mathalpha]";
+}
+
+
+void InsetMathSpecialChar::maple(MapleStream & os) const
+{
+ os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::mathematica(MathematicaStream & os) const
+{
+ os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::octave(OctaveStream & os) const
+{
+ os.os().put(char_);
+}
+
+
+void InsetMathSpecialChar::mathmlize(MathStream & ms) const
+{
+ switch (char_) {
+ case '&':
+ ms << "&";
+ break;
+ default:
+ ms.os().put(char_);
+ break;
+ }
+}
+
+
+} // namespace lyx
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file InsetMathSpecialChar.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Enrico Forestieri
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef MATH_SPECIALCHARINSET_H
+#define MATH_SPECIALCHARINSET_H
+
+#include "InsetMath.h"
+
+namespace lyx {
+
+/// The special character inset.
+class InsetMathSpecialChar : public InsetMath {
+public:
+ ///
+ explicit InsetMathSpecialChar(docstring name);
+ ///
+ void setBuffer(Buffer &) {}
+ ///
+ 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 &, int x, int y) const;
+ ///
+ int kerning(BufferView const *) const { return kerning_; }
+ ///
+ void write(WriteStream & os) const;
+ ///
+ void validate(LaTeXFeatures & features) const;
+ ///
+ void normalize(NormalStream & ns) const;
+ ///
+ void octave(OctaveStream & os) const;
+ ///
+ void maple(MapleStream &) const;
+ ///
+ void mathematica(MathematicaStream &) const;
+ ///
+ void mathmlize(MathStream & ms) const;
+ /// identifies SpecialChar insets
+ InsetMathSpecialChar const * asSpecialCharInset() const { return this; }
+ ///
+ docstring name() const { return name_; }
+ ///
+ char_type getChar() const { return char_; }
+
+private:
+ virtual Inset * clone() const;
+ /// the latex name
+ docstring name_;
+ /// the displayed character
+ char_type char_;
+ /// cached kerning for superscript
+ mutable int kerning_;
+};
+
+} // namespace lyx
+
+#endif
#include "InsetMathRoot.h"
#include "InsetMathSize.h"
#include "InsetMathSpace.h"
+#include "InsetMathSpecialChar.h"
#include "InsetMathSplit.h"
#include "InsetMathSqrt.h"
#include "InsetMathStackrel.h"
}
+bool isSpecialChar(docstring name)
+{
+ if (name.size() != 1) {
+ string const s = to_ascii(name);
+ return s == "textasciicircum" || s == "mathcircumflex" ||
+ s == "textasciitilde" || s == "textbackslash";
+ } else {
+ char_type const c = name.at(0);
+ return c == '{' || c == '}' || c == '&' || c == '$' ||
+ c == '#' || c == '%' || c == '_';
+ }
+}
+
+
} // namespace anon
MathWordList const & mathedWordList()
return MathAtom(new InsetMathPhantom(InsetMathPhantom::vphantom));
if (s == "ensuremath")
return MathAtom(new InsetMathEnsureMath);
+ if (isSpecialChar(s))
+ return MathAtom(new InsetMathSpecialChar(s));
return MathAtom(new MathMacro(s));
}
if (!requires_.empty())
features.require(requires_);
- if (name() == "binom" || name() == "mathcircumflex")
- features.require(to_utf8(name()));
+ if (name() == "binom")
+ features.require("binom");
// validate the cells and the definition
if (displayMode() == DISPLAY_NORMAL) {
}
-docstring escapeSpecialChars(docstring const & str)
+docstring escapeSpecialChars(docstring const & str, bool textmode)
{
+ docstring const backslash = textmode ? from_ascii("\\textbackslash ")
+ : from_ascii("\\backslash ");
+ docstring const caret = textmode ? from_ascii("\\textasciicircum ")
+ : from_ascii("\\mathcircumflex ");
+
return subst(subst(subst(subst(subst(subst(subst(subst(subst(str,
- from_ascii("\\"), from_ascii("\\backslash ")),
- from_ascii("^"), from_ascii("\\mathcircumflex ")),
+ from_ascii("\\"), backslash),
+ from_ascii("^"), caret),
from_ascii("_"), from_ascii("\\_")),
from_ascii("$"), from_ascii("\\$")),
from_ascii("#"), from_ascii("\\#")),
void Parser::tokenize(docstring const & buffer)
{
- idocstringstream is(mode_ & Parse::VERBATIM ?
- escapeSpecialChars(buffer) : buffer, ios::in | ios::binary);
+ idocstringstream is(mode_ & Parse::VERBATIM
+ ? escapeSpecialChars(buffer, mode_ & Parse::TEXTMODE)
+ : buffer, ios::in | ios::binary);
char_type c;
while (is.get(c)) {