merge the formfield patch from ooo-build
[ooovba.git] / hwpfilter / source / formula.cpp
blob0b4ab0c4d358b53041cae1430d37678070db1d07
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formula.cpp,v $
10 * $Revision: 1.6 $
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 ************************************************************************/
31 #include "formula.h"
33 #include "mzstring.h"
34 #include "nodes.h"
35 #include "mapping.h"
36 #include "hwpeq.h"
37 #include <iostream>
39 extern LinkedList<Node> nodelist;
41 #ifndef DEBUG
43 #include "hcode.h"
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)
53 #else
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--;
59 #endif
61 extern Node *mainParse(const char *);
64 void Formula::makeMathML(Node *res)
66 Node *tmp = res;
67 if( !tmp ) return;
68 #ifdef DEBUG
69 inds;
70 fprintf(stderr,"<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">\n");
71 #else
72 padd(ascii("xmlns:math"), ascii("CDATA"), ascii("http://www.w3.org/1998/Math/MathML"));
73 rstartEl(ascii("math:math"), rList);
74 pList->clear();
75 rstartEl(ascii("math:semantics"), rList);
76 #endif
77 if( tmp->child )
78 makeLines( tmp->child );
80 #ifdef DEBUG
81 inds;
82 fprintf(stderr,"<math:semantics/>\n");
83 indo;
84 inde;
85 fprintf(stderr,"</math:math>\n");
86 #else
87 rendEl(ascii("math:semantics"));
88 rendEl(ascii("math:math"));
89 #endif
92 void Formula::makeLines(Node *res)
94 Node *tmp = res;
95 if( !tmp ) return;
97 if( tmp->child ){
98 if( tmp->child->id == ID_LINES )
99 makeLines( tmp->child );
100 else
101 makeLine( tmp->child );
103 if( tmp->next )
104 makeLine( tmp->next );
107 void Formula::makeLine(Node *res)
109 if( !res ) return;
110 #ifdef DEBUG
111 inds; fprintf(stderr,"<math:mrow>\n");
112 #else
113 rstartEl(ascii("math:mrow"), rList);
114 #endif
115 if( res->child )
116 makeExprList( res->child );
117 #ifdef DEBUG
118 inde; fprintf(stderr,"</math:mrow>\n");
119 #else
120 rendEl(ascii("math:mrow"));
121 #endif
124 void Formula::makeExprList(Node *res)
126 if( !res ) return;
127 Node *tmp = res->child;
128 if( !tmp ) return ;
130 if( tmp->id == ID_EXPRLIST ){
131 Node *next = tmp->next;
132 makeExprList( tmp ) ;
133 if( next )
134 makeExpr( next );
136 else
137 makeExpr( tmp );
140 void Formula::makeExpr(Node *res)
142 if( !res ) return;
143 Node *tmp = res->child;
144 if( !tmp ) return;
145 switch( tmp->id ) {
146 case ID_PRIMARYEXPR:
147 if( tmp->next ){
148 #ifdef DEBUG
149 inds;
150 fprintf(stderr,"<math:mrow>\n");
151 #else
152 rstartEl(ascii("math:mrow"), rList);
153 #endif
156 makePrimary(tmp);
158 if( tmp->next ){
159 #ifdef DEBUG
160 inde; fprintf(stderr,"</math:mrow>\n");
161 #else
162 rendEl(ascii("math:mrow"));
163 #endif
165 break;
166 case ID_SUBEXPR:
167 case ID_SUPEXPR:
168 case ID_SUBSUPEXPR:
169 makeSubSup(tmp);
170 break;
171 case ID_FRACTIONEXPR:
172 case ID_OVER:
173 makeFraction(tmp);
174 break;
175 case ID_DECORATIONEXPR:
176 makeDecoration(tmp);
177 break;
178 case ID_SQRTEXPR:
179 case ID_ROOTEXPR:
180 makeRoot(tmp);
181 break;
182 case ID_ARROWEXPR:
183 makeArrow(tmp);
184 break;
185 case ID_ACCENTEXPR:
186 makeAccent(tmp);
187 break;
188 case ID_PARENTH:
189 case ID_ABS:
190 makeParenth(tmp);
191 break;
192 case ID_FENCE:
193 makeFence(tmp);
194 break;
195 case ID_BLOCK:
196 makeBlock(tmp);
197 case ID_BEGIN:
198 makeBegin(tmp);
199 case ID_END:
200 makeEnd(tmp);
201 break;
205 void Formula::makeIdentifier(Node *res)
207 Node *tmp = res;
208 if( !tmp ) return;
209 if( !tmp->value ) return;
210 switch( tmp->id ){
211 case ID_CHARACTER :
212 #ifdef DEBUG
213 inds;
214 fprintf(stderr,"<math:mi>%s</math:mi>\n",tmp->value);
215 indo;
216 #else
217 rstartEl(ascii("math:mi"), rList);
218 rchars(tmp->value);
219 rendEl(ascii("math:mi"));
220 #endif
221 break;
222 case ID_STRING :
224 #ifdef DEBUG
225 #else
226 rstartEl(ascii("math:mi"), rList);
227 reucstr(tmp->value, strlen(tmp->value));
228 rendEl(ascii("math:mi"));
229 #endif
231 break;
232 case ID_IDENTIFIER :
233 #ifdef DEBUG
234 inds;
235 fprintf(stderr,"<math:mi>%s</math:mi>\n",getMathMLEntity(tmp->value, entity));
236 indo;
237 #else
238 rstartEl(ascii("math:mi"), rList);
239 runistr(getMathMLEntity(tmp->value, entity));
240 rendEl(ascii("math:mi"));
241 #endif
242 break;
243 case ID_NUMBER :
244 #ifdef DEBUG
245 inds;
246 fprintf(stderr,"<math:mn>%s</math:mn>\n",tmp->value);
247 indo;
248 #else
249 rstartEl(ascii("math:mn"), rList);
250 rchars(tmp->value);
251 rendEl(ascii("math:mn"));
252 #endif
253 break;
254 case ID_OPERATOR :
255 case ID_DELIMETER :
257 #ifdef DEBUG
258 inds; fprintf(stderr,"<math:mo>%s</math:mo>\n",tmp->value); indo;
259 #else
260 rstartEl(ascii("math:mo"), rList);
261 runistr(getMathMLEntity(tmp->value,entity));
262 rendEl(ascii("math:mo"));
263 #endif
264 break;
268 void Formula::makePrimary(Node *res)
270 Node *tmp = res;
271 if( !tmp ) return ;
272 if( tmp->child ){
273 if( tmp->child->id == ID_PRIMARYEXPR ){
274 makePrimary(tmp->child);
276 else{
277 makeIdentifier(tmp->child);
280 if( tmp->next ){
281 makeIdentifier(tmp->next);
285 void Formula::makeSubSup(Node *res)
287 Node *tmp = res;
288 if( !tmp ) return;
290 #ifdef DEBUG
291 inds;
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");
296 else
297 fprintf(stderr,"<math:msubsup>\n");
298 #else
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);
303 else
304 rstartEl(ascii("math:msubsup"), rList);
305 #endif
307 tmp = tmp->child;
308 if( res->id == ID_SUBSUPEXPR ) {
309 makeExpr(tmp);
310 makeBlock(tmp->next);
311 makeBlock(tmp->next->next);
313 else{
314 makeExpr(tmp);
315 makeExpr(tmp->next);
318 #ifdef DEBUG
319 inde;
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");
324 else
325 fprintf(stderr,"</math:msubsup>\n");
326 #else
327 if( res->id == ID_SUBEXPR )
328 rendEl(ascii("math:msub"));
329 else if( res->id == ID_SUPEXPR )
330 rendEl(ascii("math:msup"));
331 else
332 rendEl(ascii("math:msubsup"));
333 #endif
336 void Formula::makeFraction(Node *res)
338 Node *tmp = res;
339 if( !tmp ) return;
341 #ifdef DEBUG
342 inds;
343 fprintf(stderr,"<math:mfrac>\n");
344 #else
345 rstartEl(ascii("math:mfrac"), rList);
346 #endif
348 tmp = tmp->child;
349 #ifdef DEBUG
350 inds;
351 fprintf(stderr,"<math:mrow>\n");
352 #else
353 rstartEl(ascii("math:mrow"), rList);
354 #endif
356 if( res->id == ID_FRACTIONEXPR )
357 makeBlock(tmp);
358 else
359 makeExprList(tmp);
361 #ifdef DEBUG
362 inde;
363 fprintf(stderr,"</math:mrow>\n");
364 inds;
365 fprintf(stderr,"<math:mrow>\n");
366 #else
367 rendEl(ascii("math:mrow"));
368 rstartEl(ascii("math:mrow"), rList);
369 #endif
371 if( res->id == ID_FRACTIONEXPR )
372 makeBlock(tmp->next);
373 else
374 makeExprList(tmp->next);
376 #ifdef DEBUG
377 inde;
378 fprintf(stderr,"</math:mrow>\n");
379 inde;
380 fprintf(stderr,"</math:mfrac>\n");
381 #else
382 rendEl(ascii("math:mrow"));
383 rendEl(ascii("math:mfrac"));
384 #endif
387 void Formula::makeDecoration(Node *res)
389 int isover = 1;
390 Node *tmp = res->child;
391 if( !tmp ) return;
392 if( !strncmp(tmp->value,"under", 5) )
393 isover = 0;
394 #ifdef DEBUG
395 inds;
396 if( isover )
397 fprintf(stderr,"<math:mover>\n");
398 else
399 fprintf(stderr,"<math:munder>\n");
400 #else
401 /* accent´Â ¾ðÁ¦ trueÀÌ°í, ¾ðÁ¦, falseÀÎÁö ¸ð¸£°Ú´Ù. */
402 if( isover ){
403 padd(ascii("accent"),ascii("CDATA"),ascii("true"));
404 rstartEl(ascii("math:mover"), rList);
406 else{
407 padd(ascii("accentunder"),ascii("CDATA"),ascii("true"));
408 rstartEl(ascii("math:munder"), rList);
410 pList->clear();
411 #endif
413 makeBlock(tmp->next);
415 #ifdef DEBUG
416 inds;
417 fprintf(stderr,"<math:mo>%s</math:mo>\n", getMathMLEntity(tmp->value,entity));
418 indo;
419 #else
420 rstartEl(ascii("math:mo"), rList);
421 runistr(getMathMLEntity(tmp->value,entity));
422 rendEl(ascii("math:mo"));
423 #endif
425 #ifdef DEBUG
426 inde;
427 if( isover )
428 fprintf(stderr,"</math:mover>\n");
429 else
430 fprintf(stderr,"</math:munder>\n");
431 #else
432 if( isover )
433 rendEl(ascii("math:mover"));
434 else
435 rendEl(ascii("math:munder"));
436 #endif
439 void Formula::makeRoot(Node *res)
441 Node *tmp = res;
442 if( !tmp ) return;
443 #ifdef DEBUG
444 inds;
445 if( tmp->id == ID_SQRTEXPR )
446 fprintf(stderr,"<math:msqrt>\n");
447 else
448 fprintf(stderr,"<math:mroot>\n");
449 #else
450 if( tmp->id == ID_SQRTEXPR )
451 rstartEl(ascii("math:msqrt"), rList);
452 else
453 rstartEl(ascii("math:mroot"), rList);
454 #endif
456 if( tmp->id == ID_SQRTEXPR ){
457 makeBlock(tmp->child);
459 else{
460 makeBracket(tmp->child);
461 makeBlock(tmp->child->next);
464 #ifdef DEBUG
465 inde;
466 if( tmp->id == ID_SQRTEXPR )
467 fprintf(stderr,"</math:msqrt>\n");
468 else
469 fprintf(stderr,"</math:mroot>\n");
470 #else
471 if( tmp->id == ID_SQRTEXPR )
472 rendEl(ascii("math:msqrt"));
473 else
474 rendEl(ascii("math:mroot"));
475 #endif
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)
487 Node *tmp = res;
488 if( !tmp ) return;
489 #ifdef DEBUG
490 inds;
491 fprintf(stderr,"<math:mrow>\n");
492 inds;
493 if( tmp->id == ID_PARENTH ){
494 fprintf(stderr,"<math:mo>(</math:mo>\n");
496 else
497 fprintf(stderr,"<math:mo>|</math:mo>\n");
498 indo; inds;
499 fprintf(stderr,"<math:mrow>\n");
500 #else
501 rstartEl(ascii("math:mrow"), rList);
502 rstartEl(ascii("math:mo"), rList);
503 if( tmp->id == ID_PARENTH )
504 rchars("(");
505 else
506 rchars("|");
507 rendEl(ascii("math:mo"));
508 rstartEl(ascii("math:mrow"), rList);
509 #endif
511 if( tmp->child )
512 makeExprList(tmp->child);
514 #ifdef DEBUG
515 inde;
516 fprintf(stderr,"</math:mrow>\n");
517 inds;
518 if( tmp->id == ID_PARENTH )
519 fprintf(stderr,"<math:mo>)</math:mo>\n");
520 else
521 fprintf(stderr,"<math:mo>|</math:mo>\n");
522 indo;
523 inde;
524 fprintf(stderr,"</math:mrow>\n");
525 #else
526 rendEl(ascii("math:mrow"));
527 rstartEl(ascii("math:mo"), rList);
528 if( tmp->id == ID_PARENTH )
529 rchars(")");
530 else
531 rchars("|");
532 rendEl(ascii("math:mo"));
533 rendEl(ascii("math:mrow"));
534 #endif
537 void Formula::makeFence(Node *res)
539 Node *tmp = res->child;
540 #ifdef DEBUG
541 inds;
542 fprintf(stderr,"<math:mfenced open=\"%s\" close=\"%s\">\n",getMathMLEntity(tmp->value, entity),
543 getMathMLEntity(tmp->next->next->value,entity));
544 #else
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);
548 pList->clear();
549 #endif
551 makeExprList(tmp->next);
553 #ifdef DEBUG
554 inde;
555 fprintf(stderr,"</math:mfenced>\n");
556 #else
557 rendEl(ascii("math:mfenced"));
558 #endif
561 void Formula::makeBracket(Node *res)
563 makeBlock(res);
566 void Formula::makeBlock(Node *res)
568 #ifdef DEBUG
569 inds;
570 fprintf(stderr,"<math:mrow>\n");
571 #else
572 rstartEl(ascii("math:mrow"), rList);
573 #endif
575 if( res->child )
576 makeExprList(res->child);
578 #ifdef DEBUG
579 inde;
580 fprintf(stderr,"</math:mrow>\n");
581 #else
582 rendEl(ascii("math:mrow"));
583 #endif
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*/)
596 int Formula::parse()
598 Node *res = 0L;
599 if( !eq ) return 0;
600 if( isHwpEQ ){
601 MzString a;
602 // fprintf(stderr,"\n\n[BEFORE]\n[%s]\n",eq);
603 eq2latex(a,eq);
605 int idx=a.find(sal::static_int_cast<char>(0xff));
606 while(idx){
607 //printf("idx = [%d]\n",idx);
608 a.replace(idx,0x20);
609 if((idx = a.find(sal::static_int_cast<char>(0xff),idx+1)) < 0)
610 break;
613 char *buf = (char *)malloc(a.length()+1);
614 bool bStart = false;
615 int i, j;
616 for( i = 0, j=0 ; i < a.length() ; i++){ // rtrim and ltrim 32 10 13
617 if( bStart ){
618 buf[j++] = a[i];
620 else{
621 if( a[i] != 32 && a[i] != 10 && a[i] != 13){
622 bStart = true;
623 buf[j++] = a[i];
627 buf[j] = 0;
628 for( i = j-1 ; i >= 0 ; i++ ){
629 if( buf[i] == 32 || buf[i] == 10 || buf[i] == 13 ){
630 buf[i] = 0;
632 else
633 break;
635 // fprintf(stderr,"\n\n[RESULT]\n[%s]\n",a.c_str());
636 if( strlen(buf) > 0 )
637 res = mainParse( a.c_str() );
638 else
639 res = 0L;
640 free(buf);
642 else{
643 res = mainParse( eq );
646 if( res ){
647 makeMathML( res );
649 Node *tmpNode;
650 int count = nodelist.count();
651 for( int i = 0 ; i < count ; i++ ){
652 tmpNode = nodelist.remove(0);
653 delete tmpNode;
656 return 0;
659 void Formula::trim()
661 int len = strlen(eq);
662 char *buf = (char *)malloc(len+1);
663 bool bStart = false;
664 int i, j;
665 for( i = 0, j=0 ; i < len ; i++){ // rtrim and ltrim 32 10 13
666 if( bStart ){
667 buf[j++] = eq[i];
669 else{
670 if( eq[i] != 32 && eq[i] != 10 && eq[i] != 13){
671 bStart = true;
672 buf[j++] = eq[i];
676 buf[j] = 0;
677 for( i = j-1 ; i >= 0 ; i++ ){
678 if( buf[i] == 32 || buf[i] == 10 || buf[i] == 13 ){
679 buf[i] = 0;
681 else
682 break;
684 if( strlen(buf) > 0 )
685 strcpy(eq, buf);
686 else
687 eq = 0L;
688 free(buf);