]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathSymbol.cpp
typo
[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         docstring tag = from_ascii(ms.namespacedTag(sym_->MathMLtype()));
164         ms << '<' << tag << ">";
165         if ((ms.xmlMode() && sym_->xmlname == "x") || (!ms.xmlMode() && sym_->htmlname == "x"))
166                 // unknown so far
167                 ms << name();
168         else if (ms.xmlMode())
169                 ms << sym_->xmlname;
170         else
171                 ms << sym_->htmlname;
172         ms << "</" << tag << '>';
173 }
174
175
176 void InsetMathSymbol::htmlize(HtmlStream & os, bool spacing) const
177 {
178         // FIXME We may need to do more interesting things
179         // with MathMLtype.
180         char const * type = sym_->MathMLtype();
181         bool op = (std::string(type) == "mo");
182
183         if (sym_->htmlname == "x")
184                 // unknown so far
185                 os << ' ' << name() << ' ';
186         else if (op && spacing)
187                 os << ' ' << sym_->htmlname << ' ';
188         else
189                 os << sym_->htmlname;
190 }
191
192
193 void InsetMathSymbol::htmlize(HtmlStream & os) const
194 {
195         htmlize(os, true);
196 }
197
198
199 void InsetMathSymbol::octave(OctaveStream & os) const
200 {
201         if (name() == "cdot")
202                 os << '*';
203         else
204                 os << name();
205 }
206
207
208 void InsetMathSymbol::write(TeXMathStream & os) const
209 {
210         unique_ptr<MathEnsurer> ensurer;
211         if (currentMode() != TEXT_MODE)
212                 ensurer = make_unique<MathEnsurer>(os);
213         else
214                 ensurer = make_unique<MathEnsurer>(os, false, true, true);
215         os << '\\' << name();
216
217         // $,#, etc. In theory the restriction based on catcodes, but then
218         // we do not handle catcodes very well, let alone cat code changes,
219         // so being outside the alpha range is good enough.
220         if (name().size() == 1 && !isAlphaASCII(name()[0]))
221                 return;
222
223         os.pendingSpace(true);
224         writeLimits(os);
225 }
226
227
228 void InsetMathSymbol::infoize2(odocstream & os) const
229 {
230         os << from_ascii("Symbol: ") << name();
231 }
232
233
234 void InsetMathSymbol::validate(LaTeXFeatures & features) const
235 {
236         // this is not really the ideal place to do this, but we can't
237         // validate in InsetMathExInt.
238         if (features.runparams().math_flavor == OutputParams::MathAsHTML
239             && sym_->name == from_ascii("int")) {
240                 features.addCSSSnippet(
241                         "span.limits{display: inline-block; vertical-align: middle; text-align:center; font-size: 75%;}\n"
242                         "span.limits span{display: block;}\n"
243                         "span.intsym{font-size: 150%;}\n"
244                         "sub.limit{font-size: 75%;}\n"
245                         "sup.limit{font-size: 75%;}");
246         } else {
247                 if (!sym_->required.empty())
248                         features.require(sym_->required);
249         }
250 }
251
252 } // namespace lyx