]> git.lyx.org Git - lyx.git/blob - src/mathed/math_write.C
Baruch's graphic-inset patch.
[lyx.git] / src / mathed / math_write.C
1 /*
2  *  File:        math_write.h
3  *  Purpose:     Write math paragraphs in LaTeX
4  *  Author:      Alejandro Aguilar Sierra <asierra@servidor.unam.mx> 
5  *  Created:     January 1996
6  *  Description: 
7  *
8  *  Dependencies: Xlib, XForms
9  *
10  *  Copyright: 1996, 1997 Alejandro Aguilar Sierra
11  *
12  *   Version: 0.8beta, Mathed & Lyx project.
13  *
14  *   You are free to use and modify this code under the terms of
15  *   the GNU General Public Licence version 2 or later.
16  */
17
18 #include <config.h>
19
20 #include "LString.h"
21 #include "math_inset.h"
22 #include "math_iter.h"
23 #include "math_parser.h"
24 #include "support/lstrings.h"
25 #include "debug.h"
26
27 using std::ostream;
28 using std::endl;
29
30 extern char const * latex_mathenv[];
31 extern char * latex_mathspace[];
32
33 // quite a hack i know. Should be done with return values...
34 static int number_of_newlines;
35
36 char const * math_font_name[] = {
37    "mathrm",
38    "mathcal",
39    "mathbf",
40    "mathsf",
41    "mathtt",
42    "mathit",
43    "textrm"
44 };
45
46
47 void
48 MathSpaceInset::Write(ostream & os, bool /* fragile */)
49 {
50    if (space >= 0 && space < 6) {
51            os << '\\' << latex_mathspace[space] << ' ';
52    }
53 }
54
55
56 void
57 MathDotsInset::Write(ostream & os, bool /* fragile */)
58 {
59         os << '\\' << name << ' ';
60 }
61
62
63 void MathSqrtInset::Write(ostream & os, bool fragile)
64 {
65         os << '\\' << name << '{';
66         MathParInset::Write(os, fragile); 
67         os << '}';
68 }
69
70
71 void MathDelimInset::Write(ostream & os, bool fragile)
72 {
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;
75     os << "\\left";
76     if (l) {
77             os << '\\' << l->name << ' ';
78     } else {
79         if (left == '{' || left == '}') {
80                 os << '\\' << char(left) << ' ';
81         } else {
82                 os << char(left) << ' ';
83         }
84     }
85    MathParInset::Write(os, fragile);
86    os << "\\right";
87    if (r) {
88            os << '\\' << r->name << ' ';
89    } else {
90        if (right == '{' || right == '}') {
91                os << '\\' << char(right) << ' ';
92       } else {
93               os << char(right) << ' ';
94       }
95    }
96 }
97
98
99 void MathDecorationInset::Write(ostream & os, bool fragile)
100 {
101         latexkeys * l = lm_get_key_by_id(deco, LM_TK_WIDE);
102         if (fragile &&
103             (strcmp(l->name, "overbrace") == 0 ||
104              strcmp(l->name, "underbrace") == 0 ||
105              strcmp(l->name, "overleftarrow") == 0 ||
106              strcmp(l->name, "overrightarrow") == 0))
107                 os << "\\protect";
108         os << '\\' << l->name << '{';
109         MathParInset::Write(os, fragile);  
110         os << '}';
111 }
112
113
114 void MathAccentInset::Write(ostream & os, bool fragile)
115 {
116         latexkeys * l = lm_get_key_by_id(code, LM_TK_ACCENT);
117         os << '\\' << l->name;
118         if (code!= LM_not)
119                 os << '{';
120         else
121                 os << ' ';
122         
123         if (inset) {
124                 inset->Write(os, fragile);
125         } else {
126                 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM) {
127                         os << '\\'
128                            << math_font_name[fn-LM_TC_RM]
129                            << '{';
130                 }
131                 if (MathIsSymbol(fn)) {
132                         latexkeys * l = lm_get_key_by_id(c, LM_TK_SYM);
133                         if (l) {
134                                 os << '\\' << l->name << ' ';
135                         }
136                 } else
137                         os << char(c);
138                 
139                 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM)
140                         os << '}';
141         }
142         
143         if (code!= LM_not)
144                 os << '}';
145 }
146
147
148 void MathBigopInset::Write(ostream & os, bool /* fragile */)
149 {
150     bool limp = GetLimits();
151     
152     os << '\\' << name;
153     
154     if (limp && !(sym != LM_int && sym != LM_oint
155                   && (GetStyle() == LM_ST_DISPLAY)))
156             os << "\\limits ";
157     else 
158     if (!limp && (sym != LM_int && sym != LM_oint
159                   && (GetStyle() == LM_ST_DISPLAY)))
160             os << "\\nolimits ";
161     else 
162             os << ' ';
163 }
164
165
166 void MathFracInset::Write(ostream & os, bool fragile)
167 {
168         os << '\\' << name << '{';
169         MathParInset::Write(os, fragile);
170         os << "}{";
171         den->Write(os, fragile);
172         os << '}';
173 }
174
175
176 void MathParInset::Write(ostream & os, bool fragile)
177 {
178         if (!array) return;
179         int brace = 0;
180         latexkeys * l;
181         MathedIter data(array);
182         // hack
183         MathedRowSt const * crow = getRowSt();   
184         data.Reset();
185         
186         if (!Permit(LMPF_FIXED_SIZE)) { 
187                 l = lm_get_key_by_id(size, LM_TK_STY);
188                 if (l) {
189                         os << '\\' << l->name << ' ';
190                 }
191         }
192         while (data.OK()) {
193                 byte cx = data.GetChar();
194                 if (cx >= ' ') {
195                         int ls;
196                         byte * s = data.GetString(ls);
197                         
198                         if (data.FCode() >= LM_TC_RM && data.FCode() <= LM_TC_TEXTRM) {
199                                 os << '\\' << math_font_name[data.FCode()-LM_TC_RM] << '{';
200                         }
201                         while (ls > 0) {
202                                 if (MathIsSymbol(data.FCode())) {
203                                         l = lm_get_key_by_id(*s, (data.FCode() == LM_TC_BSYM) ?
204                                                              LM_TK_BIGSYM : LM_TK_SYM);
205                                         if (l) {
206                                                 os << '\\' << l->name << ' ';
207                                         } else { 
208                                                 lyxerr << "Illegal symbol code[" << *s
209                                                        << " " << ls << " " << data.FCode() << "]";
210                                         }
211                                 } else {
212                                         // Is there a standard logical XOR?
213                                         if ((data.FCode() == LM_TC_TEX && *s != '{' && *s != '}') ||
214                                             (data.FCode() == LM_TC_SPECIAL))
215                                                 os << '\\';
216                                         else {
217                                                 if (*s == '{') ++brace;
218                                                 if (*s == '}') --brace;
219                                         }
220                                         if (*s == '}' && data.FCode() == LM_TC_TEX && brace < 0) 
221                                                 lyxerr <<"Math warning: Unexpected closing brace."
222                                                        << endl;
223                                         else           
224                                                 os << char(*s);
225                                 }
226                                 ++s; --ls;
227                         }
228                         if (data.FCode()>= LM_TC_RM && data.FCode()<= LM_TC_TEXTRM)
229                                 os << '}';
230                 } else     
231                         if (MathIsInset(cx)) {
232                                 MathedInset * p = data.GetInset();
233                                 if (cx == LM_TC_UP)
234                                         os << "^{";
235                                 if (cx == LM_TC_DOWN)
236                                         os << "_{";
237                                 p->Write(os, fragile);
238                                 if (cx == LM_TC_UP || cx == LM_TC_DOWN)
239                                         os << '}';
240                                 data.Next();
241                         } else
242                                 switch(cx) {
243                                 case LM_TC_TAB:
244                                 {
245                                         os << " & ";
246                                         data.Next();
247                                         break;
248                                 }
249                                 case LM_TC_CR:
250                                 {
251                                         if (crow) {
252                                                 if (!crow->isNumbered()) {  
253                                                         os << "\\nonumber ";
254                                                 }
255                                                 if (crow->getLabel()) {
256                                                         os << "\\label{"
257                                                            << crow->getLabel()
258                                                            << "} ";
259                                                 }
260                                                 crow = crow->getNext();
261                                         }
262                                         if (fragile)
263                                                 os << "\\protect";
264                                         os << "\\\\\n";
265                                         ++number_of_newlines;
266                                         data.Next();
267                                         break;
268                                 }
269                                 default:
270                                         lyxerr << "WMath Error: unrecognized code[" << cx << "]";
271                                         return;
272                                 }     
273         }
274         
275         if (crow) {
276                 if (!crow->isNumbered()) {
277                         os << "\\nonumber ";
278                 }
279                 if (crow->getLabel()) {
280                         os << "\\label{"
281                            << crow->getLabel()
282                            << "} ";
283                 }
284         }
285
286         if (brace > 0)
287                 os << string(brace, '}');
288 }
289
290
291 void MathMatrixInset::Write(ostream & os, bool fragile)
292 {
293     if (GetType() == LM_OT_MATRIX){
294             if (fragile)
295                     os << "\\protect";
296             os << "\\begin{"
297                << name
298                << '}';
299         if (v_align == 't' || v_align == 'b') {
300                 os << '['
301                    << char(v_align)
302                    << ']';
303         }
304         os << '{'
305            << h_align
306            << "}\n";
307         ++number_of_newlines;
308     }
309     MathParInset::Write(os, fragile);
310     if (GetType() == LM_OT_MATRIX){
311             os << "\n";
312             if (fragile)
313                     os << "\\protect";
314             os << "\\end{"
315                << name
316                << '}';
317         ++number_of_newlines;
318     }
319 }
320
321
322 void mathed_write(MathParInset * p, ostream & os, int * newlines,
323                   bool fragile, char const * label)
324 {
325    number_of_newlines = 0;
326    short mathed_env = p->GetType();
327
328    if (mathed_env == LM_EN_INTEXT) {
329            if (fragile) os << "\\protect";
330            os << "\\( "; // changed from " \\( " (Albrecht Dress)
331    } 
332    else {
333      if (mathed_env == LM_EN_DISPLAY){
334              os << "\\[\n";
335      } else {
336              os << "\\begin{"
337                 << latex_mathenv[mathed_env]
338                 << "}\n";
339      }
340      ++number_of_newlines;
341    }
342    
343    if (label && label[0] > ' ' && mathed_env == LM_EN_EQUATION){
344            os << "\\label{"
345               << label
346               << "}\n";
347      ++number_of_newlines;
348    }
349
350    p->Write(os, fragile);
351    
352    if (mathed_env == LM_EN_INTEXT){
353            if (fragile) os << "\\protect";
354            os << " \\)";
355    }
356    else if (mathed_env == LM_EN_DISPLAY) {
357            os << "\\]\n";
358      ++number_of_newlines;
359    }
360    else {
361            os << "\n\\end{"
362               << latex_mathenv[mathed_env]
363               << "}\n";
364      number_of_newlines += 2;
365    }
366    *newlines = number_of_newlines;
367 }