3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
26 bool is_math_env(string const & name)
28 static char const * const known_math_envs[] = { "equation",
29 "equation*", "eqnarray", "eqnarray*", "align", "align*", "gather",
30 "gather*", "multline", "multline*", "math", "displaymath", "flalign",
32 // These require extra args
33 "alignat", "alignat*", "xalignat", "xalignat*", "xxalignat",
36 for (char const * const * what = known_math_envs; *what; ++what)
43 void parse_math(Parser & p, ostream & os, unsigned flags, const mode_type mode)
46 Token const & t = p.get_token();
49 cerr << "t: " << t << " flags: " << flags << "\n";
52 if (flags & FLAG_ITEM) {
53 if (t.cat() == catSpace)
57 if (t.cat() == catBegin) {
58 // skip the brace and collect everything to the next matching
60 flags |= FLAG_BRACE_LAST;
64 // handle only this single token, leave the loop if done
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
79 parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
81 p.get_token(); // skip the second '$' token
86 parse_math(p, os, FLAG_SIMPLE, MATH_MODE);
91 else if (flags & FLAG_SIMPLE) {
92 // this is the end of the formula
97 cerr << "\nmode: " << mode << endl;
98 p.error("something strange in the parser\n");
103 else if (t.cat() == catLetter ||
104 t.cat() == catSuper ||
106 t.cat() == catOther ||
107 t.cat() == catAlign ||
108 t.cat() == catActive ||
109 t.cat() == catParameter)
112 else if (t.cat() == catBegin) {
114 parse_math(p, os, FLAG_BRACE_LAST, mode);
118 else if (t.cat() == catEnd) {
119 if (flags & FLAG_BRACE_LAST)
121 os << "unexpected '}' in math\n";
124 else if (t.cat() == catComment) {
126 cerr << "Ignoring comment: " << t.asInput();
136 else if (t.cs() == "(") {
138 parse_math(p, os, FLAG_SIMPLE2, MATH_MODE);
142 else if (t.cs() == "[") {
143 // special handling of a few common SW user quirks
145 //if (p.next_token().cs() ==
147 parse_math(p, os, FLAG_EQUATION, MATH_MODE);
151 else if (t.cs() == "protect")
152 // ignore \\protect, will hopefully be re-added during output
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);
162 parse_math(p, os, FLAG_END, mode);
163 os << "\\end{" << name << "}";
164 active_environments.pop_back();
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() + "}");
176 p.error("found 'end' unexpectedly");
179 else if (t.cs() == ")") {
180 if (flags & FLAG_SIMPLE2)
182 p.error("found '\\)' unexpectedly");
185 else if (t.cs() == "]") {
186 if (flags & FLAG_EQUATION)
188 p.error("found '\\]' unexpectedly");
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);
199 else if (t.cs() == "mbox" || t.cs() == "fbox") {
200 os << "\\" << t.cs() << '{';
201 parse_math(p, os, FLAG_ITEM, MATHTEXT_MODE);
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 << "}";
216 else if (t.cs() == "ss")
219 else if (t.cs() == "cr") {
220 // lyx can't handle \\cr
221 cerr << "Warning: Converting TeX '\\cr' to LaTeX '\\\\'."
229 if (flags & FLAG_LEAVE) {
230 flags &= ~FLAG_LEAVE;