X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathDecoration.cpp;h=47792498915e4737d09c02d77a391e2d57703417;hb=6c13af3f298a96c5564684b83c52989473b020ce;hp=f7a038bec879bd903db5d153da700ff69c47610f;hpb=f497296c30e6da2f97b16da8ad1c9e96feffb16b;p=lyx.git diff --git a/src/mathed/InsetMathDecoration.cpp b/src/mathed/InsetMathDecoration.cpp index f7a038bec8..4779249891 100644 --- a/src/mathed/InsetMathDecoration.cpp +++ b/src/mathed/InsetMathDecoration.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,36 +12,46 @@ #include #include "InsetMathDecoration.h" + #include "MathData.h" #include "MathParser.h" #include "MathSupport.h" #include "MathStream.h" +#include "MetricsInfo.h" #include "LaTeXFeatures.h" -#include "debug.h" -#include "support/std_ostream.h" +#include "support/debug.h" +#include "support/docstring.h" +#include "support/gettext.h" +#include "support/lassert.h" +#include "support/lstrings.h" + +#include + +using namespace lyx::support; +using namespace std; namespace lyx { -InsetMathDecoration::InsetMathDecoration(latexkeys const * key) - : InsetMathNest(1), key_(key) +InsetMathDecoration::InsetMathDecoration(Buffer * buf, latexkeys const * key) + : InsetMathNest(buf, 1), key_(key), dh_(0), dy_(0), dw_(0) { -// lyxerr << " creating deco " << key->name << std::endl; +// lyxerr << " creating deco " << key->name << endl; } -std::auto_ptr InsetMathDecoration::doClone() const +Inset * InsetMathDecoration::clone() const { - return std::auto_ptr(new InsetMathDecoration(*this)); + return new InsetMathDecoration(*this); } bool InsetMathDecoration::upper() const { - return key_->name.substr(0, 5) != "under"; + return key_->name.substr(0, 5) != "under" && key_->name != "utilde"; } @@ -49,13 +59,7 @@ bool InsetMathDecoration::isScriptable() const { return key_->name == "overbrace" || - key_->name == "underbrace" || - key_->name == "overleftarrow" || - key_->name == "overrightarrow" || - key_->name == "overleftrightarrow" || - key_->name == "underleftarrow" || - key_->name == "underrightarrow" || - key_->name == "underleftrightarrow"; + key_->name == "underbrace"; } @@ -87,22 +91,22 @@ bool InsetMathDecoration::wide() const key_->name == "widetilde" || key_->name == "underleftarrow" || key_->name == "underrightarrow" || - key_->name == "underleftrightarrow"; + key_->name == "underleftrightarrow" || + key_->name == "undertilde" || + key_->name == "utilde"; } -bool InsetMathDecoration::ams() const +InsetMath::mode_type InsetMathDecoration::currentMode() const { - return - key_->name == "overleftrightarrow" || - key_->name == "underleftarrow" || - key_->name == "underrightarrow" || - key_->name == "underleftrightarrow"; + return key_->name == "underbar" ? TEXT_MODE : MATH_MODE; } -bool InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const { + Changer dummy = mi.base.changeEnsureMath(currentMode()); + cell(0).metrics(mi, dim); dh_ = 6; //mathed_char_height(LM_TC_VAR, mi, 'I', ascent_, descent_); @@ -115,33 +119,31 @@ bool InsetMathDecoration::metrics(MetricsInfo & mi, Dimension & dim) const dy_ = dim.des + 1; dim.des += dh_ + 2; } - - metricsMarkers(dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; } void InsetMathDecoration::draw(PainterInfo & pi, int x, int y) const { - cell(0).draw(pi, x + 1, y); + Changer dummy = pi.base.changeEnsureMath(currentMode()); + + cell(0).draw(pi, x, y); + Dimension const & dim0 = cell(0).dimension(*pi.base.bv); if (wide()) - mathed_draw_deco(pi, x + 1, y + dy_, cell(0).width(), dh_, key_->name); + mathed_draw_deco(pi, x + 1, y + dy_, dim0.wid, dh_, key_->name); else - mathed_draw_deco(pi, x + 1 + (cell(0).width() - dw_) / 2, + mathed_draw_deco(pi, x + 1 + (dim0.wid - dw_) / 2, y + dy_, dw_, dh_, key_->name); - drawMarkers(pi, x, y); - setPosCache(pi, x, y); } void InsetMathDecoration::write(WriteStream & os) const { + MathEnsurer ensurer(os); if (os.fragile() && protect()) os << "\\protect"; - os << '\\' << key_->name << '{' << cell(0) << '}'; + os << '\\' << key_->name << '{'; + ModeSpecifier specifier(os, currentMode()); + os << cell(0) << '}'; } @@ -153,16 +155,132 @@ void InsetMathDecoration::normalize(NormalStream & os) const void InsetMathDecoration::infoize(odocstream & os) const { - os << "Deco: " << key_->name; + os << bformat(_("Decoration: %1$s"), key_->name); } +namespace { + struct Attributes { + Attributes() : over(false) {} + Attributes(bool o, string t) + : over(o), tag(t) {} + bool over; + string tag; + }; + + typedef map TranslationMap; + + void buildTranslationMap(TranslationMap & t) { + // the decorations we need to support are listed in lib/symbols + t["acute"] = Attributes(true, "´"); + t["bar"] = Attributes(true, "‾"); + t["breve"] = Attributes(true, "˘"); + t["check"] = Attributes(true, "ˇ"); + t["ddddot"] = Attributes(true, "⃜"); + t["dddot"] = Attributes(true, "⃛"); + t["ddot"] = Attributes(true, "¨"); + t["dot"] = Attributes(true, "˙"); + t["grave"] = Attributes(true, "`"); + t["hat"] = Attributes(true, "ˆ"); + t["mathring"] = Attributes(true, "˚"); + t["overbrace"] = Attributes(true, "⏞"); + t["overleftarrow"] = Attributes(true, "⟵"); + t["overleftrightarrow"] = Attributes(true, "⟷"); + t["overline"] = Attributes(true, "¯"); + t["overrightarrow"] = Attributes(true, "⟶"); + t["tilde"] = Attributes(true, "˜"); + t["underbar"] = Attributes(false, "_"); + t["underbrace"] = Attributes(false, "⏟"); + t["underleftarrow"] = Attributes(false, "⟵"); + t["underleftrightarrow"] = Attributes(false, "⟷"); + // this is the macron, again, but it works + t["underline"] = Attributes(false, "¯"); + t["underrightarrow"] = Attributes(false, "⟶"); + t["undertilde"] = Attributes(false, "∼"); + t["utilde"] = Attributes(false, "∼"); + t["vec"] = Attributes(true, "→"); + t["widehat"] = Attributes(true, "^"); + t["widetilde"] = Attributes(true, "∼"); + } + + TranslationMap const & translationMap() { + static TranslationMap t; + if (t.empty()) + buildTranslationMap(t); + return t; + } +} + +void InsetMathDecoration::mathmlize(MathStream & os) const +{ + TranslationMap const & t = translationMap(); + TranslationMap::const_iterator cur = t.find(to_utf8(key_->name)); + LASSERT(cur != t.end(), return); + char const * const outag = cur->second.over ? "mover" : "munder"; + os << MTag(outag) + << MTag("mrow") << cell(0) << ETag("mrow") + << from_ascii("" + cur->second.tag + "") + << ETag(outag); +} + + +void InsetMathDecoration::htmlize(HtmlStream & os) const +{ + string const name = to_utf8(key_->name); + if (name == "bar") { + os << MTag("span", "class='overbar'") << cell(0) << ETag("span"); + return; + } + + if (name == "underbar" || name == "underline") { + os << MTag("span", "class='underbar'") << cell(0) << ETag("span"); + return; + } + + TranslationMap const & t = translationMap(); + TranslationMap::const_iterator cur = t.find(name); + LASSERT(cur != t.end(), return); + + bool symontop = cur->second.over; + string const symclass = symontop ? "symontop" : "symonbot"; + os << MTag("span", "class='symbolpair " + symclass + "'") + << '\n'; + + if (symontop) + os << MTag("span", "class='symbol'") << from_ascii(cur->second.tag); + else + os << MTag("span", "class='base'") << cell(0); + os << ETag("span") << '\n'; + if (symontop) + os << MTag("span", "class='base'") << cell(0); + else + os << MTag("span", "class='symbol'") << from_ascii(cur->second.tag); + os << ETag("span") << '\n' << ETag("span") << '\n'; +} + + +// ideas borrowed from the eLyXer code void InsetMathDecoration::validate(LaTeXFeatures & features) const { - if (ams()) - features.require("amsmath"); + if (features.runparams().math_flavor == OutputParams::MathAsHTML) { + string const name = to_utf8(key_->name); + if (name == "bar") { + features.addCSSSnippet("span.overbar{border-top: thin black solid;}"); + } else if (name == "underbar" || name == "underline") { + features.addCSSSnippet("span.underbar{border-bottom: thin black solid;}"); + } else { + features.addCSSSnippet( + "span.symbolpair{display: inline-block; text-align:center;}\n" + "span.symontop{vertical-align: top;}\n" + "span.symonbot{vertical-align: bottom;}\n" + "span.symbolpair span{display: block;}\n" + "span.symbol{height: 0.5ex;}"); + } + } else { + if (!key_->requires.empty()) + features.require(key_->requires); + } InsetMathNest::validate(features); } - } // namespace lyx