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