]> git.lyx.org Git - lyx.git/blob - src/tex2lyx/math.C
Add a Buffer::fully_loaded member function, returning true only when
[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 * known_math_envs[] = { "equation", "equation*",
29         "eqnarray", "eqnarray*", "align", "align*", "gather", "gather*",
30         "multline", "multline*", 0};
31
32         for (char const ** what = known_math_envs; *what; ++what)
33                 if (*what == name)
34                         return true;
35         return false;
36 }
37
38
39 void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
40 {
41         while (p.good()) {
42                 Token const & t = p.get_token();
43
44 #ifdef FILEDEBUG
45                 cerr << "t: " << t << " flags: " << flags << "\n";
46 #endif
47
48                 if (flags & FLAG_ITEM) {
49                         if (t.cat() == catSpace)
50                                 continue;
51
52                         flags &= ~FLAG_ITEM;
53                         if (t.cat() == catBegin) {
54                                 // skip the brace and collect everything to the next matching
55                                 // closing brace
56                                 flags |= FLAG_BRACE_LAST;
57                                 continue;
58                         }
59
60                         // handle only this single token, leave the loop if done
61                         flags |= FLAG_LEAVE;
62                 }
63
64
65                 //
66                 // cat codes
67                 //
68                 if (t.cat() == catMath) {
69                         if (mode == MATHTEXT_MODE) {
70                                 // we are inside some text mode thingy, so opening new math is allowed
71                                 Token const & n = p.get_token();
72                                 if (n.cat() == catMath) {
73                                         // TeX's $$...$$ syntax for displayed math
74                                         os << "\\[";
75                                         parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
76                                         os << "\\]";
77                                         p.get_token(); // skip the second '$' token
78                                 } else {
79                                         // simple $...$  stuff
80                                         p.putback();
81                                         os << '$';
82                                         parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
83                                         os << '$';
84                                 }
85                         }
86
87                         else if (flags & FLAG_SIMPLE) {
88                                 // this is the end of the formula
89                                 return;
90                         }
91
92                         else {
93                                 cerr << "\nmode: " << mode << endl;
94                                 p.error("something strange in the parser\n");
95                                 break;
96                         }
97                 }
98
99                 else if (t.cat() == catLetter ||
100                                t.cat() == catSpace ||
101                                t.cat() == catSuper ||
102                                t.cat() == catSub ||
103                                t.cat() == catOther ||
104                                t.cat() == catAlign ||
105                                t.cat() == catActive ||
106                                t.cat() == catParameter)
107                         os << t.character();
108
109                 else if (t.cat() == catNewline) {
110                         //if (p.next_token().cat() == catNewline) {
111                         //      p.get_token();
112                         //      handle_par(os);
113                         //} else {
114                                 os << "\n "; // note the space
115                         //}
116                 }
117
118                 else if (t.cat() == catBegin) {
119                         os << '{';
120                         parse_math(p, os, FLAG_BRACE_LAST, mode);
121                         os << '}';
122                 }
123
124                 else if (t.cat() == catEnd) {
125                         if (flags & FLAG_BRACE_LAST)
126                                 return;
127                         os << "unexpected '}' in math\n";
128                 }
129
130                 else if (t.cat() == catComment)
131                         handle_comment(p);
132
133                 //
134                 // control sequences
135                 //
136
137                 else if (t.cs() == "(") {
138                         os << "\\(";
139                         parse_math(p, os, FLAG_SIMPLE2, MATH_MODE);
140                         os << "\\)";
141                 }
142
143                 else if (t.cs() == "[") {
144                         // special handling of a few common SW user quirks
145                         p.skip_spaces();
146                         //if (p.next_token().cs() ==
147                         os << "\\[";
148                         parse_math(p, os, FLAG_EQUATION, MATH_MODE);
149                         os << "\\]";
150                 }
151
152                 else if (t.cs() == "protect")
153                         // ignore \\protect, will hopefully be re-added during output
154                         ;
155
156                 else if (t.cs() == "begin") {
157                         string const name = p.getArg('{', '}');
158                         active_environments.push_back(name);
159                         os << "\\begin{" << name << "}";
160                         if (name == "tabular")
161                                 parse_math(p, os, FLAG_END, MATHTEXT_MODE);
162                         else
163                                 parse_math(p, os, FLAG_END, mode);
164                         os << "\\end{" << name << "}";
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                                 active_environments.pop_back();
175                                 return;
176                         }
177                         p.error("found 'end' unexpectedly");
178                 }
179
180                 else if (t.cs() == ")") {
181                         if (flags & FLAG_SIMPLE2)
182                                 return;
183                         p.error("found '\\)' unexpectedly");
184                 }
185
186                 else if (t.cs() == "]") {
187                         if (flags & FLAG_EQUATION)
188                                 return;
189                         p.error("found '\\]' unexpectedly");
190                 }
191
192                 else if (t.cs() == "textrm" || t.cs() == "textsf" || t.cs() == "textbf"
193                                 || t.cs() == "texttt" || t.cs() == "textsc") {
194                         os << '\\' << t.cs() << '{';
195                         parse_math(p, os, FLAG_ITEM, MATHTEXT_MODE);
196                         os << '}';
197                 }
198
199                 else if (t.cs() == "mbox") {
200                         os << "\\mbox{";
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
220                         os << t.asInput();
221
222                 if (flags & FLAG_LEAVE) {
223                         flags &= ~FLAG_LEAVE;
224                         break;
225                 }
226         }
227 }
228
229
230
231
232 // }])