]> git.lyx.org Git - features.git/blob - src/frontends/controllers/ControlMath.cpp
Whitespace cleanup
[features.git] / src / frontends / controllers / ControlMath.cpp
1 /**
2  * \file ControlMath.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "ControlMath.h"
14 #include "debug.h"
15 #include "FuncRequest.h"
16
17 #include "support/lyxalgo.h" // sorted
18 #include "support/lstrings.h"
19 #include "support/filetools.h"
20
21 #include <functional>
22
23 using std::string;
24 using std::map;
25
26 namespace lyx {
27
28 using support::compare;
29 using support::libFileSearch;
30 using support::subst;
31
32 namespace frontend {
33
34 ControlMath::ControlMath(Dialog & dialog)
35         : Dialog::Controller(dialog)
36 {
37         // FIXME: Ideally, those unicode codepoints would be defined
38         // in "lib/symbols". Unfortunately, some of those are already
39         // defined with non-unicode ids for use within mathed.
40         // FIXME 2: We should fill-in this map with the parsed "symbols"
41         // file done in MathFactory.cpp.
42         math_symbols_["("] = MathSymbol('(');
43         math_symbols_[")"] = MathSymbol(')');
44         math_symbols_["{"] = MathSymbol('{');
45         math_symbols_["}"] = MathSymbol('}');
46         math_symbols_["["] = MathSymbol('[');
47         math_symbols_["]"] = MathSymbol(']');
48         math_symbols_["|"] = MathSymbol('|');
49         math_symbols_["/"] = MathSymbol('/', 54, Font::CMSY_FAMILY);
50         math_symbols_["backslash"] = MathSymbol('\\', 110, Font::CMSY_FAMILY);
51         math_symbols_["lceil"] = MathSymbol(0x2308, 100, Font::CMSY_FAMILY);
52         math_symbols_["rceil"] = MathSymbol(0x2309, 101, Font::CMSY_FAMILY);
53         math_symbols_["lfloor"] = MathSymbol(0x230A, 98, Font::CMSY_FAMILY);
54         math_symbols_["rfloor"] = MathSymbol(0x230B, 99, Font::CMSY_FAMILY);
55         math_symbols_["langle"] = MathSymbol(0x2329, 104, Font::CMSY_FAMILY);
56         math_symbols_["rangle"] = MathSymbol(0x232A, 105, Font::CMSY_FAMILY);
57         math_symbols_["uparrow"] = MathSymbol(0x2191, 34, Font::CMSY_FAMILY);
58         math_symbols_["Uparrow"] = MathSymbol(0x21D1, 42, Font::CMSY_FAMILY);
59         math_symbols_["updownarrow"] = MathSymbol(0x2195, 108, Font::CMSY_FAMILY);
60         math_symbols_["Updownarrow"] = MathSymbol(0x21D5, 109, Font::CMSY_FAMILY);
61         math_symbols_["downarrow"] = MathSymbol(0x2193, 35, Font::CMSY_FAMILY);
62         math_symbols_["Downarrow"] = MathSymbol(0x21D3, 43, Font::CMSY_FAMILY);
63         math_symbols_["downdownarrows"] = MathSymbol(0x21CA, 184, Font::MSA_FAMILY);
64         math_symbols_["downharpoonleft"] = MathSymbol(0x21C3, 188, Font::MSA_FAMILY);
65         math_symbols_["downharpoonright"] = MathSymbol(0x21C2, 186, Font::MSA_FAMILY);
66         math_symbols_["vert"] = MathSymbol(0x007C, 106, Font::CMSY_FAMILY);
67         math_symbols_["Vert"] = MathSymbol(0x2016, 107, Font::CMSY_FAMILY);
68
69         std::map<string, MathSymbol>::const_iterator it = math_symbols_.begin();
70         std::map<string, MathSymbol>::const_iterator end = math_symbols_.end();
71         for (; it != end; ++it)
72                 tex_names_[it->second.unicode] = it->first;
73 }
74
75
76 void ControlMath::dispatchFunc(kb_action action, string const & arg) const
77 {
78         kernel().dispatch(FuncRequest(action, arg));
79 }
80
81
82 void ControlMath::dispatchInsert(string const & name) const
83 {
84         dispatchFunc(LFUN_MATH_INSERT, '\\' + name);
85 }
86
87
88 void ControlMath::dispatchSubscript() const
89 {
90         dispatchFunc(LFUN_MATH_INSERT, "_");
91 }
92
93
94 void ControlMath::dispatchSuperscript() const
95 {
96         dispatchFunc(LFUN_MATH_INSERT, "^");
97 }
98
99
100 void ControlMath::dispatchCubeRoot() const
101 {
102         dispatchFunc(LFUN_MATH_INSERT, "\\root");
103         dispatchFunc(LFUN_SELF_INSERT, "3");
104         dispatchFunc(LFUN_CHAR_FORWARD);
105 }
106
107
108 void ControlMath::dispatchMatrix(string const & str) const
109 {
110         dispatchFunc(LFUN_MATH_MATRIX, str);
111 }
112
113
114 void ControlMath::dispatchDelim(string const & str) const
115 {
116         dispatchFunc(LFUN_MATH_DELIM, str);
117 }
118
119
120 void ControlMath::dispatchBigDelim(string const & str) const
121 {
122         dispatchFunc(LFUN_MATH_BIGDELIM, str);
123 }
124
125
126 void ControlMath::dispatchToggleDisplay() const
127 {
128         dispatchFunc(LFUN_MATH_DISPLAY);
129 }
130
131
132 void ControlMath::showDialog(string const & name) const
133 {
134         dispatchFunc(LFUN_DIALOG_SHOW, name);
135 }
136
137
138 MathSymbol const & ControlMath::mathSymbol(string tex_name) const
139 {
140         map<string, MathSymbol>::const_iterator it =
141                 math_symbols_.find(tex_name);
142
143         static MathSymbol unknown_symbol;
144         if (it == math_symbols_.end())
145                 return unknown_symbol;
146
147         return it->second;
148 }
149
150
151 std::string const & ControlMath::texName(char_type math_symbol) const
152 {
153         map<char_type, string>::const_iterator it =
154                 tex_names_.find(math_symbol);
155
156         static string empty_string;
157         if (it == tex_names_.end())
158                 return empty_string;
159
160         return it->second;
161 }
162
163
164 char const * function_names[] = {
165         "arccos", "arcsin", "arctan", "arg", "bmod",
166         "cos", "cosh", "cot", "coth", "csc", "deg",
167         "det", "dim", "exp", "gcd", "hom", "inf", "ker",
168         "lg", "lim", "liminf", "limsup", "ln", "log",
169         "max", "min", "sec", "sin", "sinh", "sup",
170         "tan", "tanh", "Pr", ""
171 };
172
173 int const nr_function_names = sizeof(function_names) / sizeof(char const *) - 1;
174
175 char const * latex_dots[] = {
176         "ldots", "cdots", "vdots", "ddots", ""
177 };
178
179 int const nr_latex_dots = sizeof(latex_dots) / sizeof(char const *) - 1;
180
181 char const * latex_deco[] = {
182         "widehat", "widetilde", "overbrace", "overleftarrow", "overrightarrow",
183         "overline", "underbrace", "underline", "underleftarrow", "underrightarrow",
184         "underleftrightarrow", "overleftrightarrow",
185         "hat", "acute", "bar", "dot",
186         "check", "grave", "vec", "ddot",
187         "breve", "tilde", "overset", "underset", ""
188 };
189
190 int const nr_latex_deco = sizeof(latex_deco) / sizeof(char const *) - 1;
191
192 char const * latex_arrow[] = {
193         "leftarrow", "rightarrow",
194         "downarrow", "uparrow", "updownarrow", "leftrightarrow",
195         "Leftarrow", "Rightarrow",
196         "Downarrow", "Uparrow", "Updownarrow", "Leftrightarrow",
197         "Longleftrightarrow", "Longleftarrow", "Longrightarrow",
198         "longleftrightarrow", "longleftarrow", "longrightarrow",
199         "leftharpoondown", "rightharpoondown",
200         "mapsto", "longmapsto",
201         "nwarrow", "nearrow",
202         "leftharpoonup", "rightharpoonup",
203         "hookleftarrow", "hookrightarrow",
204         "swarrow", "searrow",
205         "rightleftharpoons",
206         "",
207 };
208
209 int const nr_latex_arrow = sizeof(latex_arrow) / sizeof(char const *);
210
211 char const * latex_bop[] = {
212         "pm", "cap", "diamond", "oplus",
213         "mp", "cup", "bigtriangleup", "ominus",
214         "times", "uplus", "bigtriangledown", "otimes",
215         "div", "sqcap", "triangleright", "oslash",
216         "cdot", "sqcup", "triangleleft", "odot",
217         "star", "vee", "amalg", "bigcirc",
218         "setminus", "wedge", "dagger", "circ",
219         "bullet", "wr", "ddagger", ""
220 };
221
222 int const nr_latex_bop = sizeof(latex_bop) / sizeof(char const *);
223
224 char const * latex_brel[] = {
225         "leq", "geq", "equiv", "models",
226         "prec", "succ", "sim", "perp",
227         "preceq", "succeq", "simeq", "mid",
228         "ll", "gg", "asymp", "parallel",
229         "subset", "supset", "approx", "smile",
230         "subseteq", "supseteq", "cong", "frown",
231         "sqsubseteq", "sqsupseteq", "doteq", "neq",
232         "in", "ni", "propto", "notin",
233         "vdash", "dashv", "bowtie", ""
234 };
235
236 int const nr_latex_brel = sizeof(latex_brel) / sizeof(char const *);
237
238 char const * latex_greek[] = {
239         "Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi",
240         "Sigma", "Upsilon", "Phi", "Psi", "Omega",
241         "alpha", "beta", "gamma", "delta", "epsilon", "varepsilon", "zeta",
242         "eta", "theta", "vartheta", "iota", "kappa", "lambda", "mu",
243         "nu", "xi", "pi", "varpi", "rho", "sigma", "varsigma",
244         "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega", ""
245 };
246
247 int const nr_latex_greek = sizeof(latex_greek) / sizeof(char const *);
248
249 char const * latex_misc[] = {
250         "nabla", "partial", "infty", "prime", "ell",
251         "emptyset", "exists", "forall", "imath",  "jmath",
252         "Re", "Im", "aleph", "wp", "hbar",
253         "angle", "top", "bot", "Vert", "neg",
254         "flat", "natural", "sharp", "surd", "triangle",
255         "diamondsuit", "heartsuit", "clubsuit", "spadesuit",
256         "textrm \\AA", "textrm \\O", "mathcircumflex", "_",
257         "mathrm T",
258         "mathbb N", "mathbb Z", "mathbb Q",
259         "mathbb R", "mathbb C", "mathbb H",
260         "mathcal F", "mathcal L",
261         "mathcal H", "mathcal O",
262         "phantom", "vphantom", "hphantom", ""
263 };
264
265 int const nr_latex_misc = sizeof(latex_misc) / sizeof(char const *);
266
267 char const * latex_varsz[] = {
268         "sum", "int", "intop", "iint", "iintop", "iiint", "iiintop",
269         "iiiint", "iiiintop", "dotsint", "dotsintop",
270         "oint", "ointop", "oiint", "oiintop", "ointctrclockwise",
271         "ointctrclockwiseop", "ointclockwise", "ointclockwiseop",
272         "sqint", "sqintop", "sqiint", "sqiintop",
273         "prod", "coprod", "bigsqcup",
274         "bigotimes", "bigodot", "bigoplus",
275         "bigcap", "bigcup", "biguplus",
276         "bigvee", "bigwedge", ""
277 };
278
279 int const nr_latex_varsz = sizeof(latex_varsz) / sizeof(char const *);
280
281 char const * latex_ams_misc[] = {
282         "digamma", "varkappa", "beth", "daleth", "gimel",
283         "ulcorner", "urcorner", "llcorner", "lrcorner",
284         "hbar", "hslash", "vartriangle",
285         "triangledown", "square", "lozenge",
286         "circledS", "angle", "measuredangle",
287         "nexists", "mho", "Finv",
288         "Game", "Bbbk", "backprime",
289         "varnothing", "blacktriangle", "blacktriangledown",
290         "blacksquare", "blacklozenge", "bigstar",
291         "sphericalangle", "complement", "eth",
292         "diagup", "diagdown", ""
293 };
294
295 int const nr_latex_ams_misc = sizeof(latex_ams_misc) / sizeof(char const *);
296
297 char const * latex_ams_arrows[] = {
298         "dashleftarrow", "dashrightarrow",
299         "leftleftarrows", "leftrightarrows",
300         "rightrightarrows", "rightleftarrows",
301         "Lleftarrow", "Rrightarrow",
302         "twoheadleftarrow", "twoheadrightarrow",
303         "leftarrowtail", "rightarrowtail",
304         "looparrowleft", "looparrowright",
305         "curvearrowleft", "curvearrowright",
306         "circlearrowleft", "circlearrowright",
307         "Lsh", "Rsh",
308         "upuparrows", "downdownarrows",
309         "upharpoonleft", "upharpoonright",
310         "downharpoonleft", "downharpoonright",
311         "leftrightharpoons", "rightleftharpoons",
312         "rightsquigarrow", "leftrightsquigarrow",
313         "nleftarrow", "nrightarrow", "nleftrightarrow",
314         "nLeftarrow", "nRightarrow", "nLeftrightarrow",
315         "multimap",
316         ""
317 };
318
319 int const nr_latex_ams_arrows = sizeof(latex_ams_arrows) / sizeof(char const *);
320
321 char const * latex_ams_rel[] = {
322         "leqq", "geqq",
323         "leqslant", "geqslant",
324         "eqslantless", "eqslantgtr",
325         "lesssim", "gtrsim",
326         "lessapprox", "gtrapprox",
327         "approxeq", "triangleq",
328         "lessdot", "gtrdot",
329         "lll", "ggg",
330         "lessgtr", "gtrless",
331         "lesseqgtr", "gtreqless",
332         "lesseqqgtr", "gtreqqless",
333         "eqcirc", "circeq",
334         "thicksim", "thickapprox",
335         "backsim", "backsimeq",
336         "subseteqq", "supseteqq",
337         "Subset", "Supset",
338         "sqsubset", "sqsupset",
339         "preccurlyeq", "succcurlyeq",
340         "curlyeqprec", "curlyeqsucc",
341         "precsim", "succsim",
342         "precapprox", "succapprox",
343         "vartriangleleft", "vartriangleright",
344         "trianglelefteq", "trianglerighteq",
345         "bumpeq", "Bumpeq",
346         "doteqdot", "risingdotseq", "fallingdotseq",
347         "vDash", "Vvdash", "Vdash",
348         "shortmid", "shortparallel",
349         "smallsmile", "smallfrown",
350         "blacktriangleleft", "blacktriangleright",
351         "because", "therefore",
352         "backepsilon",
353         "varpropto",
354         "between",
355         "pitchfork",
356         ""
357 };
358
359 int const nr_latex_ams_rel = sizeof(latex_ams_rel) / sizeof(char const *);
360
361 char const * latex_ams_nrel[] = {
362         "nless", "ngtr",
363         "nleq", "ngeq",
364         "nleqslant", "ngeqslant",
365         "nleqq", "ngeqq",
366         "lneq", "gneq",
367         "lneqq", "gneqq",
368         "lvertneqq", "gvertneqq",
369         "lnsim", "gnsim",
370         "lnapprox", "gnapprox",
371         "nprec", "nsucc",
372         "npreceq", "nsucceq",
373         "precnsim", "succnsim",
374         "precnapprox", "succnapprox",
375         "subsetneq", "supsetneq",
376         "subsetneqq", "supsetneqq",
377         "nsubseteq", "nsupseteq", "nsupseteqq",
378         "nvdash", "nvDash", "nVDash",
379         "varsubsetneq", "varsupsetneq",
380         "varsubsetneqq", "varsupsetneqq",
381         "ntriangleleft", "ntriangleright",
382         "ntrianglelefteq", "ntrianglerighteq",
383         "ncong", "nsim",
384         "nmid", "nshortmid",
385         "nparallel", "nshortparallel",
386         "", "", ""
387 };
388
389 int const nr_latex_ams_nrel = sizeof(latex_ams_nrel) / sizeof(char const *);
390
391
392 char const * latex_ams_ops[] = {
393         "dotplus", "smallsetminus", "Cap",
394         "Cup", "barwedge", "veebar",
395         "doublebarwedge", "boxminus", "boxtimes",
396         "boxdot", "boxplus", "divideontimes",
397         "ltimes", "rtimes", "leftthreetimes",
398         "rightthreetimes", "curlywedge", "curlyvee",
399         "circleddash", "circledast", "circledcirc",
400         "centerdot", "intercal", ""
401 };
402
403 int const nr_latex_ams_ops = sizeof(latex_ams_ops) / sizeof(char const *);
404
405
406 char const *  latex_delimiters[] = {
407         "(", ")", "{", "}", "[", "]",
408         "lceil", "rceil", "lfloor", "rfloor", "langle", "rangle",
409         "uparrow", "updownarrow", "Uparrow", "Updownarrow", "downarrow", "Downarrow",
410         "|", "Vert", "/", "backslash", ""
411 };
412
413
414 int const nr_latex_delimiters = sizeof(latex_delimiters) / sizeof(char const *);
415
416 namespace {
417
418 struct XPMmap {
419         char const * key;
420         char const * value;
421 };
422
423
424 bool operator<(XPMmap const & lhs, XPMmap const & rhs)
425 {
426                 return compare(lhs.key, rhs.key) < 0;
427 }
428
429
430 class CompareKey : public std::unary_function<XPMmap, bool> {
431 public:
432         CompareKey(string const & name) : name_(name) {}
433         bool operator()(XPMmap const & other) const {
434                 return other.key == name_;
435         }
436 private:
437         string const name_;
438 };
439
440
441 XPMmap sorted_xpm_map[] = {
442         { "Bumpeq", "bumpeq2" },
443         { "Cap", "cap2" },
444         { "Cup", "cup2" },
445         { "Delta", "delta2" },
446         { "Downarrow", "downarrow2" },
447         { "Gamma", "gamma2" },
448         { "Lambda", "lambda2" },
449         { "Leftarrow", "leftarrow2" },
450         { "Leftrightarrow", "leftrightarrow2" },
451         { "Longleftarrow", "longleftarrow2" },
452         { "Longleftrightarrow", "longleftrightarrow2" },
453         { "Longrightarrow", "longrightarrow2" },
454         { "Omega", "omega2" },
455         { "Phi", "phi2" },
456         { "Pi", "pi2" },
457         { "Psi", "psi2" },
458         { "Rightarrow", "rightarrow2" },
459         { "Sigma", "sigma2" },
460         { "Subset", "subset2" },
461         { "Supset", "supset2" },
462         { "Theta", "theta2" },
463         { "Uparrow", "uparrow2" },
464         { "Updownarrow", "updownarrow2" },
465         { "Upsilon", "upsilon2" },
466         { "Vdash", "vdash3" },
467         { "Xi", "xi2" },
468         { "nLeftarrow", "nleftarrow2" },
469         { "nLeftrightarrow", "nleftrightarrow2" },
470         { "nRightarrow", "nrightarrow2" },
471         { "nVDash", "nvdash3" },
472         { "nvDash", "nvdash2" },
473         { "textrm \\AA", "textrm_AA"},
474         { "textrm \\O", "textrm_Oe"},
475         { "vDash", "vdash2" }
476 };
477
478 size_t const nr_sorted_xpm_map = sizeof(sorted_xpm_map) / sizeof(XPMmap);
479
480 } // namespace anon
481
482
483 string const find_xpm(string const & name)
484 {
485         XPMmap const * const begin = sorted_xpm_map;
486         XPMmap const * const end = begin + nr_sorted_xpm_map;
487         BOOST_ASSERT(sorted(begin, end));
488
489         XPMmap const * const it =
490                 std::find_if(begin, end, CompareKey(name));
491
492         string xpm_name;
493         if (it != end)
494                 xpm_name = it->value;
495         else {
496                 xpm_name = subst(name, "_", "underscore");
497                 xpm_name = subst(xpm_name, ' ', '_');
498
499                 // This way we can have "math-delim { }" on the toolbar.
500                 xpm_name = subst(xpm_name, "(", "lparen");
501                 xpm_name = subst(xpm_name, ")", "rparen");
502                 xpm_name = subst(xpm_name, "[", "lbracket");
503                 xpm_name = subst(xpm_name, "]", "rbracket");
504                 xpm_name = subst(xpm_name, "{", "lbrace");
505                 xpm_name = subst(xpm_name, "}", "rbrace");
506                 xpm_name = subst(xpm_name, "|", "bars");
507         }
508
509         LYXERR(Debug::GUI) << "find_xpm(" << name << ")\n"
510                            << "Looking for math XPM called \""
511                            << xpm_name << '"' << std::endl;
512
513         return libFileSearch("images/math/", xpm_name, "xpm").absFilename();
514 }
515
516 } // namespace frontend
517 } // namespace lyx