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"
32 #define rstartEl(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->startElement(x,y); } while(false)
33 #define rendEl(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->endElement(x); } while(false)
34 #define rchars(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(false)
35 #define runistr(x) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(x); } while(false)
36 #define reucstr(x,y) do { if (m_rxDocumentHandler.is()) m_rxDocumentHandler->characters(OUString(x,y, RTL_TEXTENCODING_EUC_KR)); } while(false)
37 #define padd(x,y,z) mxList->addAttribute(x,y,z)
39 static int indent
= 0;
40 #define inds indent++; for(int i = 0 ; i < indent ; i++) fprintf(stderr," ")
41 #define inde for(int i = 0 ; i < indent ; i++) fprintf(stderr," "); indent--
42 #define indo indent--;
45 void Formula::makeMathML(Node
*res
)
51 fprintf(stderr
,"<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">\n");
53 padd("xmlns:math", "CDATA", "http://www.w3.org/1998/Math/MathML");
54 rstartEl("math:math", mxList
);
56 rstartEl("math:semantics", mxList
);
59 makeLines( tmp
->child
);
63 fprintf(stderr
,"<math:semantics/>\n");
66 fprintf(stderr
,"</math:math>\n");
68 rendEl("math:semantics");
73 void Formula::makeLines(Node
*res
)
79 if( tmp
->child
->id
== ID_LINES
)
80 makeLines( tmp
->child
);
82 makeLine( tmp
->child
);
85 makeLine( tmp
->next
);
88 void Formula::makeLine(Node
*res
)
92 inds
; fprintf(stderr
,"<math:mrow>\n");
94 rstartEl("math:mrow", mxList
);
97 makeExprList( res
->child
);
99 inde
; fprintf(stderr
,"</math:mrow>\n");
105 void Formula::makeExprList(Node
*res
)
108 Node
*tmp
= res
->child
;
111 if( tmp
->id
== ID_EXPRLIST
){
112 Node
*next
= tmp
->next
;
113 makeExprList( tmp
) ;
121 void Formula::makeExpr(Node
*res
)
124 Node
*tmp
= res
->child
;
131 fprintf(stderr
,"<math:mrow>\n");
133 rstartEl("math:mrow", mxList
);
141 inde
; fprintf(stderr
,"</math:mrow>\n");
152 case ID_FRACTIONEXPR
:
156 case ID_DECORATIONEXPR
:
184 void Formula::makeIdentifier(Node
*res
)
188 if( !tmp
->value
) return;
193 fprintf(stderr
,"<math:mi>%s</math:mi>\n",tmp
->value
.get());
196 rstartEl("math:mi", mxList
);
197 rchars(OUString::createFromAscii(tmp
->value
.get()));
205 rstartEl("math:mi", mxList
);
206 reucstr(tmp
->value
.get(), strlen(tmp
->value
.get()));
214 fprintf(stderr
,"<math:mi>%s</math:mi>\n",
215 getMathMLEntity(tmp
->value
.get()).c_str());
218 rstartEl("math:mi", mxList
);
219 runistr(fromHcharStringToOUString(getMathMLEntity(tmp
->value
.get())));
226 fprintf(stderr
,"<math:mn>%s</math:mn>\n",tmp
->value
.get());
229 rstartEl("math:mn", mxList
);
230 rchars(OUString::createFromAscii(tmp
->value
.get()));
238 inds
; fprintf(stderr
,"<math:mo>%s</math:mo>\n",tmp
->value
.get()); indo
;
240 rstartEl("math:mo", mxList
);
241 runistr(fromHcharStringToOUString(getMathMLEntity(tmp
->value
.get())));
248 void Formula::makePrimary(Node
*res
)
253 if( tmp
->child
->id
== ID_PRIMARYEXPR
){
254 makePrimary(tmp
->child
);
257 makeIdentifier(tmp
->child
);
261 makeIdentifier(tmp
->next
);
265 void Formula::makeSubSup(Node
*res
)
272 if( res
->id
== ID_SUBEXPR
)
273 fprintf(stderr
,"<math:msub>\n");
274 else if( res
->id
== ID_SUPEXPR
)
275 fprintf(stderr
,"<math:msup>\n");
277 fprintf(stderr
,"<math:msubsup>\n");
279 if( res
->id
== ID_SUBEXPR
)
280 rstartEl("math:msub", mxList
);
281 else if( res
->id
== ID_SUPEXPR
)
282 rstartEl("math:msup", mxList
);
284 rstartEl("math:msubsup", mxList
);
288 if( res
->id
== ID_SUBSUPEXPR
) {
290 makeBlock(tmp
->next
);
291 makeBlock(tmp
->next
->next
);
300 if( res
->id
== ID_SUBEXPR
)
301 fprintf(stderr
,"</math:msub>\n");
302 else if( res
->id
== ID_SUPEXPR
)
303 fprintf(stderr
,"</math:msup>\n");
305 fprintf(stderr
,"</math:msubsup>\n");
307 if( res
->id
== ID_SUBEXPR
)
309 else if( res
->id
== ID_SUPEXPR
)
312 rendEl("math:msubsup");
316 void Formula::makeFraction(Node
*res
)
323 fprintf(stderr
,"<math:mfrac>\n");
325 rstartEl("math:mfrac", mxList
);
331 fprintf(stderr
,"<math:mrow>\n");
333 rstartEl("math:mrow", mxList
);
336 if( res
->id
== ID_FRACTIONEXPR
)
343 fprintf(stderr
,"</math:mrow>\n");
345 fprintf(stderr
,"<math:mrow>\n");
348 rstartEl("math:mrow", mxList
);
351 if( res
->id
== ID_FRACTIONEXPR
)
352 makeBlock(tmp
->next
);
354 makeExprList(tmp
->next
);
358 fprintf(stderr
,"</math:mrow>\n");
360 fprintf(stderr
,"</math:mfrac>\n");
363 rendEl("math:mfrac");
367 void Formula::makeDecoration(Node
*res
)
370 Node
*tmp
= res
->child
;
372 if( !strncmp(tmp
->value
.get(),"under", 5) )
377 fprintf(stderr
,"<math:mover>\n");
379 fprintf(stderr
,"<math:munder>\n");
381 /* FIXME: no idea when 'accent' is true or false. */
383 padd("accent","CDATA","true");
384 rstartEl("math:mover", mxList
);
387 padd("accentunder","CDATA","true");
388 rstartEl("math:munder", mxList
);
393 makeBlock(tmp
->next
);
397 fprintf(stderr
,"<math:mo>%s</math:mo>\n",
398 getMathMLEntity(tmp
->value
.get()).c_str());
401 rstartEl("math:mo", mxList
);
402 runistr(fromHcharStringToOUString(getMathMLEntity(tmp
->value
.get())));
409 fprintf(stderr
,"</math:mover>\n");
411 fprintf(stderr
,"</math:munder>\n");
414 rendEl("math:mover");
416 rendEl("math:munder");
420 void Formula::makeRoot(Node
*res
)
426 if( tmp
->id
== ID_SQRTEXPR
)
427 fprintf(stderr
,"<math:msqrt>\n");
429 fprintf(stderr
,"<math:mroot>\n");
431 if( tmp
->id
== ID_SQRTEXPR
)
432 rstartEl("math:msqrt", mxList
);
434 rstartEl("math:mroot", mxList
);
437 if( tmp
->id
== ID_SQRTEXPR
){
438 makeBlock(tmp
->child
);
441 makeBracket(tmp
->child
);
442 makeBlock(tmp
->child
->next
);
447 if( tmp
->id
== ID_SQRTEXPR
)
448 fprintf(stderr
,"</math:msqrt>\n");
450 fprintf(stderr
,"</math:mroot>\n");
452 if( tmp
->id
== ID_SQRTEXPR
)
453 rendEl("math:msqrt");
455 rendEl("math:mroot");
458 void Formula::makeAccent(Node
*res
)
460 makeDecoration( res
);
462 void Formula::makeParenth(Node
*res
)
468 fprintf(stderr
,"<math:mrow>\n");
470 if( tmp
->id
== ID_PARENTH
){
471 fprintf(stderr
,"<math:mo>(</math:mo>\n");
474 fprintf(stderr
,"<math:mo>|</math:mo>\n");
476 fprintf(stderr
,"<math:mrow>\n");
478 rstartEl("math:mrow", mxList
);
479 rstartEl("math:mo", mxList
);
480 if( tmp
->id
== ID_PARENTH
)
485 rstartEl("math:mrow", mxList
);
489 makeExprList(tmp
->child
);
493 fprintf(stderr
,"</math:mrow>\n");
495 if( tmp
->id
== ID_PARENTH
)
496 fprintf(stderr
,"<math:mo>)</math:mo>\n");
498 fprintf(stderr
,"<math:mo>|</math:mo>\n");
501 fprintf(stderr
,"</math:mrow>\n");
504 rstartEl("math:mo", mxList
);
505 if( tmp
->id
== ID_PARENTH
)
514 void Formula::makeFence(Node
*res
)
516 Node
*tmp
= res
->child
;
519 fprintf(stderr
,"<math:mfenced open=\"%s\" close=\"%s\">\n",
520 getMathMLEntity(tmp
->value
.get()).c_str(),
521 getMathMLEntity(tmp
->next
->next
->value
.get()).c_str());
523 padd("open", "CDATA",
524 OUString(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->value
.get()).c_str())));
525 padd("close", "CDATA",
526 OUString(reinterpret_cast<sal_Unicode
const *>(getMathMLEntity(tmp
->next
->next
->value
.get()).c_str())));
527 rstartEl("math:mfenced", mxList
);
531 makeExprList(tmp
->next
);
535 fprintf(stderr
,"</math:mfenced>\n");
537 rendEl("math:mfenced");
541 void Formula::makeBracket(Node
*res
)
546 void Formula::makeBlock(Node
*res
)
550 fprintf(stderr
,"<math:mrow>\n");
552 rstartEl("math:mrow", mxList
);
556 makeExprList(res
->child
);
560 fprintf(stderr
,"</math:mrow>\n");
566 void Formula::parse()
572 // fprintf(stderr,"\n\n[BEFORE]\n[%s]\n",eq);
575 int idx
=a
.indexOf('\xff');
577 //printf("idx = [%d]\n",idx);
578 a
= a
.replaceAt(idx
, 1, "\x20");
579 idx
= a
.indexOf('\xff', idx
+ 1);
582 char *buf
= static_cast<char *>(malloc(a
.getLength()+1));
585 for( i
= 0, j
=0 ; i
< a
.getLength() ; i
++){ // rtrim and ltrim 32 10 13
590 if( a
[i
] != 32 && a
[i
] != 10 && a
[i
] != 13){
597 for( i
= j
-1 ; i
>= 0 ; i
++ ){
598 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
604 // fprintf(stderr,"\n\n[RESULT]\n[%s]\n",a.c_str());
606 res
= mainParse( a
.getStr() );
619 int len
= strlen(eq
);
620 char *buf
= static_cast<char *>(malloc(len
+1));
623 for( i
= 0, j
=0 ; i
< len
; i
++){ // rtrim and ltrim 32 10 13
628 if( eq
[i
] != 32 && eq
[i
] != 10 && eq
[i
] != 13){
635 for( i
= j
-1 ; i
>= 0 ; i
++ ){
636 if( buf
[i
] == 32 || buf
[i
] == 10 || buf
[i
] == 13 ){
649 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */