]> git.lyx.org Git - features.git/blob - src/mathed/InsetMathXArrow.cpp
Do not allow pasting backslashes in macro names
[features.git] / src / mathed / InsetMathXArrow.cpp
1 /**
2  * \file InsetMathXArrow.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetMathXArrow.h"
14
15 #include "MathData.h"
16 #include "MathStream.h"
17 #include "MathSupport.h"
18
19 #include "LaTeXFeatures.h"
20 #include "MetricsInfo.h"
21
22 #include "support/debug.h"
23 #include "support/lassert.h"
24
25 #include <algorithm>
26
27 using namespace std;
28
29 namespace lyx {
30
31
32 InsetMathXArrow::InsetMathXArrow(Buffer * buf, docstring const & name)
33         : InsetMathFracBase(buf), name_(name)
34 {}
35
36
37 Inset * InsetMathXArrow::clone() const
38 {
39         return new InsetMathXArrow(*this);
40 }
41
42
43 void InsetMathXArrow::metrics(MetricsInfo & mi, Dimension & dim) const
44 {
45         Changer dummy2 = mi.base.changeEnsureMath();
46         Changer dummy = mi.base.changeScript();
47         Dimension dim0;
48         cell(0).metrics(mi, dim0);
49         Dimension dim1;
50         cell(1).metrics(mi, dim1);
51         dim.wid = max(dim0.width(), dim1.width()) + 10;
52         dim.asc = dim0.height() + 10;
53         dim.des = dim1.height();
54 }
55
56
57 void InsetMathXArrow::draw(PainterInfo & pi, int x, int y) const
58 {
59         Changer dummy2 = pi.base.changeEnsureMath();
60         Changer dummy = pi.base.changeScript();
61         Dimension const dim = dimension(*pi.base.bv);
62         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
63         // center the cells with the decoration
64         cell(0).draw(pi, x + dim.width()/2 - dim0.width()/2, y - 10);
65         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
66         cell(1).draw(pi, x + dim.width()/2 - dim1.width()/2, y + dim1.height());
67         mathed_draw_deco(pi, x, y - 7, dim.wid, 5, name_);
68 }
69
70
71 void InsetMathXArrow::write(TeXMathStream & os) const
72 {
73         MathEnsurer ensurer(os);
74         os << '\\' << name_;
75         if (!cell(1).empty())
76                 os << '[' << cell(1) << ']';
77         os << '{' << cell(0) << '}';
78 }
79
80
81 void InsetMathXArrow::normalize(NormalStream & os) const
82 {
83         os << "[xarrow " << name_ << ' ' <<  cell(0) << ' ' << cell(1) << ']';
84 }
85
86
87 static std::map<string, string> latex_to_html_entities = {
88                 {"xleftarrow", "&larr;"},
89                 {"xrightarrow", "&rarr;"},
90                 {"xhookleftarrow", "&larrhk;"},
91                 {"xhookrightarrow", "&rarrhk;"},
92                 {"xLeftarrow", "&lArr;"},
93                 {"xRightarrow", "&rArr;"},
94                 {"xleftrightarrow", "&leftrightarrow;"},
95                 {"xLeftrightarrow", "&Leftrightarrow;"},
96                 {"xleftharpoondown", "&leftharpoondown;"},
97                 {"xleftharpoonup", "&leftharpoonup;"},
98                 {"xleftrightharpoons", "&leftrightharpoons;"},
99                 {"xrightharpoondown", "&rightharpoondown;"},
100                 {"xrightharpoonup", "&rightharpoonup;"},
101                 {"xrightleftharpoons", "&rightleftharpoons;"},
102                 {"xmapsto", "&mapsto;"},
103 };
104
105
106 static std::map<string, string> latex_to_xml_entities = {
107                 {"xleftarrow", "&#x2190;"},
108                 {"xrightarrow", "&#x2192;"},
109                 {"xhookleftarrow", "&#x21a9;"},
110                 {"xhookrightarrow", "&#x21aa;"},
111                 {"xLeftarrow", "&#x21d0;"},
112                 {"xRightarrow", "&#x21d2;"},
113                 {"xleftrightarrow", "&#x2194;"},
114                 {"xLeftrightarrow", "&#x21d4;"},
115                 {"xleftharpoondown", "&#x21bd;"},
116                 {"xleftharpoonup", "&#x21bc;"},
117                 {"xleftrightharpoons", "&#x21cb;"},
118                 {"xrightharpoondown", "&#x21c1;"},
119                 {"xrightharpoonup", "&#x21c0;"},
120                 {"xrightleftharpoons", "&#x21cc;"},
121                 {"xmapsto", "&#x21a6;"},
122 };
123
124
125 docstring map_latex_to(docstring latex, bool xml = false)
126 {
127         auto dict = (xml) ? latex_to_xml_entities : latex_to_html_entities;
128
129         auto mapping = dict.find(to_ascii(latex));
130         if (mapping != dict.end()) {
131                 return from_ascii(mapping->second);
132         } else {
133                 std::string format = (xml) ? "XML" : "HTML";
134                 lyxerr << "mathmlize " << format << " conversion for '" << latex << "' not implemented" << endl;
135                 LASSERT(false, return from_ascii(dict["xrightarrow"]));
136                 return docstring();
137         }
138 }
139
140
141 void InsetMathXArrow::mathmlize(MathMLStream & ms) const
142 {
143         docstring arrow = map_latex_to(name_, ms.xmlMode());
144         ms << "<" << from_ascii(ms.namespacedTag("munderover")) << " accent='false' accentunder='false'>"
145            << MTagInline("mo") << arrow << ETagInline("mo")
146            << cell(1) << cell(0)
147            << "</" << from_ascii(ms.namespacedTag("munderover"))<< ">";
148 }
149
150
151 void InsetMathXArrow::htmlize(HtmlStream & os) const
152 {
153         docstring arrow = map_latex_to(name_);
154         os << MTag("span", "class='xarrow'")
155            << MTag("span", "class='xatop'") << cell(0) << ETag("span")
156            << MTag("span", "class='xabottom'") << arrow << ETag("span")
157            << ETag("span");
158 }
159
160
161 void InsetMathXArrow::validate(LaTeXFeatures & features) const
162 {
163         if (name_ == "xleftarrow" || name_ == "xrightarrow")
164                 features.require("amsmath");
165         else
166                 features.require("mathtools");
167
168         if (features.runparams().math_flavor == OutputParams::MathAsHTML)
169                 // CSS adapted from eLyXer
170                 features.addCSSSnippet(
171                         "span.xarrow{display: inline-block; vertical-align: middle; text-align:center;}\n"
172                         "span.xatop{display: block;}\n"
173                         "span.xabottom{display: block;}");
174         InsetMathNest::validate(features);
175 }
176
177
178 } // namespace lyx