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