2 * \file ControlMath.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
8 * Full author contact details are available in file CREDITS.
13 #include "ControlMath.h"
15 #include "FuncRequest.h"
17 #include "support/lyxalgo.h" // sorted
18 #include "support/lstrings.h"
19 #include "support/filetools.h"
28 using support::compare;
29 using support::libFileSearch;
34 ControlMath::ControlMath(Dialog & dialog)
35 : Dialog::Controller(dialog)
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);
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;
76 void ControlMath::dispatchFunc(kb_action action, string const & arg) const
78 kernel().dispatch(FuncRequest(action, arg));
82 void ControlMath::dispatchInsert(string const & name) const
84 dispatchFunc(LFUN_MATH_INSERT, '\\' + name);
88 void ControlMath::dispatchSubscript() const
90 dispatchFunc(LFUN_MATH_INSERT, "_");
94 void ControlMath::dispatchSuperscript() const
96 dispatchFunc(LFUN_MATH_INSERT, "^");
100 void ControlMath::dispatchCubeRoot() const
102 dispatchFunc(LFUN_MATH_INSERT, "\\root");
103 dispatchFunc(LFUN_SELF_INSERT, "3");
104 dispatchFunc(LFUN_CHAR_FORWARD);
108 void ControlMath::dispatchMatrix(string const & str) const
110 dispatchFunc(LFUN_MATH_MATRIX, str);
114 void ControlMath::dispatchDelim(string const & str) const
116 dispatchFunc(LFUN_MATH_DELIM, str);
120 void ControlMath::dispatchBigDelim(string const & str) const
122 dispatchFunc(LFUN_MATH_BIGDELIM, str);
126 void ControlMath::dispatchToggleDisplay() const
128 dispatchFunc(LFUN_MATH_DISPLAY);
132 void ControlMath::showDialog(string const & name) const
134 dispatchFunc(LFUN_DIALOG_SHOW, name);
138 MathSymbol const & ControlMath::mathSymbol(string tex_name) const
140 map<string, MathSymbol>::const_iterator it =
141 math_symbols_.find(tex_name);
143 static MathSymbol unknown_symbol;
144 if (it == math_symbols_.end())
145 return unknown_symbol;
151 std::string const & ControlMath::texName(char_type math_symbol) const
153 map<char_type, string>::const_iterator it =
154 tex_names_.find(math_symbol);
156 static string empty_string;
157 if (it == tex_names_.end())
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", ""
173 int const nr_function_names = sizeof(function_names) / sizeof(char const *) - 1;
175 char const * latex_dots[] = {
176 "ldots", "cdots", "vdots", "ddots", ""
179 int const nr_latex_dots = sizeof(latex_dots) / sizeof(char const *) - 1;
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", ""
190 int const nr_latex_deco = sizeof(latex_deco) / sizeof(char const *) - 1;
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",
209 int const nr_latex_arrow = sizeof(latex_arrow) / sizeof(char const *);
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", ""
222 int const nr_latex_bop = sizeof(latex_bop) / sizeof(char const *);
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", ""
236 int const nr_latex_brel = sizeof(latex_brel) / sizeof(char const *);
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", ""
247 int const nr_latex_greek = sizeof(latex_greek) / sizeof(char const *);
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", "_",
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", ""
265 int const nr_latex_misc = sizeof(latex_misc) / sizeof(char const *);
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", ""
279 int const nr_latex_varsz = sizeof(latex_varsz) / sizeof(char const *);
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", ""
295 int const nr_latex_ams_misc = sizeof(latex_ams_misc) / sizeof(char const *);
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",
308 "upuparrows", "downdownarrows",
309 "upharpoonleft", "upharpoonright",
310 "downharpoonleft", "downharpoonright",
311 "leftrightharpoons", "rightleftharpoons",
312 "rightsquigarrow", "leftrightsquigarrow",
313 "nleftarrow", "nrightarrow", "nleftrightarrow",
314 "nLeftarrow", "nRightarrow", "nLeftrightarrow",
319 int const nr_latex_ams_arrows = sizeof(latex_ams_arrows) / sizeof(char const *);
321 char const * latex_ams_rel[] = {
323 "leqslant", "geqslant",
324 "eqslantless", "eqslantgtr",
326 "lessapprox", "gtrapprox",
327 "approxeq", "triangleq",
330 "lessgtr", "gtrless",
331 "lesseqgtr", "gtreqless",
332 "lesseqqgtr", "gtreqqless",
334 "thicksim", "thickapprox",
335 "backsim", "backsimeq",
336 "subseteqq", "supseteqq",
338 "sqsubset", "sqsupset",
339 "preccurlyeq", "succcurlyeq",
340 "curlyeqprec", "curlyeqsucc",
341 "precsim", "succsim",
342 "precapprox", "succapprox",
343 "vartriangleleft", "vartriangleright",
344 "trianglelefteq", "trianglerighteq",
346 "doteqdot", "risingdotseq", "fallingdotseq",
347 "vDash", "Vvdash", "Vdash",
348 "shortmid", "shortparallel",
349 "smallsmile", "smallfrown",
350 "blacktriangleleft", "blacktriangleright",
351 "because", "therefore",
359 int const nr_latex_ams_rel = sizeof(latex_ams_rel) / sizeof(char const *);
361 char const * latex_ams_nrel[] = {
364 "nleqslant", "ngeqslant",
368 "lvertneqq", "gvertneqq",
370 "lnapprox", "gnapprox",
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",
385 "nparallel", "nshortparallel",
389 int const nr_latex_ams_nrel = sizeof(latex_ams_nrel) / sizeof(char const *);
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", ""
403 int const nr_latex_ams_ops = sizeof(latex_ams_ops) / sizeof(char const *);
406 char const * latex_delimiters[] = {
407 "(", ")", "{", "}", "[", "]",
408 "lceil", "rceil", "lfloor", "rfloor", "langle", "rangle",
409 "uparrow", "updownarrow", "Uparrow", "Updownarrow", "downarrow", "Downarrow",
410 "|", "Vert", "/", "backslash", ""
414 int const nr_latex_delimiters = sizeof(latex_delimiters) / sizeof(char const *);
424 bool operator<(XPMmap const & lhs, XPMmap const & rhs)
426 return compare(lhs.key, rhs.key) < 0;
430 class CompareKey : public std::unary_function<XPMmap, bool> {
432 CompareKey(string const & name) : name_(name) {}
433 bool operator()(XPMmap const & other) const {
434 return other.key == name_;
441 XPMmap sorted_xpm_map[] = {
442 { "Bumpeq", "bumpeq2" },
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" },
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" },
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" }
478 size_t const nr_sorted_xpm_map = sizeof(sorted_xpm_map) / sizeof(XPMmap);
483 string const find_xpm(string const & name)
485 XPMmap const * const begin = sorted_xpm_map;
486 XPMmap const * const end = begin + nr_sorted_xpm_map;
487 BOOST_ASSERT(sorted(begin, end));
489 XPMmap const * const it =
490 std::find_if(begin, end, CompareKey(name));
494 xpm_name = it->value;
496 xpm_name = subst(name, "_", "underscore");
497 xpm_name = subst(xpm_name, ' ', '_');
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 xpm_name = subst(xpm_name, ",", "thinspace");
508 xpm_name = subst(xpm_name, ":", "mediumspace");
509 xpm_name = subst(xpm_name, ";", "thickspace");
510 xpm_name = subst(xpm_name, "!", "negthinspace");
513 LYXERR(Debug::GUI) << "find_xpm(" << name << ")\n"
514 << "Looking for math XPM called \""
515 << xpm_name << '"' << std::endl;
517 return libFileSearch("images/math/", xpm_name, "xpm").absFilename();
520 } // namespace frontend