Am 17.02.2014 02:42, schrieb Uwe Stöhr:
Attached is the patch to fully support the \xarrow commands including HTML
support.
I forgot that there are more \xarrow commands provided by the mathtools package. Attached is an
updated patch.
regards Uwe
src/mathed/InsetMathNest.cpp | 13 ++++
src/mathed/InsetMathXArrow.cpp | 137 +++++++++++++++++++++++++++++++++++++++++
src/mathed/InsetMathXArrow.h | 32 ++++++++++
src/mathed/MathFactory.cpp | 8 +++
src/mathed/MathParser.cpp | 12 ++++
src/mathed/MathSupport.cpp | 136 +++++++++++++++++++++++++++++++++++-----
6 files changed, 321 insertions(+), 17 deletions(-)
diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp
index 3d31b9a..b7b458e 100644
--- a/src/mathed/InsetMathNest.cpp
+++ b/src/mathed/InsetMathNest.cpp
@@ -2104,8 +2104,21 @@ MathCompletionList::MathCompletionList(Cursor const & cur)
globals.push_back(from_ascii("\\framebox"));
globals.push_back(from_ascii("\\makebox"));
globals.push_back(from_ascii("\\kern"));
+ globals.push_back(from_ascii("\\xhookrightarrow"));
+ globals.push_back(from_ascii("\\xhookleftarrow"));
globals.push_back(from_ascii("\\xrightarrow"));
+ globals.push_back(from_ascii("\\xRightarrow"));
+ globals.push_back(from_ascii("\\xrightharpoondown"));
+ globals.push_back(from_ascii("\\xrightharpoonup"));
+ globals.push_back(from_ascii("\\xrightleftharpoons"));
globals.push_back(from_ascii("\\xleftarrow"));
+ globals.push_back(from_ascii("\\xLeftarrow"));
+ globals.push_back(from_ascii("\\xleftharpoondown"));
+ globals.push_back(from_ascii("\\xleftharpoonup"));
+ globals.push_back(from_ascii("\\xleftrightarrow"));
+ globals.push_back(from_ascii("\\xLeftrightarrow"));
+ globals.push_back(from_ascii("\\xleftrightharpoons"));
+ globals.push_back(from_ascii("\\xmapsto"));
globals.push_back(from_ascii("\\split"));
globals.push_back(from_ascii("\\gathered"));
globals.push_back(from_ascii("\\aligned"));
diff --git a/src/mathed/InsetMathXArrow.cpp b/src/mathed/InsetMathXArrow.cpp
index 7439970..87dbe82 100644
--- a/src/mathed/InsetMathXArrow.cpp
+++ b/src/mathed/InsetMathXArrow.cpp
@@ -33,6 +33,16 @@ Inset * InsetMathXArrow::clone() const
return new InsetMathXArrow(*this);
}
+InsetMathXMathtools::InsetMathXMathtools(Buffer * buf, docstring const & name)
+ : InsetMathFracBase(buf), name_(name)
+{}
+
+
+Inset * InsetMathXMathtools::clone() const
+{
+ return new InsetMathXMathtools(*this);
+}
+
void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
{
@@ -47,6 +57,19 @@ void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
metricsMarkers(dim);
}
+void InsetMathXMathtools::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ ScriptChanger dummy(mi.base);
+ Dimension dim0;
+ cell(0).metrics(mi, dim0);
+ Dimension dim1;
+ cell(1).metrics(mi, dim1);
+ dim.wid = max(dim0.width(), dim1.width()) + 10;
+ dim.asc = dim0.height() + 10;
+ dim.des = dim1.height();
+ metricsMarkers(dim);
+}
+
void InsetMathXArrow::draw(PainterInfo & pi, int x, int y) const
{
@@ -55,6 +78,20 @@ void InsetMathXArrow::draw(PainterInfo & pi, int x, int y) const
Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
// center the cells with the decoration
cell(0).draw(pi, x + dim.width()/2 - dim0.width()/2, y - 10);
+ Dimension const &dim1 = cell(1).dimension(*pi.base.bv);
+ cell(1).draw(pi, x + dim.width()/2 - dim1.width()/2, y + dim1.height());
+ mathed_draw_deco(pi, x + 1, y - 7, dim.wid - 2, 5, name_);
+ drawMarkers(pi, x, y);
+}
+
+
+void InsetMathXMathtools::draw(PainterInfo & pi, int x, int y) const
+{
+ ScriptChanger dummy(pi.base);
+ Dimension const dim = dimension(*pi.base.bv);
+ Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
+ // center the cells with the decoration
+ cell(0).draw(pi, x + dim.width()/2 - dim0.width()/2, y - 10);
Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
cell(1).draw(pi, x + dim.width()/2 - dim1.width()/2, y + dim1.height());
mathed_draw_deco(pi, x + 1, y - 7, dim.wid - 2, 5, name_);
@@ -72,12 +109,28 @@ void InsetMathXArrow::write(WriteStream & os) const
}
+void InsetMathXMathtools::write(WriteStream & os) const
+{
+ MathEnsurer ensurer(os);
+ os << '\\' << name_;
+ if (!cell(1).empty())
+ os << '[' << cell(1) << ']';
+ os << '{' << cell(0) << '}';
+}
+
+
void InsetMathXArrow::normalize(NormalStream & os) const
{
os << "[xarrow " << name_ << ' ' << cell(0) << ' ' << cell(1) << ']';
}
+void InsetMathXMathtools::normalize(NormalStream & os) const
+{
+ os << "[xarrow " << name_ << ' ' << cell(0) << ' ' << cell(1) << ']';
+}
+
+
void InsetMathXArrow::mathmlize(MathStream & ms) const
{
char const * const arrow = name_ == "xleftarrow"
@@ -88,6 +141,41 @@ void InsetMathXArrow::mathmlize(MathStream & ms) const
}
+void InsetMathXMathtools::mathmlize(MathStream & ms) const
+{
+ char * arrow;
+ if (name_ == "xhookleftarrow")
+ arrow = "↩";
+ else if (name_ == "xhookrightarrow")
+ arrow = "↪";
+ else if (name_ == "xLeftarrow")
+ arrow = "⇐";
+ else if (name_ == "xRightarrow")
+ arrow = "⇒";
+ else if (name_ == "xleftrightarrow")
+ arrow = "↔";
+ else if (name_ == "xLeftrightarrow")
+ arrow = "⇔";
+ else if (name_ == "xleftharpoondown")
+ arrow = "↽";
+ else if (name_ == "xleftharpoonup")
+ arrow = "↼";
+ else if (name_ == "xleftrightharpoons")
+ arrow = "⇋";
+ else if (name_ == "xrightharpoondown")
+ arrow = "⇁";
+ else if (name_ == "xrightharpoonup")
+ arrow = "⇀";
+ else if (name_ == "xrightleftharpoons")
+ arrow = "⇌";
+ else if (name_ == "xmapsto")
+ arrow = "↦";
+ ms << "<munderover accent='false' accentunder='false'>"
+ << arrow << cell(1) << cell(0)
+ << "</munderover>";
+}
+
+
void InsetMathXArrow::htmlize(HtmlStream & os) const
{
char const * const arrow = name_ == "xleftarrow"
@@ -99,6 +187,42 @@ void InsetMathXArrow::htmlize(HtmlStream & os) const
}
+void InsetMathXMathtools::htmlize(HtmlStream & os) const
+{
+ char * arrow;
+ if (name_ == "xhookleftarrow")
+ arrow = "↩";
+ else if (name_ == "xhookrightarrow")
+ arrow = "↪";
+ else if (name_ == "xLeftarrow")
+ arrow = "⇐";
+ else if (name_ == "xRightarrow")
+ arrow = "⇒";
+ else if (name_ == "xleftrightarrow")
+ arrow = "↔";
+ else if (name_ == "xLeftrightarrow")
+ arrow = "⇔";
+ else if (name_ == "xleftharpoondown")
+ arrow = "↽";
+ else if (name_ == "xleftharpoonup")
+ arrow = "↼";
+ else if (name_ == "xleftrightharpoons")
+ arrow = "⇋";
+ else if (name_ == "xrightharpoondown")
+ arrow = "⇁";
+ else if (name_ == "xrightharpoonup")
+ arrow = "⇀";
+ else if (name_ == "xrightleftharpoons")
+ arrow = "⇌";
+ else if (name_ == "xmapsto")
+ arrow = "↦";
+ os << MTag("span", "class='xarrow'")
+ << MTag("span", "class='xatop'") << cell(0) << ETag("span")
+ << MTag("span", "class='xabottom'") << arrow << ETag("span")
+ << ETag("span");
+}
+
+
void InsetMathXArrow::validate(LaTeXFeatures & features) const
{
features.require("amsmath");
@@ -112,4 +236,17 @@ void InsetMathXArrow::validate(LaTeXFeatures & features) const
}
+void InsetMathXMathtools::validate(LaTeXFeatures & features) const
+{
+ features.require("mathtools");
+ if (features.runparams().math_flavor == OutputParams::MathAsHTML)
+ // CSS adapted from eLyXer
+ features.addCSSSnippet(
+ "span.xarrow{display: inline-block; vertical-align: middle; text-align:center;}\n"
+ "span.xatop{display: block;}\n"
+ "span.xabottom{display: block;}");
+ InsetMathNest::validate(features);
+}
+
+
} // namespace lyx
diff --git a/src/mathed/InsetMathXArrow.h b/src/mathed/InsetMathXArrow.h
index f63eb2b..3157cb7 100644
--- a/src/mathed/InsetMathXArrow.h
+++ b/src/mathed/InsetMathXArrow.h
@@ -49,5 +49,37 @@ private:
};
+
+/// Wide arrows from the mathtools package \xhookrightarrow
+class InsetMathXMathtools : public InsetMathFracBase {
+public:
+ ///
+ explicit InsetMathXMathtools(Buffer * buf, docstring const & name);
+ ///
+ void draw(PainterInfo & pi, int x, int y) const;
+ ///
+ void write(WriteStream & os) const;
+ ///
+ void metrics(MetricsInfo & mi, Dimension & dim) const;
+ ///
+ void normalize(NormalStream & os) const;
+ ///
+ void mathmlize(MathStream &) const;
+ ///
+ void htmlize(HtmlStream &) const;
+ ///
+ void validate(LaTeXFeatures & features) const;
+ ///
+ InsetCode lyxCode() const { return MATH_XARROW_CODE; }
+
+private:
+ virtual Inset * clone() const;
+ ///
+ bool upper() const;
+ ///
+ docstring const name_;
+};
+
+
} // namespace lyx
#endif
diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp
index 151771d..21c961d 100644
--- a/src/mathed/MathFactory.cpp
+++ b/src/mathed/MathFactory.cpp
@@ -436,6 +436,14 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf)
return MathAtom(new InsetMathDiagram(buf));
if (s == "xrightarrow" || s == "xleftarrow")
return MathAtom(new InsetMathXArrow(buf, s));
+ if (s == "xhookrightarrow" || s == "xhookleftarrow" ||
+ s == "xRightarrow" || s == "xLeftarrow" ||
+ s == "xleftrightarrow" || s == "xLeftrightarrow" ||
+ s == "xrightharpoondown" || s == "xrightharpoonup" ||
+ s == "xleftharpoondown" || s == "xleftharpoonup" ||
+ s == "xleftrightharpoons" || s == "xrightleftharpoons" ||
+ s == "xmapsto")
+ return MathAtom(new InsetMathXMathtools(buf, s));
if (s == "split" || s == "alignedat")
return MathAtom(new InsetMathSplit(buf, s));
if (s == "cases")
diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp
index ef98778..fdb6aa8 100644
--- a/src/mathed/MathParser.cpp
+++ b/src/mathed/MathParser.cpp
@@ -1488,6 +1488,18 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
}
+ else if (t.cs() == "xhookrightarrow" || t.cs() == "xhookleftarrow" ||
+ t.cs() == "xRightarrow" || t.cs() == "xLeftarrow" ||
+ t.cs() == "xleftrightarrow" || t.cs() == "xLeftrightarrow" ||
+ t.cs() == "xrightharpoondown" || t.cs() == "xrightharpoonup" ||
+ t.cs() == "xleftharpoondown" || t.cs() == "xleftharpoonup" ||
+ t.cs() == "xleftrightharpoons" || t.cs() == "xrightleftharpoons" ||
+ t.cs() == "xmapsto") {
+ cell->push_back(createInsetMath(t.cs(), buf));
+ parse(cell->back().nucleus()->cell(1), FLAG_OPTION, mode);
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+ }
+
else if (t.cs() == "ref" || t.cs() == "eqref" || t.cs() == "prettyref"
|| t.cs() == "pageref" || t.cs() == "vpageref" || t.cs() == "vref") {
cell->push_back(MathAtom(new InsetMathRef(buf, t.cs())));
diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp
index 6db7fcb..31cc43a 100644
--- a/src/mathed/MathSupport.cpp
+++ b/src/mathed/MathSupport.cpp
@@ -112,6 +112,95 @@ double const brace[] = {
};
+double const mapsto[] = {
+ 2, 3,
+ 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
+ 1, 0.015, 0.475, 0.945, 0.475,
+ 1, 0.015, 0.015, 0.015, 0.985,
+ 0
+};
+
+
+double const lhook[] = {
+ 2, 3,
+ 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
+ 1, 0.015, 0.475, 0.7, 0.475,
+ 2, 5,
+ 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
+ 0.825, 0.35, 0.7, 0.475,
+ 0
+};
+
+
+double const rhook[] = {
+ 2, 3,
+ 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
+ 1, 0.3, 0.475, 0.985, 0.475,
+ 2, 5,
+ 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
+ 0.175, 0.35, 0.3, 0.475,
+ 0
+};
+
+
+double const LRArrow[] = {
+ 2, 3,
+ 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
+ 2, 3,
+ 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
+ 1, 0.2, 0.8, 0.8, 0.8,
+ 1, 0.2, 0.2, 0.8, 0.2,
+ 0
+};
+
+
+double const LArrow[] = {
+ 2, 3,
+ 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
+ 1, 0.2, 0.8, 0.985, 0.8,
+ 1, 0.2, 0.2, 0.985, 0.2,
+ 0
+};
+
+
+double const lharpoondown[] = {
+ 2, 2,
+ 0.015, 0.5, 0.25, 0.985,
+ 1, 0.02, 0.475, 0.985, 0.475,
+ 0
+};
+
+
+double const lharpoonup[] = {
+ 2, 2,
+ 0.25, 0.015, 0.015, 0.5,
+ 1, 0.02, 0.525, 0.985, 0.525,
+ 0
+};
+
+
+double const lrharpoons[] = {
+ 2, 2,
+ 0.25, 0.015, 0.015, 0.225,
+ 1, 0.02, 0.23, 0.985, 0.23,
+ 2, 2,
+ 0.75, 0.985, 0.985, 0.775,
+ 1, 0.02, 0.7, 0.980, 0.7,
+ 0
+};
+
+
+double const rlharpoons[] = {
+ 2, 2,
+ 0.75, 0.015, 0.985, 0.225,
+ 1, 0.02, 0.23, 0.985, 0.23,
+ 2, 2,
+ 0.25, 0.985, 0.015, 0.775,
+ 1, 0.02, 0.7, 0.980, 0.7,
+ 0
+};
+
+
double const arrow[] = {
4, 7,
0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
@@ -282,23 +371,36 @@ struct named_deco_struct {
named_deco_struct deco_table[] = {
// Decorations
- {"widehat", angle, 3 },
- {"widetilde", tilde, 0 },
- {"underbar", hline, 0 },
- {"underline", hline, 0 },
- {"overline", hline, 0 },
- {"underbrace", brace, 1 },
- {"overbrace", brace, 3 },
- {"overleftarrow", arrow, 1 },
- {"overrightarrow", arrow, 3 },
- {"overleftrightarrow", udarrow, 1 },
- {"xleftarrow", arrow, 1 },
- {"xrightarrow", arrow, 3 },
- {"underleftarrow", arrow, 1 },
- {"underrightarrow", arrow, 3 },
- {"underleftrightarrow", udarrow, 1 },
- {"undertilde", tilde, 0 },
- {"utilde", tilde, 0 },
+ {"widehat", angle, 3 },
+ {"widetilde", tilde, 0 },
+ {"underbar", hline, 0 },
+ {"underline", hline, 0 },
+ {"overline", hline, 0 },
+ {"underbrace", brace, 1 },
+ {"overbrace", brace, 3 },
+ {"overleftarrow", arrow, 1 },
+ {"overrightarrow", arrow, 3 },
+ {"overleftrightarrow", udarrow, 1 },
+ {"xhookleftarrow", lhook, 0 },
+ {"xhookrightarrow", rhook, 0 },
+ {"xleftarrow", arrow, 1 },
+ {"xLeftarrow", LArrow, 0 },
+ {"xleftharpoondown", lharpoondown, 0 },
+ {"xleftharpoonup", lharpoonup, 0 },
+ {"xleftrightharpoons", lrharpoons, 0 },
+ {"xleftrightarrow", udarrow, 1 },
+ {"xLeftrightarrow", LRArrow, 0 },
+ {"xmapsto", mapsto, 0 },
+ {"xrightarrow", arrow, 3 },
+ {"xRightarrow", LArrow, 2 },
+ {"xrightharpoondown", lharpoonup, 2 },
+ {"xrightharpoonup", lharpoondown, 2 },
+ {"xrightleftharpoons", rlharpoons, 0 },
+ {"underleftarrow", arrow, 1 },
+ {"underrightarrow", arrow, 3 },
+ {"underleftrightarrow", udarrow, 1 },
+ {"undertilde", tilde, 0 },
+ {"utilde", tilde, 0 },
// Delimiters
{"(", parenth, 0 },