3 * Purpose: Write math paragraphs in LaTeX
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: January 1996
8 * Dependencies: Xlib, XForms
10 * Copyright: 1996, 1997 Alejandro Aguilar Sierra
12 * Version: 0.8beta, Mathed & Lyx project.
14 * You are free to use and modify this code under the terms of
15 * the GNU General Public Licence version 2 or later.
21 #include "math_inset.h"
22 #include "math_iter.h"
23 #include "math_parser.h"
24 #include "support/lstrings.h"
30 extern char const * latex_mathenv[];
31 extern char * latex_mathspace[];
33 // quite a hack i know. Should be done with return values...
34 static int number_of_newlines;
36 char const * math_font_name[] = {
48 MathSpaceInset::Write(ostream & os, bool /* fragile */)
50 if (space >= 0 && space < 6) {
51 os << '\\' << latex_mathspace[space] << ' ';
57 MathDotsInset::Write(ostream & os, bool /* fragile */)
59 os << '\\' << name << ' ';
63 void MathSqrtInset::Write(ostream & os, bool fragile)
65 os << '\\' << name << '{';
66 MathParInset::Write(os, fragile);
71 void MathDelimInset::Write(ostream & os, bool fragile)
73 latexkeys * l = (left != '|') ? lm_get_key_by_id(left, LM_TK_SYM): 0;
74 latexkeys * r = (right != '|') ? lm_get_key_by_id(right, LM_TK_SYM): 0;
77 os << '\\' << l->name << ' ';
79 if (left == '{' || left == '}') {
80 os << '\\' << char(left) << ' ';
82 os << char(left) << ' ';
85 MathParInset::Write(os, fragile);
88 os << '\\' << r->name << ' ';
90 if (right == '{' || right == '}') {
91 os << '\\' << char(right) << ' ';
93 os << char(right) << ' ';
99 void MathDecorationInset::Write(ostream & os, bool fragile)
101 latexkeys * l = lm_get_key_by_id(deco, LM_TK_WIDE);
102 os << '\\' << l->name << '{';
103 MathParInset::Write(os, fragile);
108 void MathAccentInset::Write(ostream & os, bool fragile)
110 latexkeys * l = lm_get_key_by_id(code, LM_TK_ACCENT);
111 os << '\\' << l->name;
118 inset->Write(os, fragile);
120 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM) {
122 << math_font_name[fn-LM_TC_RM]
125 if (MathIsSymbol(fn)) {
126 latexkeys * l = lm_get_key_by_id(c, LM_TK_SYM);
128 os << '\\' << l->name << ' ';
133 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM)
142 void MathBigopInset::Write(ostream & os, bool /* fragile */)
144 bool limp = GetLimits();
148 if (limp && !(sym != LM_int && sym != LM_oint
149 && (GetStyle() == LM_ST_DISPLAY)))
152 if (!limp && (sym != LM_int && sym != LM_oint
153 && (GetStyle() == LM_ST_DISPLAY)))
160 void MathFracInset::Write(ostream & os, bool fragile)
162 os << '\\' << name << '{';
163 MathParInset::Write(os, fragile);
165 den->Write(os, fragile);
170 void MathParInset::Write(ostream & os, bool fragile)
175 MathedIter data(array);
177 MathedRowSt const * crow = getRowSt();
180 if (!Permit(LMPF_FIXED_SIZE)) {
181 l = lm_get_key_by_id(size, LM_TK_STY);
183 os << '\\' << l->name << ' ';
187 byte cx = data.GetChar();
190 byte * s = data.GetString(ls);
192 if (data.FCode() >= LM_TC_RM && data.FCode() <= LM_TC_TEXTRM) {
193 os << '\\' << math_font_name[data.FCode()-LM_TC_RM] << '{';
196 if (MathIsSymbol(data.FCode())) {
197 l = lm_get_key_by_id(*s, (data.FCode() == LM_TC_BSYM) ?
198 LM_TK_BIGSYM : LM_TK_SYM);
200 os << '\\' << l->name << ' ';
202 lyxerr << "Illegal symbol code[" << *s
203 << " " << ls << " " << data.FCode() << "]";
206 // Is there a standard logical XOR?
207 if ((data.FCode() == LM_TC_TEX && *s != '{' && *s != '}') ||
208 (data.FCode() == LM_TC_SPECIAL))
211 if (*s == '{') ++brace;
212 if (*s == '}') --brace;
214 if (*s == '}' && data.FCode() == LM_TC_TEX && brace < 0)
215 lyxerr <<"Math warning: Unexpected closing brace."
222 if (data.FCode()>= LM_TC_RM && data.FCode()<= LM_TC_TEXTRM)
225 if (MathIsInset(cx)) {
226 MathedInset * p = data.GetInset();
229 if (cx == LM_TC_DOWN)
231 p->Write(os, fragile);
232 if (cx == LM_TC_UP || cx == LM_TC_DOWN)
246 if (!crow->isNumbered()) {
249 if (crow->getLabel()) {
254 crow = crow->getNext();
259 ++number_of_newlines;
264 lyxerr << "WMath Error: unrecognized code[" << cx << "]";
270 if (!crow->isNumbered()) {
273 if (crow->getLabel()) {
281 // Just make sure that the correct number of braces are output.
289 // Something like this should work too:
290 os << string(brace, '}'); // not one-off error I hope.
295 void MathMatrixInset::Write(ostream & os, bool fragile)
297 if (GetType() == LM_OT_MATRIX){
303 if (v_align == 't' || v_align == 'b') {
311 ++number_of_newlines;
313 MathParInset::Write(os, fragile);
314 if (GetType() == LM_OT_MATRIX){
321 ++number_of_newlines;
326 void mathed_write(MathParInset * p, ostream & os, int * newlines,
327 bool fragile, char const * label)
329 number_of_newlines = 0;
330 short mathed_env = p->GetType();
332 if (mathed_env == LM_EN_INTEXT) {
333 if (fragile) os << "\\protect";
334 os << "\\( "; // changed from " \\( " (Albrecht Dress)
338 // Is this '\n' really needed, what can go wrong
339 //if it is not there? The reason why I want to avoid this is
340 // because of the "backlook" into the output stream.
344 if (!suffixIs(outf, '\n')) {
345 // in batchmode we need to make sure
346 // a space before an equation doesn't
347 // make the LaTeX output different
348 // compared to "Exported LaTeX" ARRae
349 // Modified to work in a cleaner and hopefully more general way
352 ++number_of_newlines;
355 if (mathed_env == LM_EN_DISPLAY){
359 << latex_mathenv[mathed_env]
362 ++number_of_newlines;
365 if (label && label[0] > ' ' && mathed_env == LM_EN_EQUATION){
369 ++number_of_newlines;
372 p->Write(os, fragile);
374 if (mathed_env == LM_EN_INTEXT){
375 if (fragile) os << "\\protect";
378 else if (mathed_env == LM_EN_DISPLAY) {
380 ++number_of_newlines;
384 << latex_mathenv[mathed_env]
386 number_of_newlines += 2;
388 *newlines = number_of_newlines;