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