1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_starmath.hxx"
32 Warning: The SvXMLElementExport helper class creates the beginning and
33 closing tags of xml elements in its constructor and destructor, so theres
34 hidden stuff going on, on occasion the ordering of these classes declarations
39 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
40 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
41 #include <com/sun/star/xml/sax/InputSource.hpp>
42 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
43 #include <com/sun/star/xml/sax/XParser.hpp>
44 #include <com/sun/star/io/XActiveDataSource.hpp>
45 #include <com/sun/star/io/XActiveDataControl.hpp>
46 #include <com/sun/star/document/XDocumentProperties.hpp>
47 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
48 #include <com/sun/star/packages/zip/ZipIOException.hpp>
49 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
50 #include <com/sun/star/beans/PropertyAttribute.hpp>
51 #include <com/sun/star/container/XNameAccess.hpp>
52 #include <com/sun/star/embed/ElementModes.hpp>
53 #include <com/sun/star/uno/Any.h>
55 #include <rtl/math.hxx>
56 #include <sfx2/frame.hxx>
57 #include <sfx2/docfile.hxx>
58 #include <tools/debug.hxx>
59 #include <tools/urlobj.hxx>
60 #include <svtools/sfxecode.hxx>
61 #include <unotools/saveopt.hxx>
62 #include <svl/stritem.hxx>
63 #include <svl/itemprop.hxx>
64 #include <unotools/processfactory.hxx>
65 #include <unotools/streamwrap.hxx>
66 #include <xmloff/xmlnmspe.hxx>
67 #include <xmloff/xmltoken.hxx>
68 #include <xmloff/nmspmap.hxx>
69 #include <xmloff/attrlist.hxx>
70 #include <xmloff/xmluconv.hxx>
71 #include <xmloff/xmlmetai.hxx>
72 #include <osl/mutex.hxx>
73 #include <comphelper/genericpropertyset.hxx>
77 #include "mathmlexport.hxx"
78 #include <starmath.hrc>
79 #include <unomodel.hxx>
80 #include <document.hxx>
81 #include <utility.hxx>
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::container
;
85 using namespace ::com::sun::star::document
;
86 using namespace ::com::sun::star::lang
;
87 using namespace ::com::sun::star::uno
;
88 using namespace ::com::sun::star
;
89 using namespace ::xmloff::token
;
91 using ::rtl::OUString
;
92 using ::rtl::OUStringBuffer
;
94 #define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
99 ////////////////////////////////////////////////////////////
101 sal_Bool
SmXMLExportWrapper::Export(SfxMedium
&rMedium
)
103 sal_Bool bRet
=sal_True
;
104 uno::Reference
<lang::XMultiServiceFactory
>
105 xServiceFactory(utl::getProcessServiceFactory());
106 DBG_ASSERT(xServiceFactory
.is(),"got no service manager");
109 uno::Reference
< lang::XComponent
> xModelComp(xModel
, uno::UNO_QUERY
);
111 sal_Bool bEmbedded
= sal_False
;
112 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
113 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
114 SmModel
*pModel
= reinterpret_cast<SmModel
*>
115 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
117 SmDocShell
*pDocShell
= pModel
?
118 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
120 SFX_CREATE_MODE_EMBEDDED
== pDocShell
->GetCreateMode() )
121 bEmbedded
= sal_True
;
123 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
126 if (pDocShell
/*&& pDocShell->GetMedium()*/)
128 DBG_ASSERT( pDocShell
->GetMedium() == &rMedium
,
129 "different SfxMedium found" );
131 SfxItemSet
* pSet
= rMedium
.GetItemSet();
134 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
135 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
137 pItem
->GetValue() >>= xStatusIndicator
;
141 // set progress range and start status indicator
142 if (xStatusIndicator
.is())
144 sal_Int32 nProgressRange
= bFlat
? 1 : 3;
145 xStatusIndicator
->start(String(SmResId(STR_STATSTR_WRITING
)),
151 // create XPropertySet with three properties for status indicator
152 comphelper::PropertyMapEntry aInfoMap
[] =
154 { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
155 &::getBooleanCppuType(),
156 beans::PropertyAttribute::MAYBEVOID
, 0},
157 { "BaseURI", sizeof("BaseURI")-1, 0,
158 &::getCppuType( (OUString
*)0 ),
159 beans::PropertyAttribute::MAYBEVOID
, 0 },
160 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
161 &::getCppuType( (OUString
*)0 ),
162 beans::PropertyAttribute::MAYBEVOID
, 0 },
163 { "StreamName", sizeof("StreamName")-1, 0,
164 &::getCppuType( (OUString
*)0 ),
165 beans::PropertyAttribute::MAYBEVOID
, 0 },
166 { NULL
, 0, 0, NULL
, 0, 0 }
168 uno::Reference
< beans::XPropertySet
> xInfoSet(
169 comphelper::GenericPropertySet_CreateInstance(
170 new comphelper::PropertySetInfo( aInfoMap
) ) );
172 SvtSaveOptions aSaveOpt
;
173 OUString
sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
174 sal_Bool
bUsePrettyPrinting( bFlat
|| aSaveOpt
.IsPrettyPrinting() );
176 aAny
.setValue( &bUsePrettyPrinting
, ::getBooleanCppuType() );
177 xInfoSet
->setPropertyValue( sUsePrettyPrinting
, aAny
);
180 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
181 xInfoSet
->setPropertyValue( sPropName
, makeAny( rMedium
.GetBaseURL( true ) ) );
184 if (xStatusIndicator
.is())
185 xStatusIndicator
->setValue(nSteps
++);
186 if (!bFlat
) //Storage (Package) of Stream
188 uno::Reference
< embed::XStorage
> xStg
= rMedium
.GetOutputStorage();
189 sal_Bool bOASIS
= ( SotStorage::GetVersion( xStg
) > SOFFICE_FILEFORMAT_60
);
191 // TODO/LATER: handle the case of embedded links gracefully
192 if ( bEmbedded
) //&& !pStg->IsRoot() )
195 if ( rMedium
.GetItemSet() )
197 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
198 rMedium
.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
199 if ( pDocHierarchItem
)
200 aName
= pDocHierarchItem
->GetValue();
203 if ( aName
.getLength() )
205 sPropName
= OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
206 xInfoSet
->setPropertyValue( sPropName
, makeAny( aName
) );
212 if (xStatusIndicator
.is())
213 xStatusIndicator
->setValue(nSteps
++);
215 bRet
= WriteThroughComponent(
216 xStg
, xModelComp
, "meta.xml", xServiceFactory
, xInfoSet
,
217 (bOASIS
? "com.sun.star.comp.Math.XMLOasisMetaExporter"
218 : "com.sun.star.comp.Math.XMLMetaExporter"),
223 if (xStatusIndicator
.is())
224 xStatusIndicator
->setValue(nSteps
++);
226 bRet
= WriteThroughComponent(
227 xStg
, xModelComp
, "content.xml", xServiceFactory
, xInfoSet
,
228 "com.sun.star.comp.Math.XMLContentExporter");
233 if (xStatusIndicator
.is())
234 xStatusIndicator
->setValue(nSteps
++);
236 bRet
= WriteThroughComponent(
237 xStg
, xModelComp
, "settings.xml", xServiceFactory
, xInfoSet
,
238 (bOASIS
? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
239 : "com.sun.star.comp.Math.XMLSettingsExporter") );
244 SvStream
*pStream
= rMedium
.GetOutStream();
245 uno::Reference
<io::XOutputStream
> xOut(
246 new utl::OOutputStreamWrapper(*pStream
) );
248 if (xStatusIndicator
.is())
249 xStatusIndicator
->setValue(nSteps
++);
251 bRet
= WriteThroughComponent(
252 xOut
, xModelComp
, xServiceFactory
, xInfoSet
,
253 "com.sun.star.comp.Math.XMLContentExporter");
256 if (xStatusIndicator
.is())
257 xStatusIndicator
->end();
263 /// export through an XML exporter component (output stream version)
264 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
265 Reference
<io::XOutputStream
> xOutputStream
,
266 Reference
<XComponent
> xComponent
,
267 Reference
<lang::XMultiServiceFactory
> & rFactory
,
268 Reference
<beans::XPropertySet
> & rPropSet
,
269 const sal_Char
* pComponentName
)
271 DBG_ASSERT(xOutputStream
.is(), "I really need an output stream!");
272 DBG_ASSERT(xComponent
.is(), "Need component!");
273 DBG_ASSERT(NULL
!= pComponentName
, "Need component name!");
276 Reference
< io::XActiveDataSource
> xSaxWriter(
277 rFactory
->createInstance(
278 OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
280 DBG_ASSERT( xSaxWriter
.is(), "can't instantiate XML writer" );
281 if (!xSaxWriter
.is())
284 // connect XML writer to output stream
285 xSaxWriter
->setOutputStream( xOutputStream
);
287 // prepare arguments (prepend doc handler to given arguments)
288 Reference
<xml::sax::XDocumentHandler
> xDocHandler( xSaxWriter
,UNO_QUERY
);
290 Sequence
<Any
> aArgs( 2 );
291 aArgs
[0] <<= xDocHandler
;
292 aArgs
[1] <<= rPropSet
;
294 // get filter component
295 Reference
< document::XExporter
> xExporter(
296 rFactory
->createInstanceWithArguments(
297 OUString::createFromAscii(pComponentName
), aArgs
), UNO_QUERY
);
298 DBG_ASSERT( xExporter
.is(),
299 "can't instantiate export filter component" );
300 if ( !xExporter
.is() )
304 // connect model and filter
305 xExporter
->setSourceDocument( xComponent
);
308 Reference
< XFilter
> xFilter( xExporter
, UNO_QUERY
);
309 uno::Sequence
< PropertyValue
> aProps(0);
310 xFilter
->filter( aProps
);
312 uno::Reference
<lang::XUnoTunnel
> xFilterTunnel
;
313 xFilterTunnel
= uno::Reference
<lang::XUnoTunnel
>
314 ( xFilter
, uno::UNO_QUERY
);
315 SmXMLExport
*pFilter
= reinterpret_cast< SmXMLExport
* >(
316 sal::static_int_cast
< sal_uIntPtr
>(
317 xFilterTunnel
->getSomething( SmXMLExport::getUnoTunnelId() )));
318 return pFilter
? pFilter
->GetSuccess() : sal_True
;
322 /// export through an XML exporter component (storage version)
323 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
324 const Reference
< embed::XStorage
>& xStorage
,
325 Reference
<XComponent
> xComponent
,
326 const sal_Char
* pStreamName
,
327 Reference
<lang::XMultiServiceFactory
> & rFactory
,
328 Reference
<beans::XPropertySet
> & rPropSet
,
329 const sal_Char
* pComponentName
,
333 DBG_ASSERT(xStorage
.is(), "Need storage!");
334 DBG_ASSERT(NULL
!= pStreamName
, "Need stream name!");
337 Reference
< io::XStream
> xStream
;
338 OUString sStreamName
= OUString::createFromAscii(pStreamName
);
341 xStream
= xStorage
->openStreamElement( sStreamName
,
342 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
344 catch ( uno::Exception
& )
346 DBG_ERROR( "Can't create output stream in package!" );
350 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
351 OUString
aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
355 uno::Reference
< beans::XPropertySet
> xSet( xStream
, uno::UNO_QUERY
);
356 xSet
->setPropertyValue( aPropName
, aAny
);
360 aPropName
= String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
361 sal_Bool bFalse
= sal_False
;
362 aAny
.setValue( &bFalse
, ::getBooleanCppuType() );
363 xSet
->setPropertyValue( aPropName
, aAny
);
366 // even plain stream must be encrypted in encrypted document
367 OUString
aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
368 sal_Bool bTrue
= sal_True
;
369 aAny
.setValue( &bTrue
, ::getBooleanCppuType() );
370 xSet
->setPropertyValue( aTmpPropName
, aAny
);
375 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
376 rPropSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
380 sal_Bool bRet
= WriteThroughComponent( xStream
->getOutputStream(), xComponent
, rFactory
,
381 rPropSet
, pComponentName
);
383 // stream is closed by SAX parser
385 // xStream->getOutputStream()->closeOutput();
390 ////////////////////////////////////////////////////////////
393 SmXMLExport::SmXMLExport(
394 const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xServiceFactory
,
395 sal_uInt16 nExportFlags
)
396 : SvXMLExport( xServiceFactory
, MAP_INCH
, XML_MATH
, nExportFlags
) ,
402 sal_Int64 SAL_CALL
SmXMLExport::getSomething(
403 const uno::Sequence
< sal_Int8
>& rId
)
404 throw(uno::RuntimeException
)
406 if ( rId
.getLength() == 16 &&
407 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
408 rId
.getConstArray(), 16 ) )
409 return sal::static_int_cast
< sal_Int64
>(reinterpret_cast< sal_uIntPtr
>(this));
411 return SvXMLExport::getSomething( rId
);
414 const uno::Sequence
< sal_Int8
> & SmXMLExport::getUnoTunnelId() throw()
416 static uno::Sequence
< sal_Int8
> * pSeq
= 0;
419 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
422 static uno::Sequence
< sal_Int8
> aSeq( 16 );
423 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
430 OUString SAL_CALL
SmXMLExport_getImplementationName() throw()
432 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
435 uno::Sequence
< OUString
> SAL_CALL
SmXMLExport_getSupportedServiceNames()
438 const OUString
aServiceName( EXPORT_SVC_NAME
);
439 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
443 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExport_createInstance(
444 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
445 throw( uno::Exception
)
448 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
449 // EXPORT_OASIS is required here allthough there is no differrence between
450 // OOo and OASIS, because without the flag, a transformation to OOo would
452 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_ALL
);
455 ////////////////////////////////////////////////////////////
457 OUString SAL_CALL
SmXMLExportMetaOOO_getImplementationName() throw()
459 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
462 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMetaOOO_getSupportedServiceNames()
465 const OUString
aServiceName( EXPORT_SVC_NAME
);
466 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
470 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMetaOOO_createInstance(
471 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
472 throw( uno::Exception
)
475 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
476 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_META
);
479 ////////////////////////////////////////////////////////////
481 OUString SAL_CALL
SmXMLExportMeta_getImplementationName() throw()
483 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
486 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMeta_getSupportedServiceNames()
489 const OUString
aServiceName( EXPORT_SVC_NAME
);
490 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
494 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMeta_createInstance(
495 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
496 throw( uno::Exception
)
499 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
500 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_META
);
503 ////////////////////////////////////////////////////////////
505 OUString SAL_CALL
SmXMLExportSettingsOOO_getImplementationName() throw()
507 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
510 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettingsOOO_getSupportedServiceNames()
513 const OUString
aServiceName( EXPORT_SVC_NAME
);
514 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
518 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettingsOOO_createInstance(
519 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
520 throw( uno::Exception
)
523 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
524 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_SETTINGS
);
527 ////////////////////////////////////////////////////////////
529 OUString SAL_CALL
SmXMLExportSettings_getImplementationName() throw()
531 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
534 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettings_getSupportedServiceNames()
537 const OUString
aServiceName( EXPORT_SVC_NAME
);
538 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
542 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettings_createInstance(
543 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
544 throw( uno::Exception
)
547 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
548 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_SETTINGS
);
551 ////////////////////////////////////////////////////////////
553 OUString SAL_CALL
SmXMLExportContent_getImplementationName() throw()
555 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
558 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportContent_getSupportedServiceNames()
561 const OUString
aServiceName( EXPORT_SVC_NAME
);
562 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
566 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportContent_createInstance(
567 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
568 throw( uno::Exception
)
571 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
572 // The EXPORT_OASIS flag is only required to avoid that a transformer is
574 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_CONTENT
);
577 ////////////////////////////////////////////////////////////
580 // override empty method from parent class
581 rtl::OUString SAL_CALL
SmXMLExport::getImplementationName()
582 throw(uno::RuntimeException
)
585 switch( getExportFlags() )
588 aTxt
= SmXMLExportMeta_getImplementationName();
590 case EXPORT_SETTINGS
:
591 aTxt
= SmXMLExportSettings_getImplementationName();
594 aTxt
= SmXMLExportContent_getImplementationName();
598 aTxt
= SmXMLExport_getImplementationName();
604 sal_uInt32
SmXMLExport::exportDoc(enum XMLTokenEnum eClass
)
606 if ( (getExportFlags() & EXPORT_CONTENT
) == 0 )
608 SvXMLExport::exportDoc( eClass
);
612 uno::Reference
<frame::XModel
> xModel
= GetModel();
613 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
614 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
615 SmModel
*pModel
= reinterpret_cast<SmModel
*>
616 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
620 SmDocShell
*pDocShell
=
621 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
622 pTree
= pDocShell
->GetFormulaTree();
623 aText
= pDocShell
->GetText();
626 GetDocHandler()->startDocument();
629 SvXMLAttributeList
&rList
= GetAttrList();
631 // make use of a default namespace
632 ResetNamespaceMap(); // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
633 _GetNamespaceMap().Add( OUString::createFromAscii(""), GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
635 rList
.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX
),
636 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX
));
638 //I think we need something like ImplExportEntities();
640 GetDocHandler()->endDocument();
647 void SmXMLExport::_ExportContent()
649 SvXMLElementExport
aEquation(*this, XML_NAMESPACE_MATH
, XML_MATH
, sal_True
, sal_True
);
650 SvXMLElementExport
*pSemantics
=0;
654 pSemantics
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
655 XML_SEMANTICS
, sal_True
, sal_True
);
658 ExportNodes(pTree
, 0);
662 // Convert symbol names
663 uno::Reference
<frame::XModel
> xModel
= GetModel();
664 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
665 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
666 SmModel
*pModel
= reinterpret_cast<SmModel
*>
667 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
668 SmDocShell
*pDocShell
= pModel
?
669 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
670 DBG_ASSERT( pDocShell
, "doc shell missing" );
673 SmParser
&rParser
= pDocShell
->GetParser();
674 BOOL bVal
= rParser
.IsExportSymbolNames();
675 rParser
.SetExportSymbolNames( TRUE
);
676 SmNode
*pTmpTree
= rParser
.Parse( aText
);
677 aText
= rParser
.GetText();
679 rParser
.SetExportSymbolNames( bVal
);
682 AddAttribute(XML_NAMESPACE_MATH
, XML_ENCODING
,
683 OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
684 SvXMLElementExport
aAnnotation(*this, XML_NAMESPACE_MATH
,
685 XML_ANNOTATION
, sal_True
, sal_False
);
686 GetDocHandler()->characters(OUString( aText
));
691 void SmXMLExport::GetViewSettings( Sequence
< PropertyValue
>& aProps
)
693 uno::Reference
<frame::XModel
> xModel
= GetModel();
697 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
698 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
699 SmModel
*pModel
= reinterpret_cast<SmModel
*>
700 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
705 SmDocShell
*pDocShell
=
706 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
711 PropertyValue
*pValue
= aProps
.getArray();
712 sal_Int32 nIndex
= 0;
714 Rectangle
aRect( pDocShell
->GetVisArea() );
716 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
717 pValue
[nIndex
++].Value
<<= aRect
.Top();
719 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
720 pValue
[nIndex
++].Value
<<= aRect
.Left();
722 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
723 pValue
[nIndex
++].Value
<<= aRect
.GetWidth();
725 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
726 pValue
[nIndex
++].Value
<<= aRect
.GetHeight();
729 void SmXMLExport::GetConfigurationSettings( Sequence
< PropertyValue
> & rProps
)
731 Reference
< XPropertySet
> xProps ( GetModel(), UNO_QUERY
);
734 Reference
< XPropertySetInfo
> xPropertySetInfo
= xProps
->getPropertySetInfo();
735 if (xPropertySetInfo
.is())
737 Sequence
< Property
> aProps
= xPropertySetInfo
->getProperties();
738 sal_Int32
nCount(aProps
.getLength());
741 rProps
.realloc(nCount
);
742 PropertyValue
* pProps
= rProps
.getArray();
745 const OUString
sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
746 const OUString
sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
747 const OUString
sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
748 const OUString
sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
749 for (sal_Int32 i
= 0; i
< nCount
; i
++, pProps
++)
751 const OUString
&rPropName
= aProps
[i
].Name
;
752 if (rPropName
!= sFormula
&&
753 rPropName
!= sBasicLibraries
&&
754 rPropName
!= sDialogLibraries
&&
755 rPropName
!= sRuntimeUID
)
757 pProps
->Name
= rPropName
;
758 pProps
->Value
= xProps
->getPropertyValue(rPropName
);
767 void SmXMLExport::ExportLine(const SmNode
*pNode
, int nLevel
)
769 ExportExpression(pNode
, nLevel
);
772 void SmXMLExport::ExportBinaryHorizontal(const SmNode
*pNode
, int nLevel
)
774 ExportExpression(pNode
, nLevel
);
777 void SmXMLExport::ExportUnaryHorizontal(const SmNode
*pNode
, int nLevel
)
779 ExportExpression(pNode
, nLevel
);
782 void SmXMLExport::ExportExpression(const SmNode
*pNode
, int nLevel
)
784 SvXMLElementExport
*pRow
=0;
785 ULONG nSize
= pNode
->GetNumSubNodes();
788 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
, sal_True
, sal_True
);
792 for (USHORT i
= 0; i
< nSize
; i
++)
793 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
794 ExportNodes(pTemp
, nLevel
+1);
799 //This saves us from situations like "a newline" where the
800 //lack of a term following the newline would otherwise create
801 //a incorrect token like <mtr/>
802 SvXMLElementExport
aDummy(*this, XML_NAMESPACE_MATH
, XML_MI
, sal_True
, sal_False
);
803 sal_Unicode nArse
[2] = {'\n','\0'};
804 GetDocHandler()->characters(nArse
);
811 void SmXMLExport::ExportBinaryVertical(const SmNode
*pNode
, int nLevel
)
813 DBG_ASSERT(pNode
->GetNumSubNodes()==3,"Bad Fraction");
814 SvXMLElementExport
aFraction(*this, XML_NAMESPACE_MATH
, XML_MFRAC
, sal_True
, sal_True
);
815 ExportNodes(pNode
->GetSubNode(0), nLevel
);
816 ExportNodes(pNode
->GetSubNode(2), nLevel
);
819 void SmXMLExport::ExportTable(const SmNode
*pNode
, int nLevel
)
821 SvXMLElementExport
*pTable
=0;
823 USHORT nSize
= pNode
->GetNumSubNodes();
825 //If the list ends in newline then the last entry has
826 //no subnodes, the newline is superfulous so we just drop
827 //the last node, inclusion would create a bad MathML
829 if (nSize
>= 1 && pNode
->GetSubNode(nSize
-1)->GetNumSubNodes() == 0)
832 // try to avoid creating a mtable element when the formula consists only
833 // of a single output line
834 if (nLevel
|| (nSize
>1))
835 pTable
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
837 for (USHORT i
= 0; i
< nSize
; i
++)
838 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
840 SvXMLElementExport
*pRow
=0;
841 SvXMLElementExport
*pCell
=0;
844 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
845 pCell
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
847 ExportNodes(pTemp
, nLevel
+1);
855 void SmXMLExport::ExportMath(const SmNode
*pNode
, int /*nLevel*/)
857 const SmMathSymbolNode
*pTemp
= static_cast<const SmMathSymbolNode
*>(pNode
);
858 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
, sal_True
, sal_False
);
859 sal_Unicode nArse
[2];
860 nArse
[0] = pTemp
->GetText().GetChar(0);
861 sal_Unicode cTmp
= ConvertMathToMathML( nArse
[0] );
864 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
866 GetDocHandler()->characters(nArse
);
869 void SmXMLExport::ExportText(const SmNode
*pNode
, int /*nLevel*/)
871 SvXMLElementExport
*pText
;
872 const SmTextNode
*pTemp
= static_cast<const SmTextNode
*>(pNode
);
873 switch (pNode
->GetToken().eType
)
878 //Note that we change the fontstyle to italic for strings that
879 //are italic and longer than a single character.
880 sal_Bool bIsItalic
= IsItalic( pTemp
->GetFont() );
881 if ((pTemp
->GetText().Len() > 1) && bIsItalic
)
882 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_ITALIC
);
883 else if ((pTemp
->GetText().Len() == 1) && !bIsItalic
)
884 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_NORMAL
);
885 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
,sal_True
,sal_False
);
889 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MN
,sal_True
,sal_False
);
892 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTEXT
,sal_True
,sal_False
);
895 GetDocHandler()->characters(OUString(pTemp
->GetText().GetBuffer()));
899 void SmXMLExport::ExportBlank(const SmNode
* /*pNode*/, int /*nLevel*/)
901 //!! exports an empty <mi> tag since for example "~_~" is allowed in
902 //!! Math (so it has no sense at all) but must not result in an empty
903 //!! <msub> tag in MathML !!
905 SvXMLElementExport
*pText
;
906 //const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
908 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
, sal_True
, sal_False
);
910 GetDocHandler()->characters( OUString() );
914 void SmXMLExport::ExportSubSupScript(const SmNode
*pNode
, int nLevel
)
916 const SmNode
*pSub
= 0;
917 const SmNode
*pSup
= 0;
918 const SmNode
*pCSub
= 0;
919 const SmNode
*pCSup
= 0;
920 const SmNode
*pLSub
= 0;
921 const SmNode
*pLSup
= 0;
922 SvXMLElementExport
*pThing
= 0, *pThing2
= 0;
924 //if we have prescripts at all then we must use the tensor notation
926 //This is one of those excellent locations where scope is vital to
927 //arrange the construction and destruction of the element helper
929 pLSub
= pNode
->GetSubNode(LSUB
+1);
930 pLSup
= pNode
->GetSubNode(LSUP
+1);
933 SvXMLElementExport
aMultiScripts(*this, XML_NAMESPACE_MATH
,
934 XML_MMULTISCRIPTS
, sal_True
, sal_True
);
937 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
938 && NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
940 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
941 XML_MUNDEROVER
, sal_True
,sal_True
);
943 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
945 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
946 XML_MUNDER
, sal_True
,sal_True
);
948 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
950 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
951 XML_MOVER
, sal_True
,sal_True
);
954 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
957 ExportNodes(pCSub
, nLevel
+1);
959 ExportNodes(pCSup
, nLevel
+1);
962 pSub
= pNode
->GetSubNode(RSUB
+1);
963 pSup
= pNode
->GetSubNode(RSUP
+1);
967 ExportNodes(pSub
, nLevel
+1);
970 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
973 ExportNodes(pSup
, nLevel
+1);
976 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
980 //Seperator element between suffix and prefix sub/sup pairs
982 SvXMLElementExport
aPrescripts(*this, XML_NAMESPACE_MATH
,
983 XML_MPRESCRIPTS
, sal_True
,sal_True
);
987 ExportNodes(pLSub
, nLevel
+1);
990 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
995 ExportNodes(pLSup
, nLevel
+1);
998 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
1005 if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)) &&
1006 NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
1008 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1009 XML_MSUBSUP
, sal_True
,sal_True
);
1011 else if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)))
1013 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUB
,
1016 else if (NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
1018 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUP
,
1022 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
1023 && NULL
!= (pCSup
=pNode
->GetSubNode(CSUP
+1)))
1025 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1026 XML_MUNDEROVER
, sal_True
,sal_True
);
1028 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
1030 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1031 XML_MUNDER
, sal_True
,sal_True
);
1033 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
1035 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1036 XML_MOVER
, sal_True
,sal_True
);
1038 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
1041 ExportNodes(pCSub
, nLevel
+1);
1043 ExportNodes(pCSup
, nLevel
+1);
1047 ExportNodes(pSub
, nLevel
+1);
1049 ExportNodes(pSup
, nLevel
+1);
1054 void SmXMLExport::ExportBrace(const SmNode
*pNode
, int nLevel
)
1056 const SmNode
*pTemp
;
1057 const SmNode
*pLeft
=pNode
->GetSubNode(0);
1058 const SmNode
*pRight
=pNode
->GetSubNode(2);
1059 SvXMLElementExport
*pFences
=0,*pRow
=0;
1060 if ( ((pLeft
) && (pLeft
->GetToken().eType
!= TNONE
)) &&
1061 ((pRight
) && (pRight
->GetToken().eType
!= TNONE
)) &&
1062 (pNode
->GetScaleMode() == SCALE_HEIGHT
))
1064 sal_Unicode nArse
[2];
1066 nArse
[0] = static_cast<
1067 const SmMathSymbolNode
* >(pLeft
)->GetText().GetChar(0);
1068 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
1069 AddAttribute(XML_NAMESPACE_MATH
, XML_OPEN
,nArse
);
1070 nArse
[0] = static_cast<
1071 const SmMathSymbolNode
* >(pRight
)->GetText().GetChar(0);
1072 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
1073 AddAttribute(XML_NAMESPACE_MATH
, XML_CLOSE
,nArse
);
1074 pFences
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MFENCED
,
1077 else if (pLeft
&& (pLeft
->GetToken().eType
!= TNONE
))
1079 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1080 sal_True
, sal_True
);
1081 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1082 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1084 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1085 ExportNodes(pLeft
, nLevel
+1);
1088 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1089 sal_True
, sal_True
);
1091 if (NULL
!= (pTemp
= pNode
->GetSubNode(1)))
1092 ExportNodes(pTemp
, nLevel
+1);
1095 else if (pRight
&& (pRight
->GetToken().eType
!= TNONE
))
1097 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1098 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1100 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1101 ExportNodes(pRight
, nLevel
+1);
1106 void SmXMLExport::ExportRoot(const SmNode
*pNode
, int nLevel
)
1108 if (pNode
->GetSubNode(0))
1110 SvXMLElementExport
aRoot(*this, XML_NAMESPACE_MATH
, XML_MROOT
,sal_True
,
1112 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1113 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1117 SvXMLElementExport
aSqrt(*this, XML_NAMESPACE_MATH
, XML_MSQRT
,sal_True
,
1119 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1123 void SmXMLExport::ExportOperator(const SmNode
*pNode
, int nLevel
)
1125 /*we need to either use content or font and size attributes
1129 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1130 sal_True
,sal_False
);
1131 SmTextNode
*pTemp
= (SmTextNode
*)pNode
->GetSubNode(0);
1132 GetDocHandler()->characters(pTemp
->GetText());
1135 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1136 sal_True
, sal_True
);
1137 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1138 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1141 void SmXMLExport::ExportAttributes(const SmNode
*pNode
, int nLevel
)
1143 SvXMLElementExport
*pElement
=0;
1145 if (pNode
->GetToken().eType
== TUNDERLINE
)
1147 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENTUNDER
,
1149 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MUNDER
,
1152 else if (pNode
->GetToken().eType
!= TOVERSTRIKE
)
1154 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENT
,
1156 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MOVER
,
1160 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1161 switch (pNode
->GetToken().eType
)
1165 //proper entity support required
1166 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1169 GetDocHandler()->characters(
1170 OUString(RTL_CONSTASCII_USTRINGPARAM("&overbar;")));
1172 sal_Unicode nArse
[2] = {0xAF,0x00};
1174 GetDocHandler()->characters(nArse
);
1179 //proper entity support required
1180 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1183 GetDocHandler()->characters(
1184 OUString(RTL_CONSTASCII_USTRINGPARAM("&underbar;")));
1186 sal_Unicode nArse
[2] = {0x0332,0x00};
1188 GetDocHandler()->characters(nArse
);
1194 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1200 static bool lcl_HasEffectOnMathvariant( const SmTokenType eType
)
1202 return eType
== TBOLD
|| eType
== TNBOLD
||
1203 eType
== TITALIC
|| eType
== TNBOLD
||
1204 eType
== TSANS
|| eType
== TSERIF
|| eType
== TFIXED
;
1207 void SmXMLExport::ExportFont(const SmNode
*pNode
, int nLevel
)
1209 SvXMLElementExport
*pElement
= 0;
1212 // gather the mathvariant attribut relevant data from all
1213 // successively following SmFontNodes...
1215 int nBold
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1216 int nItalic
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1217 int nSansSerifFixed
= -1;
1218 SmTokenType eNodeType
= TUNKNOWN
;
1219 while (lcl_HasEffectOnMathvariant( (eNodeType
= pNode
->GetToken().eType
) ))
1223 case TBOLD
: nBold
= 1; break;
1224 case TNBOLD
: nBold
= 0; break;
1225 case TITALIC
: nItalic
= 1; break;
1226 case TNITALIC
: nItalic
= 0; break;
1227 case TSANS
: nSansSerifFixed
= 0; break;
1228 case TSERIF
: nSansSerifFixed
= 1; break;
1229 case TFIXED
: nSansSerifFixed
= 2; break;
1231 DBG_ASSERT( 0, "unexpected case" );
1233 // According to the parser every node that is to be evaluated heres
1234 // has a single non-zero subnode at index 1!! Thus we only need to check
1235 // that single node for follow-up nodes that have an effect on the attribute.
1236 if (pNode
->GetNumSubNodes() > 1 && pNode
->GetSubNode(1) &&
1237 lcl_HasEffectOnMathvariant( pNode
->GetSubNode(1)->GetToken().eType
))
1239 pNode
= pNode
->GetSubNode(1);
1245 switch (pNode
->GetToken().eType
)
1247 //wrap a phantom element around everything*/
1249 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1250 XML_MPHANTOM
, sal_True
,sal_True
);
1253 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLACK
);
1256 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_WHITE
);
1259 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_RED
);
1262 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_GREEN
);
1265 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLUE
);
1268 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_AQUA
);
1271 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_FUCHSIA
);
1274 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_YELLOW
);
1278 const SmFontNode
*pFontNode
= static_cast<const SmFontNode
*>(pNode
);
1279 const Fraction
&aFrac
= pFontNode
->GetSizeParameter();
1281 OUStringBuffer sStrBuf
;
1282 switch(pFontNode
->GetSizeType())
1284 case FNTSIZ_MULTIPLY
:
1285 SvXMLUnitConverter::convertDouble(sStrBuf
,
1286 static_cast<double>(aFrac
*Fraction(100.00)));
1287 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1290 SvXMLUnitConverter::convertDouble(sStrBuf
,
1291 static_cast<double>(Fraction(100.00)/aFrac
));
1292 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1294 case FNTSIZ_ABSOLUT
:
1295 SvXMLUnitConverter::convertDouble(sStrBuf
,
1296 static_cast<double>(aFrac
));
1298 GetXMLToken(XML_UNIT_PT
));
1302 //The problem here is that the wheels fall off because
1303 //font size is stored in 100th's of a mm not pts, and
1304 //rounding errors take their toll on the original
1305 //value specified in points.
1307 //Must fix StarMath to retain the original pt values
1308 Fraction aTemp
= Sm100th_mmToPts(pFontNode
->GetFont().
1309 GetSize().Height());
1311 if (pFontNode
->GetSizeType() == FNTSIZ_MINUS
)
1316 double mytest
= static_cast<double>(aTemp
);
1318 mytest
= ::rtl::math::round(mytest
,1);
1319 SvXMLUnitConverter::convertDouble(sStrBuf
,mytest
);
1320 sStrBuf
.append(GetXMLToken(XML_UNIT_PT
));
1325 OUString
sStr(sStrBuf
.makeStringAndClear());
1326 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHSIZE
, sStr
);
1337 // nBold: -1 = yet undefined; 0 = false; 1 = true;
1338 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
1339 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
1340 const sal_Char
*pText
= "normal";
1341 if (nSansSerifFixed
== -1 || nSansSerifFixed
== 1)
1344 if (nBold
== 1 && nItalic
!= 1)
1346 else if (nBold
!= 1 && nItalic
== 1)
1348 else if (nBold
== 1 && nItalic
== 1)
1349 pText
= "bold-italic";
1351 else if (nSansSerifFixed
== 0)
1353 pText
= "sans-serif";
1354 if (nBold
== 1 && nItalic
!= 1)
1355 pText
= "bold-sans-serif";
1356 else if (nBold
!= 1 && nItalic
== 1)
1357 pText
= "sans-serif-italic";
1358 else if (nBold
== 1 && nItalic
== 1)
1359 pText
= "sans-serif-bold-italic";
1361 else if (nSansSerifFixed
== 2)
1362 pText
= "monospace"; // no modifiers allowed for monospace ...
1365 DBG_ASSERT( 0, "unexpected case" );
1367 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, A2OU(pText
));
1375 if (pNode
->GetNumSubNodes() > 1) //or in the future is a node that
1376 //cannot take the currently supported
1379 //for now we will just always export with a style and not worry about
1380 //anyone else for the moment.
1382 //wrap a style around it
1383 SvXMLElementExport
aStyle(*this, XML_NAMESPACE_MATH
, XML_MSTYLE
, sal_True
,sal_True
);
1384 ExportExpression(pNode
, nLevel
);
1388 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1395 void SmXMLExport::ExportVerticalBrace(const SmNode
*pNode
, int nLevel
)
1397 //Place the overbrace value OVER a vertical brace and then place that
1398 //expression OVER the overbrace value, If someone can find a
1399 //dedicated term in MathML to handle this overbrace/underbrace concept
1403 switch (pNode
->GetToken().eType
)
1414 DBG_ASSERT(pNode
->GetNumSubNodes()==3,"Bad Vertical Brace");
1415 SvXMLElementExport
aOver1(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1417 // using accents will draw the over-/underbraces too close to the base
1418 // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
1419 // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
1420 // AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT, XML_TRUE);
1421 SvXMLElementExport
aOver2(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1422 ExportNodes(pNode
->GetSubNode(0), nLevel
);
1423 ExportNodes(pNode
->GetSubNode(1), nLevel
);
1425 ExportNodes(pNode
->GetSubNode(2), nLevel
);
1428 void SmXMLExport::ExportMatrix(const SmNode
*pNode
, int nLevel
)
1430 SvXMLElementExport
aTable(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
1431 const SmMatrixNode
*pMatrix
= static_cast<const SmMatrixNode
*>(pNode
);
1433 for (ULONG y
= 0; y
< pMatrix
->GetNumRows(); y
++)
1435 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
1436 for (ULONG x
= 0; x
< pMatrix
->GetNumCols(); x
++)
1437 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
++))
1439 SvXMLElementExport
aCell(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
1440 ExportNodes(pTemp
, nLevel
+1);
1445 void SmXMLExport::ExportNodes(const SmNode
*pNode
, int nLevel
)
1449 switch(pNode
->GetType())
1452 ExportTable(pNode
, nLevel
);
1457 ExportExpression(pNode
, nLevel
);
1460 ExportLine(pNode
, nLevel
);
1463 ExportText(pNode
, nLevel
);
1465 case NSPECIAL
: //NSPECIAL requires some sort of Entity preservation in the XML engine.
1466 case NGLYPH_SPECIAL
:
1469 sal_Unicode cTmp
= 0;
1470 const SmTextNode
*pTemp
= static_cast< const SmTextNode
* >(pNode
);
1471 if (pTemp
->GetText().Len() > 0)
1472 cTmp
= ConvertMathToMathML( pTemp
->GetText().GetChar(0) );
1475 // no conversion to MathML implemented -> export it as text
1476 // thus at least it will not vanish into nothing
1477 ExportText(pNode
, nLevel
);
1481 //To fully handle generic MathML we need to implement the full
1482 //operator dictionary, we will generate MathML with explicit
1483 //stretchiness for now.
1484 sal_Int16 nLength
= GetAttrList().getLength();
1485 sal_Bool bAddStretch
=sal_True
;
1486 for ( sal_Int16 i
= 0; i
< nLength
; i
++ )
1488 OUString sLocalName
;
1489 sal_uInt16 nPrefix
= GetNamespaceMap().GetKeyByAttrName(
1490 GetAttrList().getNameByIndex(i
), &sLocalName
);
1492 if ( ( XML_NAMESPACE_MATH
== nPrefix
) &&
1493 IsXMLToken(sLocalName
, XML_STRETCHY
) )
1495 bAddStretch
= sal_False
;
1501 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1503 ExportMath(pNode
, nLevel
);
1508 ExportMath(pNode
, nLevel
);
1511 ExportBinaryHorizontal(pNode
, nLevel
);
1514 ExportUnaryHorizontal(pNode
, nLevel
);
1517 ExportBrace(pNode
, nLevel
);
1520 ExportBinaryVertical(pNode
, nLevel
);
1523 ExportSubSupScript(pNode
, nLevel
);
1526 ExportRoot(pNode
, nLevel
);
1529 ExportOperator(pNode
, nLevel
);
1532 ExportAttributes(pNode
, nLevel
);
1535 ExportFont(pNode
, nLevel
);
1537 case NVERTICAL_BRACE
:
1538 ExportVerticalBrace(pNode
, nLevel
);
1541 ExportMatrix(pNode
, nLevel
);
1544 ExportBlank(pNode
, nLevel
);
1547 DBG_ASSERT( 0, "Warning: failed to export a node?" );
1553 ULONG nSize
= pNode
->GetNumSubNodes();
1554 for (ULONG i
= 0; i
< nSize
; i
++)
1555 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
1556 ExportNodes(pTemp
, nLevel
+1);
1563 ////////////////////////////////////////////////////////////