]> git.lyx.org Git - lyx.git/blob - src/mathed/math_factory.C
cosmetics
[lyx.git] / src / mathed / math_factory.C
1 #include <config.h>
2
3 #include "math_parser.h"
4 #include "math_arrayinset.h"
5 #include "math_amsarrayinset.h"
6 #include "math_binominset.h"
7 #include "math_boxinset.h"
8 #include "math_casesinset.h"
9 #include "math_decorationinset.h"
10 #include "math_dotsinset.h"
11 #include "math_fboxinset.h"
12 #include "math_fontinset.h"
13 #include "math_fracinset.h"
14 #include "math_kerninset.h"
15 #include "math_lefteqninset.h"
16 #include "math_macro.h"
17 #include "math_macrotable.h"
18 #include "math_macroarg.h"
19 #include "math_notinset.h"
20 #include "math_parboxinset.h"
21 #include "math_rootinset.h"
22 #include "math_sizeinset.h"
23 #include "math_spaceinset.h"
24 #include "math_splitinset.h"
25 #include "math_sqrtinset.h"
26 #include "math_stackrelinset.h"
27 #include "math_substackinset.h"
28 #include "math_symbolinset.h"
29 #include "math_undersetinset.h"
30 #include "math_unknowninset.h"
31 #include "math_xarrowinset.h"
32 #include "math_xymatrixinset.h"
33 #include "math_xyarrowinset.h"
34
35 //#include "insets/insetref.h"
36 #include "ref_inset.h"
37
38 #include "math_metricsinfo.h"
39 #include "debug.h"
40 #include "math_support.h"
41 #include "Lsstream.h"
42 #include "support/filetools.h" // LibFileSearch
43 #include "frontends/font_loader.h"
44
45 #include <map>
46 #include <fstream>
47
48
49 namespace {
50
51 // file scope
52 typedef std::map<string, latexkeys> WordList;
53 WordList theWordList;
54
55
56 struct key_type {
57         ///
58         string name;
59         ///
60         string inset;
61         ///
62         string extra;
63 };
64
65
66 key_type wordlist_array[] =
67 {
68         {"!",  "space", ""},
69         {",",  "space", ""},
70         {":",  "space", ""},
71         {";",  "space", ""},
72         {"Vmatrix",  "matrix", ""},
73         {"acute",  "decoration", ""},
74         {"bar",  "decoration", ""},
75         {"begin",  "begin", ""},
76         {"bf",  "oldfont", ""},
77         {"bmatrix",  "matrix", ""},
78         {"acute",  "decoration", ""},
79         {"breve",  "decoration", ""},
80         {"cal",  "oldfont", ""},
81         {"cdots",  "dots", ""},
82         {"check",  "decoration", ""},
83         {"ddot",  "decoration", ""},
84         {"dddot",  "decoration", ""},
85         {"ddots",  "dots", ""},
86         {"displaystyle",  "style", ""},
87         {"dot",  "decoration", ""},
88         {"dotsb",  "dots", ""},
89         {"dotsc",  "dots", ""},
90         {"dotsi",  "dots", ""},
91         {"dotsm",  "dots", ""},
92         {"dotso",  "dots", ""},
93         {"end",  "end", ""},
94         {"fbox",  "fbox", ""},
95         {"frak",  "font", ""},
96         {"grave",  "decoration", ""},
97         {"hat",  "decoration", ""},
98         {"it",  "oldfont", ""},
99         {"label",  "label", ""},
100         {"ldots",  "dots", ""},
101         {"left",  "left", ""},
102         {"lyxnegspace",  "space", ""},
103         {"lyxposspace",  "space", ""},
104         {"mathbb",  "font", ""},
105         {"mathbf",  "font", ""},
106         {"mathcal",  "font", ""},
107         {"mathfrak",  "font", ""},
108         {"mathit",  "font", ""},
109         {"mathnormal",  "font", ""},
110         {"mathring",  "decoration", ""},
111         {"mathrm",  "font", ""},
112         {"mathsf",  "font", ""},
113         {"mathtt",  "font", ""},
114         {"matrix",  "matrix", ""},
115         {"mbox",  "mbox", ""},
116         {"newcommand",  "newcommand", ""},
117         {"overbrace",  "decoration", ""},
118         {"overleftarrow",  "decoration", ""},
119         {"overline",  "decoration", ""},
120         {"overrightarrow",  "decoration", ""},
121         {"overleftrightarrow", "decoration", ""},
122         {"pageref",  "ref", ""},
123         {"parbox",  "parbox", ""},
124         {"pmatrix",  "matrix", ""},
125         {"prettyref",  "ref", ""},
126         {"protect",  "protect", ""},
127         {"qquad",  "space", ""},
128         {"quad",  "space", ""},
129         {"ref",  "ref", ""},
130         {"right",  "right", ""},
131         {"rm",  "oldfont", ""},
132         {"scriptscriptstyle",  "style", ""},
133         {"scriptstyle",  "style", ""},
134         {"text",    "font", "mathtext"},
135         {"textbf",  "font", "mathtext"},
136         {"textipa", "font", "mathtext"},
137         {"textit",  "font", "mathtext"},
138         {"textmd",  "font", "mathtext"},
139         {"textrm",  "font", "mathtext"},
140         {"textsl",  "font", "mathtext"},
141         {"textup",  "font", "mathtext"},
142         {"textstyle",  "style", ""},
143         {"tilde",  "decoration", ""},
144         {"tt",  "oldfont", ""},
145         {"underbar",  "decoration", ""},
146         {"underbrace",  "decoration", ""},
147         {"underleftarrow", "decoration", ""},
148         {"underline",  "decoration", ""},
149         {"underrightarrow", "decoration", ""},
150         {"underleftrightarrow", "decoration", ""},
151         {"underset",  "underset", ""},
152         {"vdots",  "dots", ""},
153         {"vec",  "decoration", ""},
154         {"vmatrix",  "matrix", ""},
155         {"vpageref",  "ref", ""},
156         {"vref",  "ref", ""},
157         {"widehat",  "decoration", ""},
158         {"widetilde",  "decoration", ""}
159 };
160
161
162 bool math_font_available(string & name)
163 {
164         LyXFont f;
165         augmentFont(f, name);
166
167         // Do we have the font proper?
168         if (fontloader.available(f))
169                 return true;
170
171         // can we fake it?
172         if (name == "eufrak") {
173                 name = "lyxfakefrak";
174                 return true;
175         }
176
177         lyxerr[Debug::MATHED] << "font " << name << " not available and I can't fake it\n";
178         return false;
179 }
180
181
182 void readSymbols(string const & filename)
183 {
184         lyxerr[Debug::MATHED] << "read symbols from " << filename << "\n";
185         std::ifstream fs(filename.c_str());
186         while (fs) {
187                 int charid     = 0;
188                 int fallbackid = 0;
189                 latexkeys tmp;
190                 string line;
191                 getline(fs, line);
192                 istringstream is(line);
193                 is      >> tmp.name
194                                 >> tmp.inset
195                                 >> charid
196                                 >> fallbackid
197                                 >> tmp.extra
198                                 >> tmp.xmlname;
199                 if (!is)
200                         continue;
201
202                 // tmp.inset _is_ the fontname here.
203                 // create fallbacks if necessary
204                 if (tmp.extra == "func" || tmp.extra == "funclim" || tmp.extra=="special") {
205                         lyxerr[Debug::MATHED] << "symbol abuse for " << tmp.name << "\n";
206                         tmp.draw = tmp.name;
207                 } else if (math_font_available(tmp.inset)) {
208                         lyxerr[Debug::MATHED] << "symbol available for " << tmp.name << "\n";
209                         tmp.draw += char(charid);
210                 } else if (fallbackid) {
211                         if (tmp.inset == "cmex")
212                                 tmp.inset  = "lyxsymbol";
213                         else
214                                 tmp.inset  = "lyxboldsymbol";
215                         lyxerr[Debug::MATHED] << "symbol fallback for " << tmp.name << "\n";
216                         tmp.draw += char(fallbackid); 
217                 } else {
218                         lyxerr[Debug::MATHED] << "faking " << tmp.name << "\n";
219                         tmp.draw = tmp.name;
220                         tmp.inset = "lyxtex";
221                 }
222
223                 if (theWordList.find(tmp.name) != theWordList.end())
224                         lyxerr[Debug::MATHED] << "readSymbols: inset " << tmp.name
225                                << " already exists.\n";
226                 else
227                         theWordList[tmp.name] = tmp;
228                 lyxerr[Debug::MATHED] << "read symbol '" << tmp.name
229                                         <<  "  inset: " << tmp.inset
230                                         <<  "  draw: " << int(tmp.draw[0])
231                                         <<  "  extra: " << tmp.extra
232                                         << "'\n";
233         }
234 }
235
236
237 void initSymbols()
238 {
239         unsigned const n = sizeof(wordlist_array) / sizeof(wordlist_array[0]);
240         for (key_type * p = wordlist_array; p != wordlist_array + n; ++p) {
241                 latexkeys tmp;
242                 tmp.name  = p->name;
243                 tmp.inset = p->inset;
244                 tmp.draw  = p->name;
245                 theWordList[p->name] = tmp;
246         }
247
248         lyxerr[Debug::MATHED] << "reading symbols file\n";
249         string const file = LibFileSearch(string(), "symbols");
250         if (file.empty())
251                 lyxerr << "Could not find symbols file\n";
252         else
253                 readSymbols(file);
254 }
255
256
257 } // namespace anon
258
259
260 latexkeys const * in_word_set(string const & str)
261 {
262         static bool initialized = false;
263
264         if (!initialized) {
265                 initSymbols();
266                 initialized = true;
267         }
268
269         WordList::iterator it = theWordList.find(str);
270         //lyxerr << "looking up '" << str << "' found: "
271         // << (it != theWordList.end()) << "\n";
272         return (it != theWordList.end()) ? &(it->second) : 0;
273 }
274
275
276 MathAtom createMathInset(string const & s)
277 {
278         lyxerr[Debug::MATHED] << "creating inset with name: '" << s << "'\n";
279         if (s.size() == 2 && s[0] == '#' && s[1] >= '1' && s[1] <= '9')
280                 return MathAtom(new MathMacroArgument(s[1] - '0'));
281
282         if (s.size() == 3 && s[0] == '\\' && s[1] == '#'
283                         && s[2] >= '1' && s[2] <= '9')
284                 return MathAtom(new MathMacroArgument(s[2] - '0'));
285         if (s == "kern")
286                 return MathAtom(new MathKernInset);
287         if (s == "xymatrix")
288                 return MathAtom(new MathXYMatrixInset);
289         if (s == "xrightarrow" || s == "xleftarrow")
290                 return MathAtom(new MathXArrowInset(s));
291         if (s == "split" || s == "gathered" || s == "aligned")
292                 return MathAtom(new MathSplitInset(s));
293         if (s == "cases")
294                 return MathAtom(new MathCasesInset);
295         if (s == "substack")
296                 return MathAtom(new MathSubstackInset);
297         if (s == "subarray" || s == "array")
298                 return MathAtom(new MathArrayInset(s, 1, 1));
299         if (s == "sqrt")
300                 return MathAtom(new MathSqrtInset);
301         if (s == "root")
302                 return MathAtom(new MathRootInset);
303         if (s == "stack")
304                 return MathAtom(new MathStackrelInset);
305         if (s == "binom" || s == "choose")
306                 return MathAtom(new MathBinomInset(s == "choose"));
307         if (s == "over" || s == "frac")
308                 return MathAtom(new MathFracInset);
309         if (s == "atop")
310                 return MathAtom(new MathFracInset(true));
311         if (s == "not")
312                 return MathAtom(new MathNotInset);
313         if (s == "lefteqn")
314                 return MathAtom(new MathLefteqnInset);
315
316         latexkeys const * l = in_word_set(s);
317         if (l) {
318                 string const & inset = l->inset;
319                 lyxerr[Debug::MATHED] << " found inset: '" << inset << "'\n";
320                 if (inset == "ref")
321                         return MathAtom(new RefInset(l->name));
322                 if (inset == "underset")
323                         return MathAtom(new MathUndersetInset);
324                 if (inset == "decoration")
325                         return MathAtom(new MathDecorationInset(l->name));
326                 if (inset == "space")
327                         return MathAtom(new MathSpaceInset(l->name));
328                 if (inset == "dots")
329                         return MathAtom(new MathDotsInset(l->name));
330                 if (inset == "mbox")
331                         return MathAtom(new MathBoxInset(l->name));
332                 if (inset == "parbox")
333                         return MathAtom(new MathParboxInset);
334                 if (inset == "fbox")
335                         return MathAtom(new MathFboxInset);
336                 if (inset == "style")
337                         return MathAtom(new MathSizeInset(l));
338                 if (inset == "font")
339                         return MathAtom(new MathFontInset(l->name));
340                 if (inset == "oldfont")
341                         return MathAtom(new MathFontInset(l->name));
342                 if (inset == "matrix")
343                         return MathAtom(new MathAMSArrayInset(s));
344                 return MathAtom(new MathSymbolInset(l));
345         }
346
347         if (MathMacroTable::has(s))
348                 return MathAtom(new MathMacro(s));
349
350         //lyxerr[Debug::MATHED] << "creating inset 2 with name: '" << s << "'\n";
351         return MathAtom(new MathUnknownInset(s));
352 }