]> git.lyx.org Git - lyx.git/blob - src/tex2lyx/math.C
If I ever see another licence blurb again, it'll be too soon...
[lyx.git] / src / tex2lyx / math.C
1 /**
2  * \file math.C
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 // {[(
12
13 #include <config.h>
14
15 #include "tex2lyx.h"
16
17 #include <iostream>
18 #include <vector>
19
20 using std::cerr;
21 using std::endl;
22 using std::ostream;
23 using std::string;
24 using std::vector;
25
26
27 bool is_math_env(string const & name)
28 {
29         static char const * known_math_envs[] = { "equation", "equation*",
30         "eqnarray", "eqnarray*", "align", "align*", "gather", "gather*",
31         "multline", "multline*", 0};
32
33         for (char const ** what = known_math_envs; *what; ++what)
34                 if (*what == name)
35                         return true;
36         return false;
37 }
38
39
40 void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
41 {
42         while (p.good()) {
43                 Token const & t = p.get_token();
44
45 #ifdef FILEDEBUG
46                 cerr << "t: " << t << " flags: " << flags << "\n";
47 #endif
48
49                 if (flags & FLAG_ITEM) {
50                         if (t.cat() == catSpace)
51                                 continue;
52
53                         flags &= ~FLAG_ITEM;
54                         if (t.cat() == catBegin) {
55                                 // skip the brace and collect everything to the next matching
56                                 // closing brace
57                                 flags |= FLAG_BRACE_LAST;
58                                 continue;
59                         }
60
61                         // handle only this single token, leave the loop if done
62                         flags |= FLAG_LEAVE;
63                 }
64
65
66                 //
67                 // cat codes
68                 //
69                 if (t.cat() == catMath) {
70                         if (mode == MATHTEXT_MODE) {
71                                 // we are inside some text mode thingy, so opening new math is allowed
72                                 Token const & n = p.get_token();
73                                 if (n.cat() == catMath) {
74                                         // TeX's $$...$$ syntax for displayed math
75                                         os << "\\[";
76                                         parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
77                                         os << "\\]";
78                                         p.get_token(); // skip the second '$' token
79                                 } else {
80                                         // simple $...$  stuff
81                                         p.putback();
82                                         os << '$';
83                                         parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
84                                         os << '$';
85                                 }
86                         }
87
88                         else if (flags & FLAG_SIMPLE) {
89                                 // this is the end of the formula
90                                 return;
91                         }
92
93                         else {
94                                 cerr << "\nmode: " << mode << endl;
95                                 p.error("something strange in the parser\n");
96                                 break;
97                         }
98                 }
99
100                 else if (t.cat() == catLetter ||
101                                t.cat() == catSpace ||
102                                t.cat() == catSuper ||
103                                t.cat() == catSub ||
104                                t.cat() == catOther ||
105                                t.cat() == catAlign ||
106                                t.cat() == catActive ||
107                                t.cat() == catParameter)
108                         os << t.character();
109
110                 else if (t.cat() == catNewline) {
111                         //if (p.next_token().cat() == catNewline) {
112                         //      p.get_token();
113                         //      handle_par(os);
114                         //} else {
115                                 os << "\n "; // note the space
116                         //}
117                 }
118
119                 else if (t.cat() == catBegin) {
120                         os << '{';
121                         parse_math(p, os, FLAG_BRACE_LAST, mode);
122                         os << '}';
123                 }
124
125                 else if (t.cat() == catEnd) {
126                         if (flags & FLAG_BRACE_LAST)
127                                 return;
128                         os << "unexpected '}' in math\n";
129                 }
130
131                 else if (t.cat() == catComment)
132                         handle_comment(p);
133
134                 //
135                 // control sequences
136                 //
137
138                 else if (t.cs() == "(") {
139                         os << "\\(";
140                         parse_math(p, os, FLAG_SIMPLE2, MATH_MODE);
141                         os << "\\)";
142                 }
143
144                 else if (t.cs() == "[") {
145                         // special handling of a few common SW user quirks
146                         p.skip_spaces();
147                         //if (p.next_token().cs() == 
148                         os << "\\[";
149                         parse_math(p, os, FLAG_EQUATION, MATH_MODE);
150                         os << "\\]";
151                 }
152
153                 else if (t.cs() == "protect")
154                         // ignore \\protect, will hopefully be re-added during output
155                         ;
156
157                 else if (t.cs() == "begin") {
158                         string const name = p.getArg('{', '}');
159                         active_environments.push_back(name);
160                         os << "\\begin{" << name << "}";
161                         if (name == "tabular")
162                                 parse_math(p, os, FLAG_END, MATHTEXT_MODE);
163                         else
164                                 parse_math(p, os, FLAG_END, mode);
165                         os << "\\end{" << name << "}";
166                 }
167
168                 else if (t.cs() == "end") {
169                         if (flags & FLAG_END) {
170                                 // eat environment name
171                                 string const name = p.getArg('{', '}');
172                                 if (name != active_environment())
173                                         p.error("\\end{" + name + "} does not match \\begin{"
174                                                 + active_environment() + "}");
175                                 active_environments.pop_back();
176                                 return;
177                         }
178                         p.error("found 'end' unexpectedly");
179                 }
180
181                 else if (t.cs() == ")") {
182                         if (flags & FLAG_SIMPLE2)
183                                 return;
184                         p.error("found '\\)' unexpectedly");
185                 }
186
187                 else if (t.cs() == "]") {
188                         if (flags & FLAG_EQUATION)
189                                 return;
190                         p.error("found '\\]' unexpectedly");
191                 }
192
193                 else if (t.cs() == "textrm" || t.cs() == "textsf" || t.cs() == "textbf"
194                                 || t.cs() == "texttt" || t.cs() == "textsc") {
195                         os << '\\' << t.cs() << '{';
196                         parse_math(p, os, FLAG_ITEM, MATHTEXT_MODE);
197                         os << '}';
198                 }
199
200                 else if (t.cs() == "mbox") {
201                         os << "\\mbox{";
202                         parse_math(p, os, FLAG_ITEM, MATHTEXT_MODE);
203                         os << '}';
204                 }
205
206                 else if (t.cs() == "\"") {
207                         string const name = p.verbatim_item();
208                              if (name == "a") os << 'ä';
209                         else if (name == "o") os << 'ö';
210                         else if (name == "u") os << 'ü';
211                         else if (name == "A") os << 'Ä';
212                         else if (name == "O") os << 'Ö';
213                         else if (name == "U") os << 'Ü';
214                         else os << "\"{" << name << "}";
215                 }
216
217                 else if (t.cs() == "ss")
218                         os << "ß";
219
220                 else 
221                         os << t.asInput();
222
223                 if (flags & FLAG_LEAVE) {
224                         flags &= ~FLAG_LEAVE;
225                         break;
226                 }
227         }
228 }
229
230
231
232
233 // }])