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