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);
103 (strcmp(l->name, "overbrace") == 0 ||
104 strcmp(l->name, "underbrace") == 0 ||
105 strcmp(l->name, "overleftarrow") == 0 ||
106 strcmp(l->name, "overrightarrow") == 0))
108 os << '\\' << l->name << '{';
109 MathParInset::Write(os, fragile);
114 void MathAccentInset::Write(ostream & os, bool fragile)
116 latexkeys * l = lm_get_key_by_id(code, LM_TK_ACCENT);
117 os << '\\' << l->name;
124 inset->Write(os, fragile);
126 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM) {
128 << math_font_name[fn-LM_TC_RM]
131 if (MathIsSymbol(fn)) {
132 latexkeys * l = lm_get_key_by_id(c, LM_TK_SYM);
134 os << '\\' << l->name << ' ';
139 if (fn>= LM_TC_RM && fn<= LM_TC_TEXTRM)
148 void MathBigopInset::Write(ostream & os, bool /* fragile */)
150 bool limp = GetLimits();
154 if (limp && !(sym != LM_int && sym != LM_oint
155 && (GetStyle() == LM_ST_DISPLAY)))
158 if (!limp && (sym != LM_int && sym != LM_oint
159 && (GetStyle() == LM_ST_DISPLAY)))
166 void MathFracInset::Write(ostream & os, bool fragile)
168 os << '\\' << name << '{';
169 MathParInset::Write(os, fragile);
171 den->Write(os, fragile);
176 void MathParInset::Write(ostream & os, bool fragile)
181 MathedIter data(array);
183 MathedRowSt const * crow = getRowSt();
186 if (!Permit(LMPF_FIXED_SIZE)) {
187 l = lm_get_key_by_id(size, LM_TK_STY);
189 os << '\\' << l->name << ' ';
193 byte cx = data.GetChar();
196 byte * s = data.GetString(ls);
198 if (data.FCode() >= LM_TC_RM && data.FCode() <= LM_TC_TEXTRM) {
199 os << '\\' << math_font_name[data.FCode()-LM_TC_RM] << '{';
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);
206 os << '\\' << l->name << ' ';
208 lyxerr << "Illegal symbol code[" << *s
209 << " " << ls << " " << data.FCode() << "]";
212 // Is there a standard logical XOR?
213 if ((data.FCode() == LM_TC_TEX && *s != '{' && *s != '}') ||
214 (data.FCode() == LM_TC_SPECIAL))
217 if (*s == '{') ++brace;
218 if (*s == '}') --brace;
220 if (*s == '}' && data.FCode() == LM_TC_TEX && brace < 0)
221 lyxerr <<"Math warning: Unexpected closing brace."
228 if (data.FCode()>= LM_TC_RM && data.FCode()<= LM_TC_TEXTRM)
231 if (MathIsInset(cx)) {
232 MathedInset * p = data.GetInset();
235 if (cx == LM_TC_DOWN)
237 p->Write(os, fragile);
238 if (cx == LM_TC_UP || cx == LM_TC_DOWN)
252 if (!crow->isNumbered()) {
255 if (crow->getLabel()) {
260 crow = crow->getNext();
265 ++number_of_newlines;
270 lyxerr << "WMath Error: unrecognized code[" << cx << "]";
276 if (!crow->isNumbered()) {
279 if (crow->getLabel()) {
287 os << string(brace, '}');
291 void MathMatrixInset::Write(ostream & os, bool fragile)
293 if (GetType() == LM_OT_MATRIX){
299 if (v_align == 't' || v_align == 'b') {
307 ++number_of_newlines;
309 MathParInset::Write(os, fragile);
310 if (GetType() == LM_OT_MATRIX){
317 ++number_of_newlines;
322 void mathed_write(MathParInset * p, ostream & os, int * newlines,
323 bool fragile, char const * label)
325 number_of_newlines = 0;
326 short mathed_env = p->GetType();
328 if (mathed_env == LM_EN_INTEXT) {
329 if (fragile) os << "\\protect";
330 os << "\\( "; // changed from " \\( " (Albrecht Dress)
333 if (mathed_env == LM_EN_DISPLAY){
337 << latex_mathenv[mathed_env]
340 ++number_of_newlines;
343 if (label && label[0] > ' ' && mathed_env == LM_EN_EQUATION){
347 ++number_of_newlines;
350 p->Write(os, fragile);
352 if (mathed_env == LM_EN_INTEXT){
353 if (fragile) os << "\\protect";
356 else if (mathed_env == LM_EN_DISPLAY) {
358 ++number_of_newlines;
362 << latex_mathenv[mathed_env]
364 number_of_newlines += 2;
366 *newlines = number_of_newlines;