]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathSymbol.cpp
Fix -Winconsistent-missing-override
[lyx.git] / src / mathed / InsetMathSymbol.cpp
1 /**
2  * \file InsetMathSymbol.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 "InsetMathSymbol.h"
14
15 #include "MathAtom.h"
16 #include "MathParser.h"
17 #include "MathStream.h"
18 #include "MathSupport.h"
19
20 #include "Dimension.h"
21 #include "LaTeXFeatures.h"
22 #include "MetricsInfo.h"
23
24 #include "support/debug.h"
25 #include "support/docstream.h"
26 #include "support/textutils.h"
27 #include "support/unique_ptr.h"
28
29 using namespace std;
30
31 namespace lyx {
32
33 InsetMathSymbol::InsetMathSymbol(latexkeys const * l)
34         : sym_(l)
35 {}
36
37
38 InsetMathSymbol::InsetMathSymbol(char const * name)
39         : sym_(in_word_set(from_ascii(name)))
40 {}
41
42
43 InsetMathSymbol::InsetMathSymbol(docstring const & name)
44         : sym_(in_word_set(name))
45 {}
46
47
48 Inset * InsetMathSymbol::clone() const
49 {
50         return new InsetMathSymbol(*this);
51 }
52
53
54 docstring InsetMathSymbol::name() const
55 {
56         return sym_->name;
57 }
58
59
60 /// The default limits value
61 Limits InsetMathSymbol::defaultLimits(bool display) const
62 {
63         if (allowsLimitsChange() && sym_->extra != "func" && display)
64                 return LIMITS;
65         else
66                 return NO_LIMITS;
67 }
68
69
70 void InsetMathSymbol::metrics(MetricsInfo & mi, Dimension & dim) const
71 {
72         // set dim
73         // FIXME: this should depend on BufferView
74         // set negative kerning_ so that a subscript is moved leftward
75         kerning_ = -mathedSymbolDim(mi.base, dim, sym_);
76         if (sym_->draw != sym_->name) {
77                 // align character vertically
78                 // FIXME: this should depend on BufferView
79                 h_ = 0;
80                 if (mathClass() == MC_OP) {
81                         // center the symbol around the fraction axis
82                         // See rule 13 of Appendix G of the TeXbook.
83                         h_ = axis_height(mi.base) + (dim.des - dim.asc) / 2;
84                 } else if (sym_->inset == "wasy") {
85                         // correct height for broken wasy font
86                         h_ = 4 * dim.des / 5;
87                 }
88                 dim.asc += h_;
89                 dim.des -= h_;
90         }
91 }
92
93
94 void InsetMathSymbol::draw(PainterInfo & pi, int x, int y) const
95 {
96         mathedSymbolDraw(pi, x, y - h_, sym_);
97 }
98
99
100 InsetMath::mode_type InsetMathSymbol::currentMode() const
101 {
102         return sym_->extra == "textmode" ? TEXT_MODE : MATH_MODE;
103 }
104
105
106 bool InsetMathSymbol::isOrdAlpha() const
107 {
108         return sym_->extra == "mathord" || sym_->extra == "mathalpha";
109 }
110
111
112 MathClass InsetMathSymbol::mathClass() const
113 {
114         if (sym_->extra == "func" || sym_->extra == "funclim")
115                 return MC_OP;
116         MathClass const mc = string_to_class(sym_->extra);
117         return (mc == MC_UNKNOWN) ? MC_ORD : mc;
118 }
119
120
121 void InsetMathSymbol::normalize(NormalStream & os) const
122 {
123         os << "[symbol " << name() << ']';
124 }
125
126
127 void InsetMathSymbol::maple(MapleStream & os) const
128 {
129         if (name() == "cdot")
130                 os << '*';
131         else if (name() == "infty")
132                 os << "infinity";
133         else
134                 os << name();
135 }
136
137 void InsetMathSymbol::maxima(MaximaStream & os) const
138 {
139         if (name() == "cdot")
140                 os << '*';
141         else if (name() == "infty")
142                 os << "inf";
143         else if (name() == "pi")
144                 os << "%pi";
145         else
146                 os << name();
147 }
148
149
150 void InsetMathSymbol::mathematica(MathematicaStream & os) const
151 {
152         if ( name() == "pi")    { os << "Pi"; return;}
153         if ( name() == "infty") { os << "Infinity"; return;}
154         if ( name() == "cdot")  { os << '*'; return;}
155         os << name();
156 }
157
158
159 void InsetMathSymbol::mathmlize(MathMLStream & ms) const
160 {
161         // FIXME We may need to do more interesting things
162         // with MathMLtype.
163         ms << MTagInline(sym_->MathMLtype());
164         if (sym_->xmlname == "x")
165                 // unknown so far
166                 ms << name();
167         else
168                 ms << sym_->xmlname;
169         ms << ETagInline(sym_->MathMLtype());
170 }
171
172
173 void InsetMathSymbol::htmlize(HtmlStream & os, bool spacing) const
174 {
175         // FIXME We may need to do more interesting things
176         // with MathMLtype.
177         char const * type = sym_->MathMLtype();
178         bool op = (std::string(type) == "mo");
179
180         if (sym_->xmlname == "x")
181                 // unknown so far
182                 os << ' ' << name() << ' ';
183         else if (op && spacing)
184                 os << ' ' << sym_->xmlname << ' ';
185         else
186                 os << sym_->xmlname;
187 }
188
189
190 void InsetMathSymbol::htmlize(HtmlStream & os) const
191 {
192         htmlize(os, true);
193 }
194
195
196 void InsetMathSymbol::octave(OctaveStream & os) const
197 {
198         if (name() == "cdot")
199                 os << '*';
200         else
201                 os << name();
202 }
203
204
205 void InsetMathSymbol::write(TeXMathStream & os) const
206 {
207         unique_ptr<MathEnsurer> ensurer;
208         if (currentMode() != TEXT_MODE)
209                 ensurer = make_unique<MathEnsurer>(os);
210         else
211                 ensurer = make_unique<MathEnsurer>(os, false, true, true);
212         os << '\\' << name();
213
214         // $,#, etc. In theory the restriction based on catcodes, but then
215         // we do not handle catcodes very well, let alone cat code changes,
216         // so being outside the alpha range is good enough.
217         if (name().size() == 1 && !isAlphaASCII(name()[0]))
218                 return;
219
220         os.pendingSpace(true);
221         writeLimits(os);
222 }
223
224
225 void InsetMathSymbol::infoize2(odocstream & os) const
226 {
227         os << from_ascii("Symbol: ") << name();
228 }
229
230
231 void InsetMathSymbol::validate(LaTeXFeatures & features) const
232 {
233         // this is not really the ideal place to do this, but we can't
234         // validate in InsetMathExInt.
235         if (features.runparams().math_flavor == OutputParams::MathAsHTML
236             && sym_->name == from_ascii("int")) {
237                 features.addCSSSnippet(
238                         "span.limits{display: inline-block; vertical-align: middle; text-align:center; font-size: 75%;}\n"
239                         "span.limits span{display: block;}\n"
240                         "span.intsym{font-size: 150%;}\n"
241                         "sub.limit{font-size: 75%;}\n"
242                         "sup.limit{font-size: 75%;}");
243         } else {
244                 if (!sym_->required.empty())
245                         features.require(sym_->required);
246         }
247 }
248
249 } // namespace lyx