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
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_starmath.hxx"
35 Warning: The SvXMLElementExport helper class creates the beginning and
36 closing tags of xml elements in its constructor and destructor, so theres
37 hidden stuff going on, on occasion the ordering of these classes declarations
42 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
43 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
44 #include <com/sun/star/xml/sax/InputSource.hpp>
45 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
46 #include <com/sun/star/xml/sax/XParser.hpp>
47 #include <com/sun/star/io/XActiveDataSource.hpp>
48 #include <com/sun/star/io/XActiveDataControl.hpp>
49 #include <com/sun/star/document/XDocumentProperties.hpp>
50 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
51 #include <com/sun/star/packages/zip/ZipIOException.hpp>
52 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
53 #include <com/sun/star/beans/PropertyAttribute.hpp>
54 #include <com/sun/star/container/XNameAccess.hpp>
55 #include <com/sun/star/embed/ElementModes.hpp>
56 #include <com/sun/star/uno/Any.h>
58 #include <rtl/math.hxx>
59 #include <sfx2/frame.hxx>
60 #include <sfx2/docfile.hxx>
61 #include <tools/debug.hxx>
62 #include <tools/urlobj.hxx>
63 #include <svtools/sfxecode.hxx>
64 #include <svtools/saveopt.hxx>
65 #include <svtools/stritem.hxx>
66 #include <svtools/itemprop.hxx>
67 #include <unotools/processfactory.hxx>
68 #include <unotools/streamwrap.hxx>
69 #include <xmloff/xmlnmspe.hxx>
70 #include <xmloff/xmltoken.hxx>
71 #include <xmloff/nmspmap.hxx>
72 #include <xmloff/attrlist.hxx>
73 #include <xmloff/xmluconv.hxx>
74 #include <xmloff/xmlmetai.hxx>
75 #include <osl/mutex.hxx>
76 #include <comphelper/genericpropertyset.hxx>
80 #include "mathmlexport.hxx"
81 #include "mathtype.hxx"
82 #include <starmath.hrc>
83 #include <unomodel.hxx>
84 #include <document.hxx>
85 #include <utility.hxx>
87 using namespace ::com::sun::star::beans
;
88 using namespace ::com::sun::star::container
;
89 using namespace ::com::sun::star::document
;
90 using namespace ::com::sun::star::lang
;
91 using namespace ::com::sun::star::uno
;
92 using namespace ::com::sun::star
;
93 using namespace ::xmloff::token
;
95 using ::rtl::OUString
;
96 using ::rtl::OUStringBuffer
;
98 #define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
103 ////////////////////////////////////////////////////////////
105 sal_Bool
SmXMLExportWrapper::Export(SfxMedium
&rMedium
)
107 sal_Bool bRet
=sal_True
;
108 uno::Reference
<lang::XMultiServiceFactory
>
109 xServiceFactory(utl::getProcessServiceFactory());
110 DBG_ASSERT(xServiceFactory
.is(),"got no service manager");
113 uno::Reference
< lang::XComponent
> xModelComp(xModel
, uno::UNO_QUERY
);
115 sal_Bool bEmbedded
= sal_False
;
116 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
117 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
118 SmModel
*pModel
= reinterpret_cast<SmModel
*>
119 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
121 SmDocShell
*pDocShell
= pModel
?
122 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
124 SFX_CREATE_MODE_EMBEDDED
== pDocShell
->GetCreateMode() )
125 bEmbedded
= sal_True
;
127 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
130 if (pDocShell
/*&& pDocShell->GetMedium()*/)
132 DBG_ASSERT( pDocShell
->GetMedium() == &rMedium
,
133 "different SfxMedium found" );
135 SfxItemSet
* pSet
= rMedium
.GetItemSet();
138 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
139 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
141 pItem
->GetValue() >>= xStatusIndicator
;
145 // set progress range and start status indicator
146 if (xStatusIndicator
.is())
148 sal_Int32 nProgressRange
= bFlat
? 1 : 3;
149 xStatusIndicator
->start(String(SmResId(STR_STATSTR_WRITING
)),
155 // create XPropertySet with three properties for status indicator
156 comphelper::PropertyMapEntry aInfoMap
[] =
158 { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
159 &::getBooleanCppuType(),
160 beans::PropertyAttribute::MAYBEVOID
, 0},
161 { "BaseURI", sizeof("BaseURI")-1, 0,
162 &::getCppuType( (OUString
*)0 ),
163 beans::PropertyAttribute::MAYBEVOID
, 0 },
164 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
165 &::getCppuType( (OUString
*)0 ),
166 beans::PropertyAttribute::MAYBEVOID
, 0 },
167 { "StreamName", sizeof("StreamName")-1, 0,
168 &::getCppuType( (OUString
*)0 ),
169 beans::PropertyAttribute::MAYBEVOID
, 0 },
170 { NULL
, 0, 0, NULL
, 0, 0 }
172 uno::Reference
< beans::XPropertySet
> xInfoSet(
173 comphelper::GenericPropertySet_CreateInstance(
174 new comphelper::PropertySetInfo( aInfoMap
) ) );
176 SvtSaveOptions aSaveOpt
;
177 OUString
sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
178 sal_Bool
bUsePrettyPrinting( bFlat
|| aSaveOpt
.IsPrettyPrinting() );
180 aAny
.setValue( &bUsePrettyPrinting
, ::getBooleanCppuType() );
181 xInfoSet
->setPropertyValue( sUsePrettyPrinting
, aAny
);
184 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
185 xInfoSet
->setPropertyValue( sPropName
, makeAny( rMedium
.GetBaseURL( true ) ) );
188 if (xStatusIndicator
.is())
189 xStatusIndicator
->setValue(nSteps
++);
190 if (!bFlat
) //Storage (Package) of Stream
192 uno::Reference
< embed::XStorage
> xStg
= rMedium
.GetOutputStorage();
193 sal_Bool bOASIS
= ( SotStorage::GetVersion( xStg
) > SOFFICE_FILEFORMAT_60
);
195 // TODO/LATER: handle the case of embedded links gracefully
196 if ( bEmbedded
) //&& !pStg->IsRoot() )
199 if ( rMedium
.GetItemSet() )
201 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
202 rMedium
.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
203 if ( pDocHierarchItem
)
204 aName
= pDocHierarchItem
->GetValue();
207 if ( aName
.getLength() )
209 sPropName
= OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
210 xInfoSet
->setPropertyValue( sPropName
, makeAny( aName
) );
216 if (xStatusIndicator
.is())
217 xStatusIndicator
->setValue(nSteps
++);
219 bRet
= WriteThroughComponent(
220 xStg
, xModelComp
, "meta.xml", xServiceFactory
, xInfoSet
,
221 (bOASIS
? "com.sun.star.comp.Math.XMLOasisMetaExporter"
222 : "com.sun.star.comp.Math.XMLMetaExporter"),
227 if (xStatusIndicator
.is())
228 xStatusIndicator
->setValue(nSteps
++);
230 bRet
= WriteThroughComponent(
231 xStg
, xModelComp
, "content.xml", xServiceFactory
, xInfoSet
,
232 "com.sun.star.comp.Math.XMLContentExporter");
237 if (xStatusIndicator
.is())
238 xStatusIndicator
->setValue(nSteps
++);
240 bRet
= WriteThroughComponent(
241 xStg
, xModelComp
, "settings.xml", xServiceFactory
, xInfoSet
,
242 (bOASIS
? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
243 : "com.sun.star.comp.Math.XMLSettingsExporter") );
248 SvStream
*pStream
= rMedium
.GetOutStream();
249 uno::Reference
<io::XOutputStream
> xOut(
250 new utl::OOutputStreamWrapper(*pStream
) );
252 if (xStatusIndicator
.is())
253 xStatusIndicator
->setValue(nSteps
++);
255 bRet
= WriteThroughComponent(
256 xOut
, xModelComp
, xServiceFactory
, xInfoSet
,
257 "com.sun.star.comp.Math.XMLContentExporter");
260 if (xStatusIndicator
.is())
261 xStatusIndicator
->end();
267 /// export through an XML exporter component (output stream version)
268 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
269 Reference
<io::XOutputStream
> xOutputStream
,
270 Reference
<XComponent
> xComponent
,
271 Reference
<lang::XMultiServiceFactory
> & rFactory
,
272 Reference
<beans::XPropertySet
> & rPropSet
,
273 const sal_Char
* pComponentName
)
275 DBG_ASSERT(xOutputStream
.is(), "I really need an output stream!");
276 DBG_ASSERT(xComponent
.is(), "Need component!");
277 DBG_ASSERT(NULL
!= pComponentName
, "Need component name!");
280 Reference
< io::XActiveDataSource
> xSaxWriter(
281 rFactory
->createInstance(
282 OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
284 DBG_ASSERT( xSaxWriter
.is(), "can't instantiate XML writer" );
285 if (!xSaxWriter
.is())
288 // connect XML writer to output stream
289 xSaxWriter
->setOutputStream( xOutputStream
);
291 // prepare arguments (prepend doc handler to given arguments)
292 Reference
<xml::sax::XDocumentHandler
> xDocHandler( xSaxWriter
,UNO_QUERY
);
294 Sequence
<Any
> aArgs( 2 );
295 aArgs
[0] <<= xDocHandler
;
296 aArgs
[1] <<= rPropSet
;
298 // get filter component
299 Reference
< document::XExporter
> xExporter(
300 rFactory
->createInstanceWithArguments(
301 OUString::createFromAscii(pComponentName
), aArgs
), UNO_QUERY
);
302 DBG_ASSERT( xExporter
.is(),
303 "can't instantiate export filter component" );
304 if ( !xExporter
.is() )
308 // connect model and filter
309 xExporter
->setSourceDocument( xComponent
);
312 Reference
< XFilter
> xFilter( xExporter
, UNO_QUERY
);
313 uno::Sequence
< PropertyValue
> aProps(0);
314 xFilter
->filter( aProps
);
316 uno::Reference
<lang::XUnoTunnel
> xFilterTunnel
;
317 xFilterTunnel
= uno::Reference
<lang::XUnoTunnel
>
318 ( xFilter
, uno::UNO_QUERY
);
319 SmXMLExport
*pFilter
= reinterpret_cast< SmXMLExport
* >(
320 sal::static_int_cast
< sal_uIntPtr
>(
321 xFilterTunnel
->getSomething( SmXMLExport::getUnoTunnelId() )));
322 return pFilter
? pFilter
->GetSuccess() : sal_True
;
326 /// export through an XML exporter component (storage version)
327 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
328 const Reference
< embed::XStorage
>& xStorage
,
329 Reference
<XComponent
> xComponent
,
330 const sal_Char
* pStreamName
,
331 Reference
<lang::XMultiServiceFactory
> & rFactory
,
332 Reference
<beans::XPropertySet
> & rPropSet
,
333 const sal_Char
* pComponentName
,
337 DBG_ASSERT(xStorage
.is(), "Need storage!");
338 DBG_ASSERT(NULL
!= pStreamName
, "Need stream name!");
341 Reference
< io::XStream
> xStream
;
342 OUString sStreamName
= OUString::createFromAscii(pStreamName
);
345 xStream
= xStorage
->openStreamElement( sStreamName
,
346 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
348 catch ( uno::Exception
& )
350 DBG_ERROR( "Can't create output stream in package!" );
354 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
355 OUString
aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
359 uno::Reference
< beans::XPropertySet
> xSet( xStream
, uno::UNO_QUERY
);
360 xSet
->setPropertyValue( aPropName
, aAny
);
364 aPropName
= String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
365 sal_Bool bFalse
= sal_False
;
366 aAny
.setValue( &bFalse
, ::getBooleanCppuType() );
367 xSet
->setPropertyValue( aPropName
, aAny
);
370 // even plain stream must be encrypted in encrypted document
371 OUString
aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
372 sal_Bool bTrue
= sal_True
;
373 aAny
.setValue( &bTrue
, ::getBooleanCppuType() );
374 xSet
->setPropertyValue( aTmpPropName
, aAny
);
379 OUString
sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
380 rPropSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
384 sal_Bool bRet
= WriteThroughComponent( xStream
->getOutputStream(), xComponent
, rFactory
,
385 rPropSet
, pComponentName
);
387 // stream is closed by SAX parser
389 // xStream->getOutputStream()->closeOutput();
394 ////////////////////////////////////////////////////////////
397 SmXMLExport::SmXMLExport(
398 const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xServiceFactory
,
399 sal_uInt16 nExportFlags
)
400 : SvXMLExport( xServiceFactory
, MAP_INCH
, XML_MATH
, nExportFlags
) ,
406 sal_Int64 SAL_CALL
SmXMLExport::getSomething(
407 const uno::Sequence
< sal_Int8
>& rId
)
408 throw(uno::RuntimeException
)
410 if ( rId
.getLength() == 16 &&
411 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
412 rId
.getConstArray(), 16 ) )
413 return sal::static_int_cast
< sal_Int64
>(reinterpret_cast< sal_uIntPtr
>(this));
415 return SvXMLExport::getSomething( rId
);
418 const uno::Sequence
< sal_Int8
> & SmXMLExport::getUnoTunnelId() throw()
420 static uno::Sequence
< sal_Int8
> * pSeq
= 0;
423 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
426 static uno::Sequence
< sal_Int8
> aSeq( 16 );
427 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
434 OUString SAL_CALL
SmXMLExport_getImplementationName() throw()
436 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
439 uno::Sequence
< OUString
> SAL_CALL
SmXMLExport_getSupportedServiceNames()
442 const OUString
aServiceName( EXPORT_SVC_NAME
);
443 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
447 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExport_createInstance(
448 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
449 throw( uno::Exception
)
452 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
453 // EXPORT_OASIS is required here allthough there is no differrence between
454 // OOo and OASIS, because without the flag, a transformation to OOo would
456 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_ALL
);
459 ////////////////////////////////////////////////////////////
461 OUString SAL_CALL
SmXMLExportMetaOOO_getImplementationName() throw()
463 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
466 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMetaOOO_getSupportedServiceNames()
469 const OUString
aServiceName( EXPORT_SVC_NAME
);
470 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
474 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMetaOOO_createInstance(
475 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
476 throw( uno::Exception
)
479 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
480 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_META
);
483 ////////////////////////////////////////////////////////////
485 OUString SAL_CALL
SmXMLExportMeta_getImplementationName() throw()
487 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
490 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMeta_getSupportedServiceNames()
493 const OUString
aServiceName( EXPORT_SVC_NAME
);
494 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
498 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMeta_createInstance(
499 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
500 throw( uno::Exception
)
503 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
504 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_META
);
507 ////////////////////////////////////////////////////////////
509 OUString SAL_CALL
SmXMLExportSettingsOOO_getImplementationName() throw()
511 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
514 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettingsOOO_getSupportedServiceNames()
517 const OUString
aServiceName( EXPORT_SVC_NAME
);
518 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
522 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettingsOOO_createInstance(
523 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
524 throw( uno::Exception
)
527 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
528 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_SETTINGS
);
531 ////////////////////////////////////////////////////////////
533 OUString SAL_CALL
SmXMLExportSettings_getImplementationName() throw()
535 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
538 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettings_getSupportedServiceNames()
541 const OUString
aServiceName( EXPORT_SVC_NAME
);
542 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
546 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettings_createInstance(
547 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
548 throw( uno::Exception
)
551 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
552 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_SETTINGS
);
555 ////////////////////////////////////////////////////////////
557 OUString SAL_CALL
SmXMLExportContent_getImplementationName() throw()
559 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
562 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportContent_getSupportedServiceNames()
565 const OUString
aServiceName( EXPORT_SVC_NAME
);
566 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
570 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportContent_createInstance(
571 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
572 throw( uno::Exception
)
575 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
576 // The EXPORT_OASIS flag is only required to avoid that a transformer is
578 return (cppu::OWeakObject
*)new SmXMLExport( rSMgr
, EXPORT_OASIS
|EXPORT_CONTENT
);
581 ////////////////////////////////////////////////////////////
584 // override empty method from parent class
585 rtl::OUString SAL_CALL
SmXMLExport::getImplementationName()
586 throw(uno::RuntimeException
)
589 switch( getExportFlags() )
592 aTxt
= SmXMLExportMeta_getImplementationName();
594 case EXPORT_SETTINGS
:
595 aTxt
= SmXMLExportSettings_getImplementationName();
598 aTxt
= SmXMLExportContent_getImplementationName();
602 aTxt
= SmXMLExport_getImplementationName();
608 sal_uInt32
SmXMLExport::exportDoc(enum XMLTokenEnum eClass
)
610 if ( (getExportFlags() & EXPORT_CONTENT
) == 0 )
612 SvXMLExport::exportDoc( eClass
);
616 uno::Reference
<frame::XModel
> xModel
= GetModel();
617 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
618 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
619 SmModel
*pModel
= reinterpret_cast<SmModel
*>
620 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
624 SmDocShell
*pDocShell
=
625 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
626 pTree
= pDocShell
->GetFormulaTree();
627 aText
= pDocShell
->GetText();
630 GetDocHandler()->startDocument();
633 SvXMLAttributeList
&rList
= GetAttrList();
635 // make use of a default namespace
636 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)
637 _GetNamespaceMap().Add( OUString::createFromAscii(""), GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
639 rList
.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX
),
640 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX
));
642 //I think we need something like ImplExportEntities();
644 GetDocHandler()->endDocument();
651 void SmXMLExport::_ExportContent()
653 SvXMLElementExport
aEquation(*this, XML_NAMESPACE_MATH
, XML_MATH
, sal_True
, sal_True
);
654 SvXMLElementExport
*pSemantics
=0;
658 pSemantics
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
659 XML_SEMANTICS
, sal_True
, sal_True
);
662 ExportNodes(pTree
, 0);
666 // Convert symbol names
667 uno::Reference
<frame::XModel
> xModel
= GetModel();
668 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
669 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
670 SmModel
*pModel
= reinterpret_cast<SmModel
*>
671 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
672 SmDocShell
*pDocShell
= pModel
?
673 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
674 DBG_ASSERT( pDocShell
, "doc shell missing" );
677 SmParser
&rParser
= pDocShell
->GetParser();
678 BOOL bVal
= rParser
.IsExportSymbolNames();
679 rParser
.SetExportSymbolNames( TRUE
);
680 SmNode
*pTmpTree
= rParser
.Parse( aText
);
681 aText
= rParser
.GetText();
683 rParser
.SetExportSymbolNames( bVal
);
686 AddAttribute(XML_NAMESPACE_MATH
, XML_ENCODING
,
687 OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
688 SvXMLElementExport
aAnnotation(*this, XML_NAMESPACE_MATH
,
689 XML_ANNOTATION
, sal_True
, sal_False
);
690 GetDocHandler()->characters(OUString( aText
));
695 void SmXMLExport::GetViewSettings( Sequence
< PropertyValue
>& aProps
)
697 uno::Reference
<frame::XModel
> xModel
= GetModel();
701 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
702 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
703 SmModel
*pModel
= reinterpret_cast<SmModel
*>
704 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
709 SmDocShell
*pDocShell
=
710 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
715 PropertyValue
*pValue
= aProps
.getArray();
716 sal_Int32 nIndex
= 0;
718 Rectangle
aRect( pDocShell
->GetVisArea() );
720 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
721 pValue
[nIndex
++].Value
<<= aRect
.Top();
723 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
724 pValue
[nIndex
++].Value
<<= aRect
.Left();
726 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
727 pValue
[nIndex
++].Value
<<= aRect
.GetWidth();
729 pValue
[nIndex
].Name
= OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
730 pValue
[nIndex
++].Value
<<= aRect
.GetHeight();
733 void SmXMLExport::GetConfigurationSettings( Sequence
< PropertyValue
> & rProps
)
735 Reference
< XPropertySet
> xProps ( GetModel(), UNO_QUERY
);
738 Reference
< XPropertySetInfo
> xPropertySetInfo
= xProps
->getPropertySetInfo();
739 if (xPropertySetInfo
.is())
741 Sequence
< Property
> aProps
= xPropertySetInfo
->getProperties();
742 sal_Int32
nCount(aProps
.getLength());
745 rProps
.realloc(nCount
);
746 PropertyValue
* pProps
= rProps
.getArray();
749 const OUString
sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
750 const OUString
sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
751 const OUString
sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
752 const OUString
sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
753 for (sal_Int32 i
= 0; i
< nCount
; i
++, pProps
++)
755 const OUString
&rPropName
= aProps
[i
].Name
;
756 if (rPropName
!= sFormula
&&
757 rPropName
!= sBasicLibraries
&&
758 rPropName
!= sDialogLibraries
&&
759 rPropName
!= sRuntimeUID
)
761 pProps
->Name
= rPropName
;
762 pProps
->Value
= xProps
->getPropertyValue(rPropName
);
771 void SmXMLExport::ExportLine(const SmNode
*pNode
, int nLevel
)
773 ExportExpression(pNode
, nLevel
);
776 void SmXMLExport::ExportBinaryHorizontal(const SmNode
*pNode
, int nLevel
)
778 ExportExpression(pNode
, nLevel
);
781 void SmXMLExport::ExportUnaryHorizontal(const SmNode
*pNode
, int nLevel
)
783 ExportExpression(pNode
, nLevel
);
786 void SmXMLExport::ExportExpression(const SmNode
*pNode
, int nLevel
)
788 SvXMLElementExport
*pRow
=0;
789 ULONG nSize
= pNode
->GetNumSubNodes();
792 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
, sal_True
, sal_True
);
796 for (USHORT i
= 0; i
< nSize
; i
++)
797 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
798 ExportNodes(pTemp
, nLevel
+1);
803 //This saves us from situations like "a newline" where the
804 //lack of a term following the newline would otherwise create
805 //a incorrect token like <mtr/>
806 SvXMLElementExport
aDummy(*this, XML_NAMESPACE_MATH
, XML_MI
, sal_True
, sal_False
);
807 sal_Unicode nArse
[2] = {'\n','\0'};
808 GetDocHandler()->characters(nArse
);
815 void SmXMLExport::ExportBinaryVertical(const SmNode
*pNode
, int nLevel
)
817 DBG_ASSERT(pNode
->GetNumSubNodes()==3,"Bad Fraction");
818 SvXMLElementExport
aFraction(*this, XML_NAMESPACE_MATH
, XML_MFRAC
, sal_True
, sal_True
);
819 ExportNodes(pNode
->GetSubNode(0), nLevel
);
820 ExportNodes(pNode
->GetSubNode(2), nLevel
);
823 void SmXMLExport::ExportTable(const SmNode
*pNode
, int nLevel
)
825 SvXMLElementExport
*pTable
=0;
827 USHORT nSize
= pNode
->GetNumSubNodes();
829 //If the list ends in newline then the last entry has
830 //no subnodes, the newline is superfulous so we just drop
831 //the last node, inclusion would create a bad MathML
833 if (nSize
>= 1 && pNode
->GetSubNode(nSize
-1)->GetNumSubNodes() == 0)
836 // try to avoid creating a mtable element when the formula consists only
837 // of a single output line
838 if (nLevel
|| (nSize
>1))
839 pTable
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
841 for (USHORT i
= 0; i
< nSize
; i
++)
842 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
844 SvXMLElementExport
*pRow
=0;
845 SvXMLElementExport
*pCell
=0;
848 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
849 pCell
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
851 ExportNodes(pTemp
, nLevel
+1);
859 void SmXMLExport::ExportMath(const SmNode
*pNode
, int /*nLevel*/)
861 const SmMathSymbolNode
*pTemp
= static_cast<const SmMathSymbolNode
*>(pNode
);
862 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
, sal_True
, sal_False
);
863 sal_Unicode nArse
[2];
864 nArse
[0] = pTemp
->GetText().GetChar(0);
865 sal_Unicode cTmp
= ConvertMathToMathML( nArse
[0] );
868 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
870 GetDocHandler()->characters(nArse
);
873 void SmXMLExport::ExportText(const SmNode
*pNode
, int /*nLevel*/)
875 SvXMLElementExport
*pText
;
876 const SmTextNode
*pTemp
= static_cast<const SmTextNode
*>(pNode
);
877 switch (pNode
->GetToken().eType
)
882 //Note that we change the fontstyle to italic for strings that
883 //are italic and longer than a single character.
884 sal_Bool bIsItalic
= IsItalic( pTemp
->GetFont() );
885 if ((pTemp
->GetText().Len() > 1) && bIsItalic
)
886 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_ITALIC
);
887 else if ((pTemp
->GetText().Len() == 1) && !bIsItalic
)
888 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_NORMAL
);
889 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
,sal_True
,sal_False
);
893 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MN
,sal_True
,sal_False
);
896 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTEXT
,sal_True
,sal_False
);
899 GetDocHandler()->characters(OUString(pTemp
->GetText().GetBuffer()));
903 void SmXMLExport::ExportBlank(const SmNode
* /*pNode*/, int /*nLevel*/)
905 //!! exports an empty <mi> tag since for example "~_~" is allowed in
906 //!! Math (so it has no sense at all) but must not result in an empty
907 //!! <msub> tag in MathML !!
909 SvXMLElementExport
*pText
;
910 //const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
912 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
, sal_True
, sal_False
);
914 GetDocHandler()->characters( OUString() );
918 void SmXMLExport::ExportSubSupScript(const SmNode
*pNode
, int nLevel
)
920 const SmNode
*pSub
= 0;
921 const SmNode
*pSup
= 0;
922 const SmNode
*pCSub
= 0;
923 const SmNode
*pCSup
= 0;
924 const SmNode
*pLSub
= 0;
925 const SmNode
*pLSup
= 0;
926 SvXMLElementExport
*pThing
= 0, *pThing2
= 0;
928 //if we have prescripts at all then we must use the tensor notation
930 //This is one of those excellent locations where scope is vital to
931 //arrange the construction and destruction of the element helper
933 pLSub
= pNode
->GetSubNode(LSUB
+1);
934 pLSup
= pNode
->GetSubNode(LSUP
+1);
937 SvXMLElementExport
aMultiScripts(*this, XML_NAMESPACE_MATH
,
938 XML_MMULTISCRIPTS
, sal_True
, sal_True
);
941 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
942 && NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
944 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
945 XML_MUNDEROVER
, sal_True
,sal_True
);
947 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
949 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
950 XML_MUNDER
, sal_True
,sal_True
);
952 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
954 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
955 XML_MOVER
, sal_True
,sal_True
);
958 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
961 ExportNodes(pCSub
, nLevel
+1);
963 ExportNodes(pCSup
, nLevel
+1);
966 pSub
= pNode
->GetSubNode(RSUB
+1);
967 pSup
= pNode
->GetSubNode(RSUP
+1);
971 ExportNodes(pSub
, nLevel
+1);
974 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
977 ExportNodes(pSup
, nLevel
+1);
980 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
984 //Seperator element between suffix and prefix sub/sup pairs
986 SvXMLElementExport
aPrescripts(*this, XML_NAMESPACE_MATH
,
987 XML_MPRESCRIPTS
, sal_True
,sal_True
);
991 ExportNodes(pLSub
, nLevel
+1);
994 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
999 ExportNodes(pLSup
, nLevel
+1);
1002 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
1009 if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)) &&
1010 NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
1012 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1013 XML_MSUBSUP
, sal_True
,sal_True
);
1015 else if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)))
1017 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUB
,
1020 else if (NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
1022 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUP
,
1026 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
1027 && NULL
!= (pCSup
=pNode
->GetSubNode(CSUP
+1)))
1029 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1030 XML_MUNDEROVER
, sal_True
,sal_True
);
1032 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
1034 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1035 XML_MUNDER
, sal_True
,sal_True
);
1037 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
1039 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1040 XML_MOVER
, sal_True
,sal_True
);
1042 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
1045 ExportNodes(pCSub
, nLevel
+1);
1047 ExportNodes(pCSup
, nLevel
+1);
1051 ExportNodes(pSub
, nLevel
+1);
1053 ExportNodes(pSup
, nLevel
+1);
1058 void SmXMLExport::ExportBrace(const SmNode
*pNode
, int nLevel
)
1060 const SmNode
*pTemp
;
1061 const SmNode
*pLeft
=pNode
->GetSubNode(0);
1062 const SmNode
*pRight
=pNode
->GetSubNode(2);
1063 SvXMLElementExport
*pFences
=0,*pRow
=0;
1064 if ( ((pLeft
) && (pLeft
->GetToken().eType
!= TNONE
)) &&
1065 ((pRight
) && (pRight
->GetToken().eType
!= TNONE
)) &&
1066 (pNode
->GetScaleMode() == SCALE_HEIGHT
))
1068 sal_Unicode nArse
[2];
1070 nArse
[0] = static_cast<
1071 const SmMathSymbolNode
* >(pLeft
)->GetText().GetChar(0);
1072 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
1073 AddAttribute(XML_NAMESPACE_MATH
, XML_OPEN
,nArse
);
1074 nArse
[0] = static_cast<
1075 const SmMathSymbolNode
* >(pRight
)->GetText().GetChar(0);
1076 DBG_ASSERT(nArse
[0] != 0xffff,"Non existant symbol");
1077 AddAttribute(XML_NAMESPACE_MATH
, XML_CLOSE
,nArse
);
1078 pFences
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MFENCED
,
1081 else if (pLeft
&& (pLeft
->GetToken().eType
!= TNONE
))
1083 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1084 sal_True
, sal_True
);
1085 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1086 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1088 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1089 ExportNodes(pLeft
, nLevel
+1);
1092 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1093 sal_True
, sal_True
);
1095 if (NULL
!= (pTemp
= pNode
->GetSubNode(1)))
1096 ExportNodes(pTemp
, nLevel
+1);
1099 else if (pRight
&& (pRight
->GetToken().eType
!= TNONE
))
1101 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1102 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1104 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1105 ExportNodes(pRight
, nLevel
+1);
1110 void SmXMLExport::ExportRoot(const SmNode
*pNode
, int nLevel
)
1112 if (pNode
->GetSubNode(0))
1114 SvXMLElementExport
aRoot(*this, XML_NAMESPACE_MATH
, XML_MROOT
,sal_True
,
1116 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1117 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1121 SvXMLElementExport
aSqrt(*this, XML_NAMESPACE_MATH
, XML_MSQRT
,sal_True
,
1123 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1127 void SmXMLExport::ExportOperator(const SmNode
*pNode
, int nLevel
)
1129 /*we need to either use content or font and size attributes
1133 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1134 sal_True
,sal_False
);
1135 SmTextNode
*pTemp
= (SmTextNode
*)pNode
->GetSubNode(0);
1136 GetDocHandler()->characters(pTemp
->GetText());
1139 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1140 sal_True
, sal_True
);
1141 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1142 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1145 void SmXMLExport::ExportAttributes(const SmNode
*pNode
, int nLevel
)
1147 SvXMLElementExport
*pElement
=0;
1149 if (pNode
->GetToken().eType
== TUNDERLINE
)
1151 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENTUNDER
,
1153 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MUNDER
,
1156 else if (pNode
->GetToken().eType
!= TOVERSTRIKE
)
1158 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENT
,
1160 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MOVER
,
1164 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1165 switch (pNode
->GetToken().eType
)
1169 //proper entity support required
1170 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1173 GetDocHandler()->characters(
1174 OUString(RTL_CONSTASCII_USTRINGPARAM("&overbar;")));
1176 sal_Unicode nArse
[2] = {0xAF,0x00};
1178 GetDocHandler()->characters(nArse
);
1183 //proper entity support required
1184 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1187 GetDocHandler()->characters(
1188 OUString(RTL_CONSTASCII_USTRINGPARAM("&underbar;")));
1190 sal_Unicode nArse
[2] = {0x0332,0x00};
1192 GetDocHandler()->characters(nArse
);
1198 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1204 static bool lcl_HasEffectOnMathvariant( const SmTokenType eType
)
1206 return eType
== TBOLD
|| eType
== TNBOLD
||
1207 eType
== TITALIC
|| eType
== TNBOLD
||
1208 eType
== TSANS
|| eType
== TSERIF
|| eType
== TFIXED
;
1211 void SmXMLExport::ExportFont(const SmNode
*pNode
, int nLevel
)
1213 SvXMLElementExport
*pElement
= 0;
1216 // gather the mathvariant attribut relevant data from all
1217 // successively following SmFontNodes...
1219 int nBold
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1220 int nItalic
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1221 int nSansSerifFixed
= -1;
1222 SmTokenType eNodeType
= TUNKNOWN
;
1223 while (lcl_HasEffectOnMathvariant( (eNodeType
= pNode
->GetToken().eType
) ))
1227 case TBOLD
: nBold
= 1; break;
1228 case TNBOLD
: nBold
= 0; break;
1229 case TITALIC
: nItalic
= 1; break;
1230 case TNITALIC
: nItalic
= 0; break;
1231 case TSANS
: nSansSerifFixed
= 0; break;
1232 case TSERIF
: nSansSerifFixed
= 1; break;
1233 case TFIXED
: nSansSerifFixed
= 2; break;
1235 DBG_ASSERT( 0, "unexpected case" );
1237 // According to the parser every node that is to be evaluated heres
1238 // has a single non-zero subnode at index 1!! Thus we only need to check
1239 // that single node for follow-up nodes that have an effect on the attribute.
1240 if (pNode
->GetNumSubNodes() > 1 && pNode
->GetSubNode(1) &&
1241 lcl_HasEffectOnMathvariant( pNode
->GetSubNode(1)->GetToken().eType
))
1243 pNode
= pNode
->GetSubNode(1);
1249 switch (pNode
->GetToken().eType
)
1251 //wrap a phantom element around everything*/
1253 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1254 XML_MPHANTOM
, sal_True
,sal_True
);
1257 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLACK
);
1260 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_WHITE
);
1263 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_RED
);
1266 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_GREEN
);
1269 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLUE
);
1272 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_AQUA
);
1275 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_FUCHSIA
);
1278 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_YELLOW
);
1282 const SmFontNode
*pFontNode
= static_cast<const SmFontNode
*>(pNode
);
1283 const Fraction
&aFrac
= pFontNode
->GetSizeParameter();
1285 OUStringBuffer sStrBuf
;
1286 switch(pFontNode
->GetSizeType())
1288 case FNTSIZ_MULTIPLY
:
1289 SvXMLUnitConverter::convertDouble(sStrBuf
,
1290 static_cast<double>(aFrac
*Fraction(100.00)));
1291 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1294 SvXMLUnitConverter::convertDouble(sStrBuf
,
1295 static_cast<double>(Fraction(100.00)/aFrac
));
1296 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1298 case FNTSIZ_ABSOLUT
:
1299 SvXMLUnitConverter::convertDouble(sStrBuf
,
1300 static_cast<double>(aFrac
));
1302 GetXMLToken(XML_UNIT_PT
));
1306 //The problem here is that the wheels fall off because
1307 //font size is stored in 100th's of a mm not pts, and
1308 //rounding errors take their toll on the original
1309 //value specified in points.
1311 //Must fix StarMath to retain the original pt values
1312 Fraction aTemp
= Sm100th_mmToPts(pFontNode
->GetFont().
1313 GetSize().Height());
1315 if (pFontNode
->GetSizeType() == FNTSIZ_MINUS
)
1320 double mytest
= static_cast<double>(aTemp
);
1322 mytest
= ::rtl::math::round(mytest
,1);
1323 SvXMLUnitConverter::convertDouble(sStrBuf
,mytest
);
1324 sStrBuf
.append(GetXMLToken(XML_UNIT_PT
));
1329 OUString
sStr(sStrBuf
.makeStringAndClear());
1330 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHSIZE
, sStr
);
1341 // nBold: -1 = yet undefined; 0 = false; 1 = true;
1342 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
1343 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
1344 const sal_Char
*pText
= "normal";
1345 if (nSansSerifFixed
== -1 || nSansSerifFixed
== 1)
1348 if (nBold
== 1 && nItalic
!= 1)
1350 else if (nBold
!= 1 && nItalic
== 1)
1352 else if (nBold
== 1 && nItalic
== 1)
1353 pText
= "bold-italic";
1355 else if (nSansSerifFixed
== 0)
1357 pText
= "sans-serif";
1358 if (nBold
== 1 && nItalic
!= 1)
1359 pText
= "bold-sans-serif";
1360 else if (nBold
!= 1 && nItalic
== 1)
1361 pText
= "sans-serif-italic";
1362 else if (nBold
== 1 && nItalic
== 1)
1363 pText
= "sans-serif-bold-italic";
1365 else if (nSansSerifFixed
== 2)
1366 pText
= "monospace"; // no modifiers allowed for monospace ...
1369 DBG_ASSERT( 0, "unexpected case" );
1371 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, A2OU(pText
));
1379 if (pNode
->GetNumSubNodes() > 1) //or in the future is a node that
1380 //cannot take the currently supported
1383 //for now we will just always export with a style and not worry about
1384 //anyone else for the moment.
1386 //wrap a style around it
1387 SvXMLElementExport
aStyle(*this, XML_NAMESPACE_MATH
, XML_MSTYLE
, sal_True
,sal_True
);
1388 ExportExpression(pNode
, nLevel
);
1392 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1399 void SmXMLExport::ExportVerticalBrace(const SmNode
*pNode
, int nLevel
)
1401 //Place the overbrace value OVER a vertical brace and then place that
1402 //expression OVER the overbrace value, If someone can find a
1403 //dedicated term in MathML to handle this overbrace/underbrace concept
1407 switch (pNode
->GetToken().eType
)
1418 DBG_ASSERT(pNode
->GetNumSubNodes()==3,"Bad Vertical Brace");
1419 SvXMLElementExport
aOver1(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1421 // using accents will draw the over-/underbraces too close to the base
1422 // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
1423 // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
1424 // AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT, XML_TRUE);
1425 SvXMLElementExport
aOver2(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1426 ExportNodes(pNode
->GetSubNode(0), nLevel
);
1427 ExportNodes(pNode
->GetSubNode(1), nLevel
);
1429 ExportNodes(pNode
->GetSubNode(2), nLevel
);
1432 void SmXMLExport::ExportMatrix(const SmNode
*pNode
, int nLevel
)
1434 SvXMLElementExport
aTable(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
1435 const SmMatrixNode
*pMatrix
= static_cast<const SmMatrixNode
*>(pNode
);
1437 for (ULONG y
= 0; y
< pMatrix
->GetNumRows(); y
++)
1439 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
1440 for (ULONG x
= 0; x
< pMatrix
->GetNumCols(); x
++)
1441 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
++))
1443 SvXMLElementExport
aCell(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
1444 ExportNodes(pTemp
, nLevel
+1);
1449 void SmXMLExport::ExportNodes(const SmNode
*pNode
, int nLevel
)
1453 switch(pNode
->GetType())
1456 ExportTable(pNode
, nLevel
);
1461 ExportExpression(pNode
, nLevel
);
1464 ExportLine(pNode
, nLevel
);
1467 ExportText(pNode
, nLevel
);
1469 case NSPECIAL
: //NSPECIAL requires some sort of Entity preservation in the XML engine.
1470 case NGLYPH_SPECIAL
:
1473 sal_Unicode cTmp
= 0;
1474 const SmTextNode
*pTemp
= static_cast< const SmTextNode
* >(pNode
);
1475 if (pTemp
->GetText().Len() > 0)
1476 cTmp
= ConvertMathToMathML( pTemp
->GetText().GetChar(0) );
1479 // no conversion to MathML implemented -> export it as text
1480 // thus at least it will not vanish into nothing
1481 ExportText(pNode
, nLevel
);
1485 //To fully handle generic MathML we need to implement the full
1486 //operator dictionary, we will generate MathML with explicit
1487 //stretchiness for now.
1488 sal_Int16 nLength
= GetAttrList().getLength();
1489 sal_Bool bAddStretch
=sal_True
;
1490 for ( sal_Int16 i
= 0; i
< nLength
; i
++ )
1492 OUString sLocalName
;
1493 sal_uInt16 nPrefix
= GetNamespaceMap().GetKeyByAttrName(
1494 GetAttrList().getNameByIndex(i
), &sLocalName
);
1496 if ( ( XML_NAMESPACE_MATH
== nPrefix
) &&
1497 IsXMLToken(sLocalName
, XML_STRETCHY
) )
1499 bAddStretch
= sal_False
;
1505 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1507 ExportMath(pNode
, nLevel
);
1512 ExportMath(pNode
, nLevel
);
1515 ExportBinaryHorizontal(pNode
, nLevel
);
1518 ExportUnaryHorizontal(pNode
, nLevel
);
1521 ExportBrace(pNode
, nLevel
);
1524 ExportBinaryVertical(pNode
, nLevel
);
1527 ExportSubSupScript(pNode
, nLevel
);
1530 ExportRoot(pNode
, nLevel
);
1533 ExportOperator(pNode
, nLevel
);
1536 ExportAttributes(pNode
, nLevel
);
1539 ExportFont(pNode
, nLevel
);
1541 case NVERTICAL_BRACE
:
1542 ExportVerticalBrace(pNode
, nLevel
);
1545 ExportMatrix(pNode
, nLevel
);
1548 ExportBlank(pNode
, nLevel
);
1551 DBG_ASSERT( 0, "Warning: failed to export a node?" );
1557 ULONG nSize
= pNode
->GetNumSubNodes();
1558 for (ULONG i
= 0; i
< nSize
; i
++)
1559 if (SmNode
*pTemp
= pNode
->GetSubNode(i
))
1560 ExportNodes(pTemp
, nLevel
+1);
1567 ////////////////////////////////////////////////////////////