1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formula.cpp,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
39 extern LinkedList
<Node
> nodelist
;
45 static hchar entity
[32];
46 #define ascii(x) OUString::createFromAscii(x)
47 #define rstartEl(x,y) rDocumentHandler->startElement(x,y)
48 #define rendEl(x) rDocumentHandler->endElement(x)
49 #define rchars(x) rDocumentHandler->characters(ascii(x))
50 #define runistr(x) rDocumentHandler->characters(OUString(x))
51 #define reucstr(x,y) rDocumentHandler->characters(OUString(x,y, RTL_TEXTENCODING_EUC_KR))
52 #define padd(x,y,z) pList->addAttribute(x,y,z)
54 static char entity
[32];
55 static int indent
= 0;
56 #define inds indent++; for(int i = 0 ; i < indent ; i++) fprintf(stderr," ")
57 #define inde for(int i = 0 ; i < indent ; i++) fprintf(stderr," "); indent--
58 #define indo indent--;
61 extern Node
*mainParse(const char *);
64 void Formula::makeMathML(Node
*res
)
70 fprintf(stderr
,"<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">\n");
72 padd(ascii("xmlns:math"), ascii("CDATA"), ascii("http://www.w3.org/1998/Math/MathML"));
73 rstartEl(ascii("math:math"), rList
);
75 rstartEl(ascii("math:semantics"), rList
);
78 makeLines( tmp
->child
);
82 fprintf(stderr
,"<math:semantics/>\n");
85 fprintf(stderr
,"</math:math>\n");
87 rendEl(ascii("math:semantics"));
88 rendEl(ascii("math:math"));
92 void Formula::makeLines(Node
*res
)
98 if( tmp
->child
->id
== ID_LINES
)
99 makeLines( tmp
->child
);
101 makeLine( tmp
->child
);
104 makeLine( tmp
->next
);
107 void Formula::makeLine(Node
*res
)
111 inds
; fprintf(stderr
,"<math:mrow>\n");
113 rstartEl(ascii("math:mrow"), rList
);
116 makeExprList( res
->child
);
118 inde
; fprintf(stderr
,"</math:mrow>\n");
120 rendEl(ascii("math:mrow"));
124 void Formula::makeExprList(Node
*res
)
127 Node
*tmp
= res
->child
;
130 if( tmp
->id
== ID_EXPRLIST
){
131 Node
*next
= tmp
->next
;
132 makeExprList( tmp
) ;
140 void Formula::makeExpr(Node
*res
)
143 Node
*tmp
= res
->child
;
150 fprintf(stderr
,"<math:mrow>\n");
152 rstartEl(ascii("math:mrow"), rList
);
160 inde
; fprintf(stderr
,"</math:mrow>\n");
162 rendEl(ascii("math:mrow"));
171 case ID_FRACTIONEXPR
:
175 case ID_DECORATIONEXPR
:
205 void Formula::makeIdentifier(Node
*res
)
209 if( !tmp
->value
) return;
214 fprintf(stderr
,"<math:mi>%s</math:mi>\n",tmp
->value
);
217 rstartEl(ascii("math:mi"), rList
);
219 rendEl(ascii("math:mi"));
226 rstartEl(ascii("math:mi"), rList
);
227 reucstr(tmp
->value
, strlen(tmp
->value
));
228 rendEl(ascii("math:mi"));
235 fprintf(stderr
,"<math:mi>%s</math:mi>\n",getMathMLEntity(tmp
->value
, entity
));
238 rstartEl(ascii("math:mi"), rList
);
239 runistr(getMathMLEntity(tmp
->value
, entity
));
240 rendEl(ascii("math:mi"));
246 fprintf(stderr
,"<math:mn>%s</math:mn>\n",tmp
->value
);
249 rstartEl(ascii("math:mn"), rList
);
251 rendEl(ascii("math:mn"));
258 inds
; fprintf(stderr
,"<math:mo>%s</math:mo>\n",tmp
->value
); indo
;
260 rstartEl(ascii("math:mo"), rList
);
261 runistr(getMathMLEntity(tmp
->value
,entity
));
262 rendEl(ascii("math:mo"));
268 void Formula::makePrimary(Node
*res
)
273 if( tmp
->child
->id
== ID_PRIMARYEXPR
){
274 makePrimary(tmp
->child
);
277 makeIdentifier(tmp
->child
);
281 makeIdentifier(tmp
->next
);
285 void Formula::makeSubSup(Node
*res
)
292 if( res
->id
== ID_SUBEXPR
)
293 fprintf(stderr
,"<math:msub>\n");
294 else if( res
->id
== ID_SUPEXPR
)
295 fprintf(stderr
,"<math:msup>\n");
297 fprintf(stderr
,"<math:msubsup>\n");
299 if( res
->id
== ID_SUBEXPR
)
300 rstartEl(ascii("math:msub"), rList
);
301 else if( res
->id
== ID_SUPEXPR
)
302 rstartEl(ascii("math:msup"), rList
);
304 rstartEl(ascii("math:msubsup"), rList
);
308 if( res
->id
== ID_SUBSUPEXPR
) {
310 makeBlock(tmp
->next
);
311 makeBlock(tmp
->next
->next
);
320 if( res
->id
== ID_SUBEXPR
)
321 fprintf(stderr
,"</math:msub>\n");
322 else if( res
->id
== ID_SUPEXPR
)
323 fprintf(stderr
,"</math:msup>\n");
325 fprintf(stderr
,"</math:msubsup>\n");
327 if( res
->id
== ID_SUBEXPR
)
328 rendEl(ascii("math:msub"));
329 else if( res
->id
== ID_SUPEXPR
)
330 rendEl(ascii("math:msup"));
332 rendEl(ascii("math:msubsup"));
336 void Formula::makeFraction(Node
*res
)
343 fprintf(stderr
,"<math:mfrac>\n");
345 rstartEl(ascii("math:mfrac"), rList
);
351 fprintf(stderr
,"<math:mrow>\n");
353 rstartEl(ascii("math:mrow"), rList
);
356 if( res
->id
== ID_FRACTIONEXPR
)
363 fprintf(stderr
,"</math:mrow>\n");
365 fprintf(stderr
,"<math:mrow>\n");
367 rendEl(ascii("math:mrow"));
368 rstartEl(ascii("math:mrow"), rList
);
371 if( res
->id
== ID_FRACTIONEXPR
)
372 makeBlock(tmp
->next
);
374 makeExprList(tmp
->next
);
378 fprintf(stderr
,"</math:mrow>\n");
380 fprintf(stderr
,"</math:mfrac>\n");
382 rendEl(ascii("math:mrow"));
383 rendEl(ascii("math:mfrac"));
387 void Formula::makeDecoration(Node
*res
)
390 Node
*tmp
= res
->child
;
392 if( !strncmp(tmp
->value
,"under", 5) )
397 fprintf(stderr
,"<math:mover>\n");
399 fprintf(stderr
,"<math:munder>\n");
401 /* accent´Â ¾ðÁ¦ trueÀÌ°í, ¾ðÁ¦, falseÀÎÁö ¸ð¸£°Ú´Ù. */
403 padd(ascii("accent"),ascii("CDATA"),ascii("true"));
404 rstartEl(ascii("math:mover"), rList
);
407 padd(ascii("accentunder"),ascii("CDATA"),ascii("true"));
408 rstartEl(ascii("math:munder"), rList
);
413 makeBlock(tmp
->next
);
417 fprintf(stderr
,"<math:mo>%s</math:mo>\n", getMathMLEntity(tmp
->value
,entity
));
420 rstartEl(ascii("math:mo"), rList
);
421 runistr(getMathMLEntity(tmp
->value
,entity
));
422 rendEl(ascii("math:mo"));
428 fprintf(stderr
,"</math:mover>\n");
430 fprintf(stderr
,"</math:munder>\n");
433 rendEl(ascii("math:mover"));
435 rendEl(ascii("math:munder"));
439 void Formula::makeRoot(Node
*res
)
445 if( tmp
->id
== ID_SQRTEXPR
)
446 fprintf(stderr
,"<math:msqrt>\n");
448 fprintf(stderr
,"<math:mroot>\n");
450 if( tmp
->id
== ID_SQRTEXPR
)
451 rstartEl(ascii("math:msqrt"), rList
);
453 rstartEl(ascii("math:mroot"), rList
);
456 if( tmp
->id
== ID_SQRTEXPR
){
457 makeBlock(tmp
->child
);
460 makeBracket(tmp
->child
);
461 makeBlock(tmp
->child
->next
);
466 if( tmp
->id
== ID_SQRTEXPR
)
467 fprintf(stderr
,"</math:msqrt>\n");
469 fprintf(stderr
,"</math:mroot>\n");
471 if( tmp
->id
== ID_SQRTEXPR
)
472 rendEl(ascii("math:msqrt"));
474 rendEl(ascii("math:mroot"));
477 // DVO: add space to avoid warning
478 void Formula::makeArrow(Node
* /*res*/)
481 void Formula::makeAccent(Node
*res
)
483 makeDecoration( res
);
485 void Formula::makeParenth(Node
*res
)
491 fprintf(stderr
,"<math:mrow>\n");
493 if( tmp
->id
== ID_PARENTH
){
494 fprintf(stderr
,"<math:mo>(</math:mo>\n");
497 fprintf(stderr
,"<math:mo>|</math:mo>\n");
499 fprintf(stderr
,"<math:mrow>\n");
501 rstartEl(ascii("math:mrow"), rList
);
502 rstartEl(ascii("math:mo"), rList
);
503 if( tmp
->id
== ID_PARENTH
)
507 rendEl(ascii("math:mo"));
508 rstartEl(ascii("math:mrow"), rList
);
512 makeExprList(tmp
->child
);
516 fprintf(stderr
,"</math:mrow>\n");
518 if( tmp
->id
== ID_PARENTH
)
519 fprintf(stderr
,"<math:mo>)</math:mo>\n");
521 fprintf(stderr
,"<math:mo>|</math:mo>\n");
524 fprintf(stderr
,"</math:mrow>\n");
526 rendEl(ascii("math:mrow"));
527 rstartEl(ascii("math:mo"), rList
);
528 if( tmp
->id
== ID_PARENTH
)
532 rendEl(ascii("math:mo"));
533 rendEl(ascii("math:mrow"));
537 void Formula::makeFence(Node
*res
)
539 Node
*tmp
= res
->child
;
542 fprintf(stderr
,"<math:mfenced open=\"%s\" close=\"%s\">\n",getMathMLEntity(tmp
->value
, entity
),
543 getMathMLEntity(tmp
->next
->next
->value
,entity
));
545 padd(ascii("open"), ascii("CDATA"), OUString(getMathMLEntity(tmp
->value
,entity
)) );
546 padd(ascii("close"), ascii("CDATA"), OUString(getMathMLEntity(tmp
->next
->next
->value
,entity
)) );
547 rstartEl(ascii("math:mfenced"), rList
);
551 makeExprList(tmp
->next
);
555 fprintf(stderr
,"</math:mfenced>\n");
557 rendEl(ascii("math:mfenced"));
561 void Formula::makeBracket(Node
*res
)
566 void Formula::makeBlock(Node
*res
)
570 fprintf(stderr
,"<math:mrow>\n");
572 rstartEl(ascii("math:mrow"), rList
);
576 makeExprList(res
->child
);
580 fprintf(stderr
,"</math:mrow>\n");
582 rendEl(ascii("math:mrow"));
586 // DVO: add space to avoid warning
587 void Formula::makeBegin(Node
* /*res*/)
591 // DVO: add space to avoid warning
592 void Formula::makeEnd(Node
* /*res*/)
602 // fprintf(stderr,"\n\n[BEFORE]\n[%s]\n",eq);
605 int idx
=a
.find(sal::static_int_cast
<char>(0xff));
607 //printf("idx = [%d]\n",idx);
609 if((idx
= a
.find(sal::static_int_cast
<char>(0xff),idx
+1)) < 0)
613 char *buf
= (char *)malloc(a
.length()+1);
616 for( i
= 0, j
=0 ; i
< a
.length() ; i
++){ // rtrim and ltrim 32 10 13
621 if( a
[i
] != 32 && a
[i
] != 10 && a
[i
] != 13){
628 for( i
= j
-1 ; i
>= 0 ; i
++ ){
629 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
635 // fprintf(stderr,"\n\n[RESULT]\n[%s]\n",a.c_str());
636 if( strlen(buf
) > 0 )
637 res
= mainParse( a
.c_str() );
643 res
= mainParse( eq
);
650 int count
= nodelist
.count();
651 for( int i
= 0 ; i
< count
; i
++ ){
652 tmpNode
= nodelist
.remove(0);
661 int len
= strlen(eq
);
662 char *buf
= (char *)malloc(len
+1);
665 for( i
= 0, j
=0 ; i
< len
; i
++){ // rtrim and ltrim 32 10 13
670 if( eq
[i
] != 32 && eq
[i
] != 10 && eq
[i
] != 13){
677 for( i
= j
-1 ; i
>= 0 ; i
++ ){
678 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
684 if( strlen(buf
) > 0 )