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 = "&larrhk;";
+	else if (name_ == "xhookrightarrow")
+		arrow = "&rarrhk;";
+	else if (name_ == "xLeftarrow")
+		arrow = "&lArr;";
+	else if (name_ == "xRightarrow")
+		arrow = "&rArr;";
+	else if (name_ == "xleftrightarrow")
+		arrow = "&leftrightarrow;";
+	else if (name_ == "xLeftrightarrow")
+		arrow = "&Leftrightarrow;";
+	else if (name_ == "xleftharpoondown")
+		arrow = "&leftharpoondown;";
+	else if (name_ == "xleftharpoonup")
+		arrow = "&leftharpoonup;";
+	else if (name_ == "xleftrightharpoons")
+		arrow = "&leftrightharpoons;";
+	else if (name_ == "xrightharpoondown")
+		arrow = "&rightharpoondown;";
+	else if (name_ == "xrightharpoonup")
+		arrow = "&rightharpoonup;";
+	else if (name_ == "xrightleftharpoons")
+		arrow = "&rightleftharpoons;";
+	else if (name_ == "xmapsto")
+		arrow = "&mapsto;";
+	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 = "&larrhk;";
+	else if (name_ == "xhookrightarrow")
+		arrow = "&rarrhk;";
+	else if (name_ == "xLeftarrow")
+		arrow = "&lArr;";
+	else if (name_ == "xRightarrow")
+		arrow = "&rArr;";
+	else if (name_ == "xleftrightarrow")
+		arrow = "&leftrightarrow;";
+	else if (name_ == "xLeftrightarrow")
+		arrow = "&Leftrightarrow;";
+	else if (name_ == "xleftharpoondown")
+		arrow = "&leftharpoondown;";
+	else if (name_ == "xleftharpoonup")
+		arrow = "&leftharpoonup;";
+	else if (name_ == "xleftrightharpoons")
+		arrow = "&leftrightharpoons;";
+	else if (name_ == "xrightharpoondown")
+		arrow = "&rightharpoondown;";
+	else if (name_ == "xrightharpoonup")
+		arrow = "&rightharpoonup;";
+	else if (name_ == "xrightleftharpoons")
+		arrow = "&rightleftharpoons;";
+	else if (name_ == "xmapsto")
+		arrow = "&mapsto;";
+	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 },

Reply via email to