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