1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "grammar.hxx"
33 #define rstartEl(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->startElement(x,y); } while(false)
34 #define rendEl(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->endElement(x); } while(false)
35 #define rchars(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(false)
36 #define runistr(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(false)
37 #define reucstr(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(OUString(x,y, RTL_TEXTENCODING_EUC_KR)); } while(false)
38 #define padd(x,y,z) mxList->addAttribute(x,y,z)
40 static int indent
= 0;
41 #define inds indent++; for(int i = 0 ; i < indent ; i++) fprintf(stderr," ")
42 #define inde for(int i = 0 ; i < indent ; i++) fprintf(stderr," "); indent--
43 #define indo indent--;
46 void Formula::makeMathML(Node
*res
)
52 fprintf(stderr
,"<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">\n");
54 padd("xmlns:math", "CDATA", "http://www.w3.org/1998/Math/MathML");
55 rstartEl("math:math", mxList
.get());
57 rstartEl("math:semantics", mxList
.get());
60 makeLines( tmp
->child
);
64 fprintf(stderr
,"<math:semantics/>\n");
67 fprintf(stderr
,"</math:math>\n");
69 rendEl("math:semantics");
74 void Formula::makeLines(Node
*res
)
80 if( tmp
->child
->id
== ID_LINES
)
81 makeLines( tmp
->child
);
83 makeLine( tmp
->child
);
86 makeLine( tmp
->next
);
89 void Formula::makeLine(Node
*res
)
93 inds
; fprintf(stderr
,"<math:mrow>\n");
95 rstartEl("math:mrow", mxList
.get());
98 makeExprList( res
->child
);
100 inde
; fprintf(stderr
,"</math:mrow>\n");
106 void Formula::makeExprList(Node
*res
)
109 Node
*tmp
= res
->child
;
112 if( tmp
->id
== ID_EXPRLIST
){
113 Node
*next
= tmp
->next
;
114 makeExprList( tmp
) ;
122 void Formula::makeExpr(Node
*res
)
125 Node
*tmp
= res
->child
;
132 fprintf(stderr
,"<math:mrow>\n");
134 rstartEl("math:mrow", mxList
.get());
142 inde
; fprintf(stderr
,"</math:mrow>\n");
153 case ID_FRACTIONEXPR
:
157 case ID_DECORATIONEXPR
:
185 void Formula::makeIdentifier(Node
*res
)
189 if( !tmp
->value
) return;
194 fprintf(stderr
,"<math:mi>%s</math:mi>\n",tmp
->value
);
197 rstartEl("math:mi", mxList
.get());
198 rchars(OUString::createFromAscii(tmp
->value
));
206 rstartEl("math:mi", mxList
.get());
207 reucstr(tmp
->value
, strlen(tmp
->value
));
215 fprintf(stderr
,"<math:mi>%s</math:mi>\n",
216 getMathMLEntity(tmp
->value
).c_str());
219 rstartEl("math:mi", mxList
.get());
220 runistr(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->value
).c_str()));
227 fprintf(stderr
,"<math:mn>%s</math:mn>\n",tmp
->value
);
230 rstartEl("math:mn", mxList
.get());
231 rchars(OUString::createFromAscii(tmp
->value
));
239 inds
; fprintf(stderr
,"<math:mo>%s</math:mo>\n",tmp
->value
); indo
;
241 rstartEl("math:mo", mxList
.get());
242 runistr(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->value
).c_str()));
249 void Formula::makePrimary(Node
*res
)
254 if( tmp
->child
->id
== ID_PRIMARYEXPR
){
255 makePrimary(tmp
->child
);
258 makeIdentifier(tmp
->child
);
262 makeIdentifier(tmp
->next
);
266 void Formula::makeSubSup(Node
*res
)
273 if( res
->id
== ID_SUBEXPR
)
274 fprintf(stderr
,"<math:msub>\n");
275 else if( res
->id
== ID_SUPEXPR
)
276 fprintf(stderr
,"<math:msup>\n");
278 fprintf(stderr
,"<math:msubsup>\n");
280 if( res
->id
== ID_SUBEXPR
)
281 rstartEl("math:msub", mxList
.get());
282 else if( res
->id
== ID_SUPEXPR
)
283 rstartEl("math:msup", mxList
.get());
285 rstartEl("math:msubsup", mxList
.get());
289 if( res
->id
== ID_SUBSUPEXPR
) {
291 makeBlock(tmp
->next
);
292 makeBlock(tmp
->next
->next
);
301 if( res
->id
== ID_SUBEXPR
)
302 fprintf(stderr
,"</math:msub>\n");
303 else if( res
->id
== ID_SUPEXPR
)
304 fprintf(stderr
,"</math:msup>\n");
306 fprintf(stderr
,"</math:msubsup>\n");
308 if( res
->id
== ID_SUBEXPR
)
310 else if( res
->id
== ID_SUPEXPR
)
313 rendEl("math:msubsup");
317 void Formula::makeFraction(Node
*res
)
324 fprintf(stderr
,"<math:mfrac>\n");
326 rstartEl("math:mfrac", mxList
.get());
332 fprintf(stderr
,"<math:mrow>\n");
334 rstartEl("math:mrow", mxList
.get());
337 if( res
->id
== ID_FRACTIONEXPR
)
344 fprintf(stderr
,"</math:mrow>\n");
346 fprintf(stderr
,"<math:mrow>\n");
349 rstartEl("math:mrow", mxList
.get());
352 if( res
->id
== ID_FRACTIONEXPR
)
353 makeBlock(tmp
->next
);
355 makeExprList(tmp
->next
);
359 fprintf(stderr
,"</math:mrow>\n");
361 fprintf(stderr
,"</math:mfrac>\n");
364 rendEl("math:mfrac");
368 void Formula::makeDecoration(Node
*res
)
371 Node
*tmp
= res
->child
;
373 if( !strncmp(tmp
->value
,"under", 5) )
378 fprintf(stderr
,"<math:mover>\n");
380 fprintf(stderr
,"<math:munder>\n");
382 /* FIXME: no idea when 'accent' is true or false. */
384 padd("accent","CDATA","true");
385 rstartEl("math:mover", mxList
.get());
388 padd("accentunder","CDATA","true");
389 rstartEl("math:munder", mxList
.get());
394 makeBlock(tmp
->next
);
398 fprintf(stderr
,"<math:mo>%s</math:mo>\n",
399 getMathMLEntity(tmp
->value
).c_str());
402 rstartEl("math:mo", mxList
.get());
403 runistr(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->value
).c_str()));
410 fprintf(stderr
,"</math:mover>\n");
412 fprintf(stderr
,"</math:munder>\n");
415 rendEl("math:mover");
417 rendEl("math:munder");
421 void Formula::makeRoot(Node
*res
)
427 if( tmp
->id
== ID_SQRTEXPR
)
428 fprintf(stderr
,"<math:msqrt>\n");
430 fprintf(stderr
,"<math:mroot>\n");
432 if( tmp
->id
== ID_SQRTEXPR
)
433 rstartEl("math:msqrt", mxList
.get());
435 rstartEl("math:mroot", mxList
.get());
438 if( tmp
->id
== ID_SQRTEXPR
){
439 makeBlock(tmp
->child
);
442 makeBracket(tmp
->child
);
443 makeBlock(tmp
->child
->next
);
448 if( tmp
->id
== ID_SQRTEXPR
)
449 fprintf(stderr
,"</math:msqrt>\n");
451 fprintf(stderr
,"</math:mroot>\n");
453 if( tmp
->id
== ID_SQRTEXPR
)
454 rendEl("math:msqrt");
456 rendEl("math:mroot");
459 void Formula::makeAccent(Node
*res
)
461 makeDecoration( res
);
463 void Formula::makeParenth(Node
*res
)
469 fprintf(stderr
,"<math:mrow>\n");
471 if( tmp
->id
== ID_PARENTH
){
472 fprintf(stderr
,"<math:mo>(</math:mo>\n");
475 fprintf(stderr
,"<math:mo>|</math:mo>\n");
477 fprintf(stderr
,"<math:mrow>\n");
479 rstartEl("math:mrow", mxList
.get());
480 rstartEl("math:mo", mxList
.get());
481 if( tmp
->id
== ID_PARENTH
)
486 rstartEl("math:mrow", mxList
.get());
490 makeExprList(tmp
->child
);
494 fprintf(stderr
,"</math:mrow>\n");
496 if( tmp
->id
== ID_PARENTH
)
497 fprintf(stderr
,"<math:mo>)</math:mo>\n");
499 fprintf(stderr
,"<math:mo>|</math:mo>\n");
502 fprintf(stderr
,"</math:mrow>\n");
505 rstartEl("math:mo", mxList
.get());
506 if( tmp
->id
== ID_PARENTH
)
515 void Formula::makeFence(Node
*res
)
517 Node
*tmp
= res
->child
;
520 fprintf(stderr
,"<math:mfenced open=\"%s\" close=\"%s\">\n",
521 getMathMLEntity(tmp
->value
).c_str(),
522 getMathMLEntity(tmp
->next
->next
->value
).c_str());
524 padd("open", "CDATA",
525 OUString(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->value
).c_str())));
526 padd("close", "CDATA",
527 OUString(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->next
->next
->value
).c_str())));
528 rstartEl("math:mfenced", mxList
.get());
532 makeExprList(tmp
->next
);
536 fprintf(stderr
,"</math:mfenced>\n");
538 rendEl("math:mfenced");
542 void Formula::makeBracket(Node
*res
)
547 void Formula::makeBlock(Node
*res
)
551 fprintf(stderr
,"<math:mrow>\n");
553 rstartEl("math:mrow", mxList
.get());
557 makeExprList(res
->child
);
561 fprintf(stderr
,"</math:mrow>\n");
567 void Formula::parse()
573 // fprintf(stderr,"\n\n[BEFORE]\n[%s]\n",eq);
576 int idx
=a
.find(sal::static_int_cast
<char>(0xff));
578 //printf("idx = [%d]\n",idx);
580 if((idx
= a
.find(sal::static_int_cast
<char>(0xff),idx
+1)) < 0)
584 char *buf
= static_cast<char *>(malloc(a
.length()+1));
587 for( i
= 0, j
=0 ; i
< a
.length() ; i
++){ // rtrim and ltrim 32 10 13
592 if( a
[i
] != 32 && a
[i
] != 10 && a
[i
] != 13){
599 for( i
= j
-1 ; i
>= 0 ; i
++ ){
600 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
606 // fprintf(stderr,"\n\n[RESULT]\n[%s]\n",a.c_str());
608 res
= mainParse( a
.c_str() );
621 int len
= strlen(eq
);
622 char *buf
= static_cast<char *>(malloc(len
+1));
625 for( i
= 0, j
=0 ; i
< len
; i
++){ // rtrim and ltrim 32 10 13
630 if( eq
[i
] != 32 && eq
[i
] != 10 && eq
[i
] != 13){
637 for( i
= j
-1 ; i
>= 0 ; i
++ ){
638 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
651 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */