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 .
22 Warning: The SvXMLElementExport helper class creates the beginning and
23 closing tags of xml elements in its constructor and destructor, so theres
24 hidden stuff going on, on occasion the ordering of these classes declarations
29 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
30 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
31 #include <com/sun/star/xml/sax/InputSource.hpp>
32 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
33 #include <com/sun/star/xml/sax/XParser.hpp>
34 #include <com/sun/star/xml/sax/Writer.hpp>
35 #include <com/sun/star/io/XActiveDataSource.hpp>
36 #include <com/sun/star/io/XActiveDataControl.hpp>
37 #include <com/sun/star/document/XDocumentProperties.hpp>
38 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
39 #include <com/sun/star/packages/zip/ZipIOException.hpp>
40 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
41 #include <com/sun/star/beans/PropertyAttribute.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/embed/ElementModes.hpp>
44 #include <com/sun/star/util/MeasureUnit.hpp>
45 #include <com/sun/star/uno/Any.h>
47 #include <rtl/math.hxx>
48 #include <sfx2/frame.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <osl/diagnose.h>
51 #include <svtools/sfxecode.hxx>
52 #include <unotools/saveopt.hxx>
53 #include <svl/stritem.hxx>
54 #include <svl/itemprop.hxx>
55 #include <comphelper/componentcontext.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <unotools/streamwrap.hxx>
58 #include <sax/tools/converter.hxx>
59 #include <xmloff/xmlnmspe.hxx>
60 #include <xmloff/xmltoken.hxx>
61 #include <xmloff/nmspmap.hxx>
62 #include <xmloff/attrlist.hxx>
63 #include <xmloff/xmlmetai.hxx>
64 #include <osl/mutex.hxx>
65 #include <comphelper/genericpropertyset.hxx>
66 #include <comphelper/servicehelper.hxx>
70 #include "mathmlexport.hxx"
71 #include <starmath.hrc>
72 #include <unomodel.hxx>
73 #include <document.hxx>
74 #include <utility.hxx>
77 using namespace ::com::sun::star::beans
;
78 using namespace ::com::sun::star::container
;
79 using namespace ::com::sun::star::document
;
80 using namespace ::com::sun::star::lang
;
81 using namespace ::com::sun::star::uno
;
82 using namespace ::com::sun::star
;
83 using namespace ::xmloff::token
;
86 #define EXPORT_SVC_NAME "com.sun.star.xml.XMLExportFilter"
91 ////////////////////////////////////////////////////////////
93 sal_Bool
SmXMLExportWrapper::Export(SfxMedium
&rMedium
)
95 sal_Bool bRet
=sal_True
;
96 uno::Reference
<uno::XComponentContext
> xContext(comphelper::getProcessComponentContext());
99 uno::Reference
< lang::XComponent
> xModelComp(xModel
, uno::UNO_QUERY
);
101 sal_Bool bEmbedded
= sal_False
;
102 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
103 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
104 SmModel
*pModel
= reinterpret_cast<SmModel
*>
105 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
107 SmDocShell
*pDocShell
= pModel
?
108 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
110 SFX_CREATE_MODE_EMBEDDED
== pDocShell
->GetCreateMode() )
111 bEmbedded
= sal_True
;
113 uno::Reference
<task::XStatusIndicator
> xStatusIndicator
;
116 if (pDocShell
/*&& pDocShell->GetMedium()*/)
118 OSL_ENSURE( pDocShell
->GetMedium() == &rMedium
,
119 "different SfxMedium found" );
121 SfxItemSet
* pSet
= rMedium
.GetItemSet();
124 const SfxUnoAnyItem
* pItem
= static_cast<const SfxUnoAnyItem
*>(
125 pSet
->GetItem(SID_PROGRESS_STATUSBAR_CONTROL
) );
127 pItem
->GetValue() >>= xStatusIndicator
;
131 // set progress range and start status indicator
132 if (xStatusIndicator
.is())
134 sal_Int32 nProgressRange
= bFlat
? 1 : 3;
135 xStatusIndicator
->start(SM_RESSTR(STR_STATSTR_WRITING
),
141 // create XPropertySet with three properties for status indicator
142 comphelper::PropertyMapEntry aInfoMap
[] =
144 { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
145 &::getBooleanCppuType(),
146 beans::PropertyAttribute::MAYBEVOID
, 0},
147 { "BaseURI", sizeof("BaseURI")-1, 0,
148 &::getCppuType( (OUString
*)0 ),
149 beans::PropertyAttribute::MAYBEVOID
, 0 },
150 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
151 &::getCppuType( (OUString
*)0 ),
152 beans::PropertyAttribute::MAYBEVOID
, 0 },
153 { "StreamName", sizeof("StreamName")-1, 0,
154 &::getCppuType( (OUString
*)0 ),
155 beans::PropertyAttribute::MAYBEVOID
, 0 },
156 { NULL
, 0, 0, NULL
, 0, 0 }
158 uno::Reference
< beans::XPropertySet
> xInfoSet(
159 comphelper::GenericPropertySet_CreateInstance(
160 new comphelper::PropertySetInfo( aInfoMap
) ) );
162 SvtSaveOptions aSaveOpt
;
163 OUString
sUsePrettyPrinting("UsePrettyPrinting");
164 sal_Bool
bUsePrettyPrinting( bFlat
|| aSaveOpt
.IsPrettyPrinting() );
166 aAny
.setValue( &bUsePrettyPrinting
, ::getBooleanCppuType() );
167 xInfoSet
->setPropertyValue( sUsePrettyPrinting
, aAny
);
170 OUString
sPropName( "BaseURI" );
171 xInfoSet
->setPropertyValue( sPropName
, makeAny( rMedium
.GetBaseURL( true ) ) );
174 if (xStatusIndicator
.is())
175 xStatusIndicator
->setValue(nSteps
++);
176 if (!bFlat
) //Storage (Package) of Stream
178 uno::Reference
< embed::XStorage
> xStg
= rMedium
.GetOutputStorage();
179 sal_Bool bOASIS
= ( SotStorage::GetVersion( xStg
) > SOFFICE_FILEFORMAT_60
);
181 // TODO/LATER: handle the case of embedded links gracefully
182 if ( bEmbedded
) //&& !pStg->IsRoot() )
185 if ( rMedium
.GetItemSet() )
187 const SfxStringItem
* pDocHierarchItem
= static_cast<const SfxStringItem
*>(
188 rMedium
.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME
) );
189 if ( pDocHierarchItem
)
190 aName
= pDocHierarchItem
->GetValue();
193 if ( !aName
.isEmpty() )
195 sPropName
= "StreamRelPath";
196 xInfoSet
->setPropertyValue( sPropName
, makeAny( aName
) );
202 if (xStatusIndicator
.is())
203 xStatusIndicator
->setValue(nSteps
++);
205 bRet
= WriteThroughComponent(
206 xStg
, xModelComp
, "meta.xml", xContext
, xInfoSet
,
207 (bOASIS
? "com.sun.star.comp.Math.XMLOasisMetaExporter"
208 : "com.sun.star.comp.Math.XMLMetaExporter"));
212 if (xStatusIndicator
.is())
213 xStatusIndicator
->setValue(nSteps
++);
215 bRet
= WriteThroughComponent(
216 xStg
, xModelComp
, "content.xml", xContext
, xInfoSet
,
217 "com.sun.star.comp.Math.XMLContentExporter");
222 if (xStatusIndicator
.is())
223 xStatusIndicator
->setValue(nSteps
++);
225 bRet
= WriteThroughComponent(
226 xStg
, xModelComp
, "settings.xml", xContext
, xInfoSet
,
227 (bOASIS
? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
228 : "com.sun.star.comp.Math.XMLSettingsExporter") );
233 SvStream
*pStream
= rMedium
.GetOutStream();
234 uno::Reference
<io::XOutputStream
> xOut(
235 new utl::OOutputStreamWrapper(*pStream
) );
237 if (xStatusIndicator
.is())
238 xStatusIndicator
->setValue(nSteps
++);
240 bRet
= WriteThroughComponent(
241 xOut
, xModelComp
, xContext
, xInfoSet
,
242 "com.sun.star.comp.Math.XMLContentExporter");
245 if (xStatusIndicator
.is())
246 xStatusIndicator
->end();
252 /// export through an XML exporter component (output stream version)
253 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
254 Reference
<io::XOutputStream
> xOutputStream
,
255 Reference
<XComponent
> xComponent
,
256 Reference
<uno::XComponentContext
> & rxContext
,
257 Reference
<beans::XPropertySet
> & rPropSet
,
258 const sal_Char
* pComponentName
)
260 OSL_ENSURE(xOutputStream
.is(), "I really need an output stream!");
261 OSL_ENSURE(xComponent
.is(), "Need component!");
262 OSL_ENSURE(NULL
!= pComponentName
, "Need component name!");
265 Reference
< xml::sax::XWriter
> xSaxWriter
= xml::sax::Writer::create(rxContext
);
267 // connect XML writer to output stream
268 xSaxWriter
->setOutputStream( xOutputStream
);
270 // prepare arguments (prepend doc handler to given arguments)
271 Reference
<xml::sax::XDocumentHandler
> xDocHandler( xSaxWriter
,UNO_QUERY
);
273 Sequence
<Any
> aArgs( 2 );
274 aArgs
[0] <<= xDocHandler
;
275 aArgs
[1] <<= rPropSet
;
277 // get filter component
278 Reference
< document::XExporter
> xExporter(
279 rxContext
->getServiceManager()->createInstanceWithArgumentsAndContext(OUString::createFromAscii(pComponentName
), aArgs
, rxContext
),
281 OSL_ENSURE( xExporter
.is(),
282 "can't instantiate export filter component" );
283 if ( !xExporter
.is() )
287 // connect model and filter
288 xExporter
->setSourceDocument( xComponent
);
291 Reference
< XFilter
> xFilter( xExporter
, UNO_QUERY
);
292 uno::Sequence
< PropertyValue
> aProps(0);
293 xFilter
->filter( aProps
);
295 uno::Reference
<lang::XUnoTunnel
> xFilterTunnel
;
296 xFilterTunnel
= uno::Reference
<lang::XUnoTunnel
>
297 ( xFilter
, uno::UNO_QUERY
);
298 SmXMLExport
*pFilter
= reinterpret_cast< SmXMLExport
* >(
299 sal::static_int_cast
< sal_uIntPtr
>(
300 xFilterTunnel
->getSomething( SmXMLExport::getUnoTunnelId() )));
301 return pFilter
? pFilter
->GetSuccess() : sal_True
;
305 /// export through an XML exporter component (storage version)
306 sal_Bool
SmXMLExportWrapper::WriteThroughComponent(
307 const Reference
< embed::XStorage
>& xStorage
,
308 Reference
<XComponent
> xComponent
,
309 const sal_Char
* pStreamName
,
310 Reference
<uno::XComponentContext
> & rxContext
,
311 Reference
<beans::XPropertySet
> & rPropSet
,
312 const sal_Char
* pComponentName
315 OSL_ENSURE(xStorage
.is(), "Need storage!");
316 OSL_ENSURE(NULL
!= pStreamName
, "Need stream name!");
319 Reference
< io::XStream
> xStream
;
320 OUString sStreamName
= OUString::createFromAscii(pStreamName
);
323 xStream
= xStorage
->openStreamElement( sStreamName
,
324 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
326 catch ( uno::Exception
& )
328 OSL_FAIL( "Can't create output stream in package!" );
332 OUString
aPropName( "MediaType" );
333 OUString
aMime( "text/xml" );
337 uno::Reference
< beans::XPropertySet
> xSet( xStream
, uno::UNO_QUERY
);
338 xSet
->setPropertyValue( aPropName
, aAny
);
340 // all streams must be encrypted in encrypted document
341 OUString
aTmpPropName( "UseCommonStoragePasswordEncryption" );
342 sal_Bool bTrue
= sal_True
;
343 aAny
.setValue( &bTrue
, ::getBooleanCppuType() );
344 xSet
->setPropertyValue( aTmpPropName
, aAny
);
349 OUString
sPropName( "StreamName" );
350 rPropSet
->setPropertyValue( sPropName
, makeAny( sStreamName
) );
354 sal_Bool bRet
= WriteThroughComponent( xStream
->getOutputStream(), xComponent
, rxContext
,
355 rPropSet
, pComponentName
);
360 ////////////////////////////////////////////////////////////
362 SmXMLExport::SmXMLExport(
363 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XComponentContext
> xContext
,
364 sal_uInt16 nExportFlags
)
365 : SvXMLExport(util::MeasureUnit::INCH
, xContext
, XML_MATH
,
372 sal_Int64 SAL_CALL
SmXMLExport::getSomething(
373 const uno::Sequence
< sal_Int8
>& rId
)
374 throw(uno::RuntimeException
)
376 if ( rId
.getLength() == 16 &&
377 0 == memcmp( getUnoTunnelId().getConstArray(),
378 rId
.getConstArray(), 16 ) )
379 return sal::static_int_cast
< sal_Int64
>(reinterpret_cast< sal_uIntPtr
>(this));
381 return SvXMLExport::getSomething( rId
);
386 class theSmXMLExportUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theSmXMLExportUnoTunnelId
> {};
389 const uno::Sequence
< sal_Int8
> & SmXMLExport::getUnoTunnelId() throw()
391 return theSmXMLExportUnoTunnelId::get().getSeq();
394 OUString SAL_CALL
SmXMLExport_getImplementationName() throw()
396 return OUString( "com.sun.star.comp.Math.XMLExporter" );
399 uno::Sequence
< OUString
> SAL_CALL
SmXMLExport_getSupportedServiceNames()
402 const OUString
aServiceName( EXPORT_SVC_NAME
);
403 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
407 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExport_createInstance(
408 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
409 throw( uno::Exception
)
411 // EXPORT_OASIS is required here allthough there is no differrence between
412 // OOo and OASIS, because without the flag, a transformation to OOo would
414 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_OASIS
|EXPORT_ALL
);
417 ////////////////////////////////////////////////////////////
419 OUString SAL_CALL
SmXMLExportMetaOOO_getImplementationName() throw()
421 return OUString( "com.sun.star.comp.Math.XMLMetaExporter" );
424 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMetaOOO_getSupportedServiceNames()
427 const OUString
aServiceName( EXPORT_SVC_NAME
);
428 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
432 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMetaOOO_createInstance(
433 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
434 throw( uno::Exception
)
436 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_META
);
439 ////////////////////////////////////////////////////////////
441 OUString SAL_CALL
SmXMLExportMeta_getImplementationName() throw()
443 return OUString( "com.sun.star.comp.Math.XMLOasisMetaExporter" );
446 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportMeta_getSupportedServiceNames()
449 const OUString
aServiceName( EXPORT_SVC_NAME
);
450 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
454 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportMeta_createInstance(
455 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
456 throw( uno::Exception
)
458 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_OASIS
|EXPORT_META
);
461 ////////////////////////////////////////////////////////////
463 OUString SAL_CALL
SmXMLExportSettingsOOO_getImplementationName() throw()
465 return OUString( "com.sun.star.comp.Math.XMLSettingsExporter" );
468 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettingsOOO_getSupportedServiceNames()
471 const OUString
aServiceName( EXPORT_SVC_NAME
);
472 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
476 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettingsOOO_createInstance(
477 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
478 throw( uno::Exception
)
480 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_SETTINGS
);
483 ////////////////////////////////////////////////////////////
485 OUString SAL_CALL
SmXMLExportSettings_getImplementationName() throw()
487 return OUString( "com.sun.star.comp.Math.XMLOasisSettingsExporter" );
490 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportSettings_getSupportedServiceNames()
493 const OUString
aServiceName( EXPORT_SVC_NAME
);
494 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
498 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportSettings_createInstance(
499 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
500 throw( uno::Exception
)
502 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_OASIS
|EXPORT_SETTINGS
);
505 ////////////////////////////////////////////////////////////
507 OUString SAL_CALL
SmXMLExportContent_getImplementationName() throw()
509 return OUString( "com.sun.star.comp.Math.XMLContentExporter" );
512 uno::Sequence
< OUString
> SAL_CALL
SmXMLExportContent_getSupportedServiceNames()
515 const OUString
aServiceName( EXPORT_SVC_NAME
);
516 const uno::Sequence
< OUString
> aSeq( &aServiceName
, 1 );
520 uno::Reference
< uno::XInterface
> SAL_CALL
SmXMLExportContent_createInstance(
521 const uno::Reference
< lang::XMultiServiceFactory
> & rSMgr
)
522 throw( uno::Exception
)
524 // The EXPORT_OASIS flag is only required to avoid that a transformer is
526 return (cppu::OWeakObject
*)new SmXMLExport( comphelper::getComponentContext(rSMgr
), EXPORT_OASIS
|EXPORT_CONTENT
);
529 ////////////////////////////////////////////////////////////
532 // override empty method from parent class
533 OUString SAL_CALL
SmXMLExport::getImplementationName()
534 throw(uno::RuntimeException
)
537 switch( getExportFlags() )
540 aTxt
= SmXMLExportMeta_getImplementationName();
542 case EXPORT_SETTINGS
:
543 aTxt
= SmXMLExportSettings_getImplementationName();
546 aTxt
= SmXMLExportContent_getImplementationName();
550 aTxt
= SmXMLExport_getImplementationName();
556 sal_uInt32
SmXMLExport::exportDoc(enum XMLTokenEnum eClass
)
558 if ( (getExportFlags() & EXPORT_CONTENT
) == 0 )
560 SvXMLExport::exportDoc( eClass
);
564 uno::Reference
<frame::XModel
> xModel
= GetModel();
565 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
566 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
567 SmModel
*pModel
= reinterpret_cast<SmModel
*>
568 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
572 SmDocShell
*pDocShell
=
573 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
574 pTree
= pDocShell
->GetFormulaTree();
575 aText
= pDocShell
->GetText();
578 GetDocHandler()->startDocument();
580 addChaffWhenEncryptedStorage();
583 SvXMLAttributeList
&rList
= GetAttrList();
585 // make use of a default namespace
586 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)
587 _GetNamespaceMap().Add( OUString(), GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
589 rList
.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX
),
590 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX
));
592 //I think we need something like ImplExportEntities();
594 GetDocHandler()->endDocument();
601 void SmXMLExport::_ExportContent()
603 SvXMLElementExport
aEquation(*this, XML_NAMESPACE_MATH
, XML_MATH
, sal_True
, sal_True
);
604 SvXMLElementExport
*pSemantics
=0;
608 pSemantics
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
609 XML_SEMANTICS
, sal_True
, sal_True
);
612 ExportNodes(pTree
, 0);
616 // Convert symbol names
617 uno::Reference
<frame::XModel
> xModel
= GetModel();
618 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
619 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
620 SmModel
*pModel
= reinterpret_cast<SmModel
*>
621 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
622 SmDocShell
*pDocShell
= pModel
?
623 static_cast<SmDocShell
*>(pModel
->GetObjectShell()) : 0;
624 OSL_ENSURE( pDocShell
, "doc shell missing" );
627 SmParser
&rParser
= pDocShell
->GetParser();
628 bool bVal
= rParser
.IsExportSymbolNames();
629 rParser
.SetExportSymbolNames( true );
630 SmNode
*pTmpTree
= rParser
.Parse( aText
);
631 aText
= rParser
.GetText();
633 rParser
.SetExportSymbolNames( bVal
);
636 AddAttribute(XML_NAMESPACE_MATH
, XML_ENCODING
,
637 OUString("StarMath 5.0"));
638 SvXMLElementExport
aAnnotation(*this, XML_NAMESPACE_MATH
,
639 XML_ANNOTATION
, sal_True
, sal_False
);
640 GetDocHandler()->characters(OUString( aText
));
645 void SmXMLExport::GetViewSettings( Sequence
< PropertyValue
>& aProps
)
647 uno::Reference
<frame::XModel
> xModel
= GetModel();
651 uno::Reference
<lang::XUnoTunnel
> xTunnel
;
652 xTunnel
= uno::Reference
<lang::XUnoTunnel
> (xModel
,uno::UNO_QUERY
);
653 SmModel
*pModel
= reinterpret_cast<SmModel
*>
654 (xTunnel
->getSomething(SmModel::getUnoTunnelId()));
659 SmDocShell
*pDocShell
=
660 static_cast<SmDocShell
*>(pModel
->GetObjectShell());
665 PropertyValue
*pValue
= aProps
.getArray();
666 sal_Int32 nIndex
= 0;
668 Rectangle
aRect( pDocShell
->GetVisArea() );
670 pValue
[nIndex
].Name
= "ViewAreaTop";
671 pValue
[nIndex
++].Value
<<= aRect
.Top();
673 pValue
[nIndex
].Name
= "ViewAreaLeft";
674 pValue
[nIndex
++].Value
<<= aRect
.Left();
676 pValue
[nIndex
].Name
= "ViewAreaWidth";
677 pValue
[nIndex
++].Value
<<= aRect
.GetWidth();
679 pValue
[nIndex
].Name
= "ViewAreaHeight";
680 pValue
[nIndex
++].Value
<<= aRect
.GetHeight();
683 void SmXMLExport::GetConfigurationSettings( Sequence
< PropertyValue
> & rProps
)
685 Reference
< XPropertySet
> xProps ( GetModel(), UNO_QUERY
);
688 Reference
< XPropertySetInfo
> xPropertySetInfo
= xProps
->getPropertySetInfo();
689 if (xPropertySetInfo
.is())
691 Sequence
< Property
> aProps
= xPropertySetInfo
->getProperties();
692 sal_Int32
nCount(aProps
.getLength());
695 rProps
.realloc(nCount
);
696 PropertyValue
* pProps
= rProps
.getArray();
699 SmConfig
*pConfig
= SM_MOD()->GetConfig();
700 const bool bUsedSymbolsOnly
= pConfig
? pConfig
->IsSaveOnlyUsedSymbols() : false;
702 const OUString
sFormula ( "Formula" );
703 const OUString
sBasicLibraries ( "BasicLibraries" );
704 const OUString
sDialogLibraries ( "DialogLibraries" );
705 const OUString
sRuntimeUID ( "RuntimeUID" );
706 for (sal_Int32 i
= 0; i
< nCount
; i
++, pProps
++)
708 const OUString
&rPropName
= aProps
[i
].Name
;
709 if (rPropName
!= sFormula
&&
710 rPropName
!= sBasicLibraries
&&
711 rPropName
!= sDialogLibraries
&&
712 rPropName
!= sRuntimeUID
)
714 pProps
->Name
= rPropName
;
716 OUString
aActualName( rPropName
);
718 // handle 'save used symbols only'
719 if (bUsedSymbolsOnly
&& rPropName
== "Symbols" )
720 aActualName
= "UserDefinedSymbolsInUse";
722 pProps
->Value
= xProps
->getPropertyValue( aActualName
);
731 void SmXMLExport::ExportLine(const SmNode
*pNode
, int nLevel
)
733 ExportExpression(pNode
, nLevel
);
736 void SmXMLExport::ExportBinaryHorizontal(const SmNode
*pNode
, int nLevel
)
738 ExportExpression(pNode
, nLevel
);
741 void SmXMLExport::ExportUnaryHorizontal(const SmNode
*pNode
, int nLevel
)
743 ExportExpression(pNode
, nLevel
);
746 void SmXMLExport::ExportExpression(const SmNode
*pNode
, int nLevel
)
748 SvXMLElementExport
*pRow
=0;
749 sal_uLong nSize
= pNode
->GetNumSubNodes();
751 // #i115443: nodes of type expression always need to be grouped with mrow statement
752 if (nSize
> 1 || (pNode
&& pNode
->GetType() == NEXPRESSION
))
753 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
, sal_True
, sal_True
);
755 for (sal_uInt16 i
= 0; i
< nSize
; i
++)
756 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
757 ExportNodes(pTemp
, nLevel
+1);
762 void SmXMLExport::ExportBinaryVertical(const SmNode
*pNode
, int nLevel
)
764 OSL_ENSURE(pNode
->GetNumSubNodes()==3,"Bad Fraction");
765 SvXMLElementExport
aFraction(*this, XML_NAMESPACE_MATH
, XML_MFRAC
, sal_True
, sal_True
);
766 ExportNodes(pNode
->GetSubNode(0), nLevel
);
767 ExportNodes(pNode
->GetSubNode(2), nLevel
);
770 void SmXMLExport::ExportTable(const SmNode
*pNode
, int nLevel
)
772 SvXMLElementExport
*pTable
=0;
774 sal_uInt16 nSize
= pNode
->GetNumSubNodes();
776 //If the list ends in newline then the last entry has
777 //no subnodes, the newline is superfulous so we just drop
778 //the last node, inclusion would create a bad MathML
780 if (nSize
>= 1 && pNode
->GetSubNode(nSize
-1)->GetNumSubNodes() == 0)
783 // try to avoid creating a mtable element when the formula consists only
784 // of a single output line
785 if (nLevel
|| (nSize
>1))
786 pTable
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
788 for (sal_uInt16 i
= 0; i
< nSize
; i
++)
789 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
))
791 SvXMLElementExport
*pRow
=0;
792 SvXMLElementExport
*pCell
=0;
795 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
796 pCell
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
798 ExportNodes(pTemp
, nLevel
+1);
806 void SmXMLExport::ExportMath(const SmNode
*pNode
, int /*nLevel*/)
808 const SmMathSymbolNode
*pTemp
= static_cast<const SmMathSymbolNode
*>(pNode
);
809 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
, sal_True
, sal_False
);
810 sal_Unicode nArse
[2];
811 nArse
[0] = pTemp
->GetText()[0];
812 sal_Unicode cTmp
= ConvertMathToMathML( nArse
[0] );
815 OSL_ENSURE(nArse
[0] != 0xffff,"Non existent symbol");
817 GetDocHandler()->characters(nArse
);
820 void SmXMLExport::ExportText(const SmNode
*pNode
, int /*nLevel*/)
822 SvXMLElementExport
*pText
;
823 const SmTextNode
*pTemp
= static_cast<const SmTextNode
*>(pNode
);
824 switch (pNode
->GetToken().eType
)
829 //Note that we change the fontstyle to italic for strings that
830 //are italic and longer than a single character.
831 sal_Bool bIsItalic
= IsItalic( pTemp
->GetFont() );
832 if ((pTemp
->GetText().getLength() > 1) && bIsItalic
)
833 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_ITALIC
);
834 else if ((pTemp
->GetText().getLength() == 1) && !bIsItalic
)
835 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, XML_NORMAL
);
836 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
,sal_True
,sal_False
);
840 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MN
,sal_True
,sal_False
);
843 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MTEXT
,sal_True
,sal_False
);
846 GetDocHandler()->characters(pTemp
->GetText());
850 void SmXMLExport::ExportBlank(const SmNode
* /*pNode*/, int /*nLevel*/)
852 //!! exports an empty <mi> tag since for example "~_~" is allowed in
853 //!! Math (so it has no sense at all) but must not result in an empty
854 //!! <msub> tag in MathML !!
856 SvXMLElementExport
*pText
;
858 pText
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MI
, sal_True
, sal_False
);
860 GetDocHandler()->characters( OUString() );
864 void SmXMLExport::ExportSubSupScript(const SmNode
*pNode
, int nLevel
)
866 const SmNode
*pSub
= 0;
867 const SmNode
*pSup
= 0;
868 const SmNode
*pCSub
= 0;
869 const SmNode
*pCSup
= 0;
870 const SmNode
*pLSub
= 0;
871 const SmNode
*pLSup
= 0;
872 SvXMLElementExport
*pThing
= 0, *pThing2
= 0;
874 //if we have prescripts at all then we must use the tensor notation
876 //This is one of those excellent locations where scope is vital to
877 //arrange the construction and destruction of the element helper
879 pLSub
= pNode
->GetSubNode(LSUB
+1);
880 pLSup
= pNode
->GetSubNode(LSUP
+1);
883 SvXMLElementExport
aMultiScripts(*this, XML_NAMESPACE_MATH
,
884 XML_MMULTISCRIPTS
, sal_True
, sal_True
);
887 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
888 && NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
890 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
891 XML_MUNDEROVER
, sal_True
,sal_True
);
893 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
895 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
896 XML_MUNDER
, sal_True
,sal_True
);
898 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
900 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
901 XML_MOVER
, sal_True
,sal_True
);
904 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
907 ExportNodes(pCSub
, nLevel
+1);
909 ExportNodes(pCSup
, nLevel
+1);
912 pSub
= pNode
->GetSubNode(RSUB
+1);
913 pSup
= pNode
->GetSubNode(RSUP
+1);
917 ExportNodes(pSub
, nLevel
+1);
920 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
923 ExportNodes(pSup
, nLevel
+1);
926 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,sal_True
,sal_True
);
930 //Separator element between suffix and prefix sub/sup pairs
932 SvXMLElementExport
aPrescripts(*this, XML_NAMESPACE_MATH
,
933 XML_MPRESCRIPTS
, sal_True
,sal_True
);
937 ExportNodes(pLSub
, nLevel
+1);
940 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
945 ExportNodes(pLSup
, nLevel
+1);
948 SvXMLElementExport
aNone(*this, XML_NAMESPACE_MATH
, XML_NONE
,
955 if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)) &&
956 NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
958 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
959 XML_MSUBSUP
, sal_True
,sal_True
);
961 else if (NULL
!= (pSub
= pNode
->GetSubNode(RSUB
+1)))
963 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUB
,
966 else if (NULL
!= (pSup
= pNode
->GetSubNode(RSUP
+1)))
968 pThing
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MSUP
,
972 if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1))
973 && NULL
!= (pCSup
=pNode
->GetSubNode(CSUP
+1)))
975 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
976 XML_MUNDEROVER
, sal_True
,sal_True
);
978 else if (NULL
!= (pCSub
= pNode
->GetSubNode(CSUB
+1)))
980 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
981 XML_MUNDER
, sal_True
,sal_True
);
983 else if (NULL
!= (pCSup
= pNode
->GetSubNode(CSUP
+1)))
985 pThing2
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
986 XML_MOVER
, sal_True
,sal_True
);
988 ExportNodes(pNode
->GetSubNode(0), nLevel
+1); //Main Term
991 ExportNodes(pCSub
, nLevel
+1);
993 ExportNodes(pCSup
, nLevel
+1);
997 ExportNodes(pSub
, nLevel
+1);
999 ExportNodes(pSup
, nLevel
+1);
1004 void SmXMLExport::ExportBrace(const SmNode
*pNode
, int nLevel
)
1006 const SmNode
*pTemp
;
1007 const SmNode
*pLeft
=pNode
->GetSubNode(0);
1008 const SmNode
*pRight
=pNode
->GetSubNode(2);
1009 SvXMLElementExport
*pFences
=0,*pRow
=0;
1010 if ( ((pLeft
) && (pLeft
->GetToken().eType
!= TNONE
)) &&
1011 ((pRight
) && (pRight
->GetToken().eType
!= TNONE
)) &&
1012 (pNode
->GetScaleMode() == SCALE_HEIGHT
))
1014 sal_Unicode nArse
[2];
1016 nArse
[0] = static_cast<
1017 const SmMathSymbolNode
* >(pLeft
)->GetText()[0];
1018 OSL_ENSURE(nArse
[0] != 0xffff,"Non existent symbol");
1019 AddAttribute(XML_NAMESPACE_MATH
, XML_OPEN
,nArse
);
1020 nArse
[0] = static_cast<
1021 const SmMathSymbolNode
* >(pRight
)->GetText()[0];
1022 OSL_ENSURE(nArse
[0] != 0xffff,"Non existent symbol");
1023 AddAttribute(XML_NAMESPACE_MATH
, XML_CLOSE
,nArse
);
1024 pFences
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MFENCED
,
1027 else if (pLeft
&& (pLeft
->GetToken().eType
!= TNONE
))
1029 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1030 sal_True
, sal_True
);
1031 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1032 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1034 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1035 ExportNodes(pLeft
, nLevel
+1);
1038 pRow
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1039 sal_True
, sal_True
);
1041 if (NULL
!= (pTemp
= pNode
->GetSubNode(1)))
1042 ExportNodes(pTemp
, nLevel
+1);
1045 else if (pRight
&& (pRight
->GetToken().eType
!= TNONE
))
1047 if (pNode
->GetScaleMode() == SCALE_HEIGHT
)
1048 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_TRUE
);
1050 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1051 ExportNodes(pRight
, nLevel
+1);
1056 void SmXMLExport::ExportRoot(const SmNode
*pNode
, int nLevel
)
1058 if (pNode
->GetSubNode(0))
1060 SvXMLElementExport
aRoot(*this, XML_NAMESPACE_MATH
, XML_MROOT
,sal_True
,
1062 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1063 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1067 SvXMLElementExport
aSqrt(*this, XML_NAMESPACE_MATH
, XML_MSQRT
,sal_True
,
1069 ExportNodes(pNode
->GetSubNode(2), nLevel
+1);
1073 void SmXMLExport::ExportOperator(const SmNode
*pNode
, int nLevel
)
1075 /*we need to either use content or font and size attributes
1077 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MROW
,
1078 sal_True
, sal_True
);
1079 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1080 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1083 void SmXMLExport::ExportAttributes(const SmNode
*pNode
, int nLevel
)
1085 SvXMLElementExport
*pElement
=0;
1087 if (pNode
->GetToken().eType
== TUNDERLINE
)
1089 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENTUNDER
,
1091 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MUNDER
,
1094 else if (pNode
->GetToken().eType
!= TOVERSTRIKE
)
1096 AddAttribute(XML_NAMESPACE_MATH
, XML_ACCENT
,
1098 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
, XML_MOVER
,
1102 ExportNodes(pNode
->GetSubNode(1), nLevel
+1);
1103 switch (pNode
->GetToken().eType
)
1107 //proper entity support required
1108 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1110 sal_Unicode nArse
[2] = {0xAF,0x00};
1111 GetDocHandler()->characters(nArse
);
1116 //proper entity support required
1117 SvXMLElementExport
aMath(*this, XML_NAMESPACE_MATH
, XML_MO
,
1119 sal_Unicode nArse
[2] = {0x0332,0x00};
1120 GetDocHandler()->characters(nArse
);
1126 ExportNodes(pNode
->GetSubNode(0), nLevel
+1);
1132 static bool lcl_HasEffectOnMathvariant( const SmTokenType eType
)
1134 return eType
== TBOLD
|| eType
== TNBOLD
||
1135 eType
== TITALIC
|| eType
== TNITALIC
||
1136 eType
== TSANS
|| eType
== TSERIF
|| eType
== TFIXED
;
1139 void SmXMLExport::ExportFont(const SmNode
*pNode
, int nLevel
)
1141 SvXMLElementExport
*pElement
= 0;
1144 // gather the mathvariant attribut relevant data from all
1145 // successively following SmFontNodes...
1147 int nBold
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1148 int nItalic
= -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1149 int nSansSerifFixed
= -1;
1150 SmTokenType eNodeType
= TUNKNOWN
;
1151 while (lcl_HasEffectOnMathvariant( (eNodeType
= pNode
->GetToken().eType
) ))
1155 case TBOLD
: nBold
= 1; break;
1156 case TNBOLD
: nBold
= 0; break;
1157 case TITALIC
: nItalic
= 1; break;
1158 case TNITALIC
: nItalic
= 0; break;
1159 case TSANS
: nSansSerifFixed
= 0; break;
1160 case TSERIF
: nSansSerifFixed
= 1; break;
1161 case TFIXED
: nSansSerifFixed
= 2; break;
1163 OSL_FAIL( "unexpected case" );
1165 // According to the parser every node that is to be evaluated heres
1166 // has a single non-zero subnode at index 1!! Thus we only need to check
1167 // that single node for follow-up nodes that have an effect on the attribute.
1168 if (pNode
->GetNumSubNodes() > 1 && pNode
->GetSubNode(1) &&
1169 lcl_HasEffectOnMathvariant( pNode
->GetSubNode(1)->GetToken().eType
))
1171 pNode
= pNode
->GetSubNode(1);
1177 switch (pNode
->GetToken().eType
)
1179 //wrap a phantom element around everything*/
1181 pElement
= new SvXMLElementExport(*this, XML_NAMESPACE_MATH
,
1182 XML_MPHANTOM
, sal_True
,sal_True
);
1185 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLACK
);
1188 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_WHITE
);
1191 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_RED
);
1194 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_GREEN
);
1197 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_BLUE
);
1200 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_AQUA
);
1203 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_FUCHSIA
);
1206 AddAttribute(XML_NAMESPACE_MATH
, XML_COLOR
, XML_YELLOW
);
1210 const SmFontNode
*pFontNode
= static_cast<const SmFontNode
*>(pNode
);
1211 const Fraction
&aFrac
= pFontNode
->GetSizeParameter();
1213 OUStringBuffer sStrBuf
;
1214 switch(pFontNode
->GetSizeType())
1216 case FNTSIZ_MULTIPLY
:
1217 ::sax::Converter::convertDouble(sStrBuf
,
1218 static_cast<double>(aFrac
*Fraction(100.00)));
1219 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1222 ::sax::Converter::convertDouble(sStrBuf
,
1223 static_cast<double>(Fraction(100.00)/aFrac
));
1224 sStrBuf
.append(static_cast<sal_Unicode
>('%'));
1226 case FNTSIZ_ABSOLUT
:
1227 ::sax::Converter::convertDouble(sStrBuf
,
1228 static_cast<double>(aFrac
));
1230 GetXMLToken(XML_UNIT_PT
));
1234 //The problem here is that the wheels fall off because
1235 //font size is stored in 100th's of a mm not pts, and
1236 //rounding errors take their toll on the original
1237 //value specified in points.
1239 //Must fix StarMath to retain the original pt values
1240 Fraction aTemp
= Sm100th_mmToPts(pFontNode
->GetFont().
1241 GetSize().Height());
1243 if (pFontNode
->GetSizeType() == FNTSIZ_MINUS
)
1248 double mytest
= static_cast<double>(aTemp
);
1250 mytest
= ::rtl::math::round(mytest
,1);
1251 ::sax::Converter::convertDouble(sStrBuf
,mytest
);
1252 sStrBuf
.append(GetXMLToken(XML_UNIT_PT
));
1257 OUString
sStr(sStrBuf
.makeStringAndClear());
1258 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHSIZE
, sStr
);
1269 // nBold: -1 = yet undefined; 0 = false; 1 = true;
1270 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
1271 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
1272 const sal_Char
*pText
= "normal";
1273 if (nSansSerifFixed
== -1 || nSansSerifFixed
== 1)
1276 if (nBold
== 1 && nItalic
!= 1)
1278 else if (nBold
!= 1 && nItalic
== 1)
1280 else if (nBold
== 1 && nItalic
== 1)
1281 pText
= "bold-italic";
1283 else if (nSansSerifFixed
== 0)
1285 pText
= "sans-serif";
1286 if (nBold
== 1 && nItalic
!= 1)
1287 pText
= "bold-sans-serif";
1288 else if (nBold
!= 1 && nItalic
== 1)
1289 pText
= "sans-serif-italic";
1290 else if (nBold
== 1 && nItalic
== 1)
1291 pText
= "sans-serif-bold-italic";
1293 else if (nSansSerifFixed
== 2)
1294 pText
= "monospace"; // no modifiers allowed for monospace ...
1297 OSL_FAIL( "unexpected case" );
1299 AddAttribute(XML_NAMESPACE_MATH
, XML_MATHVARIANT
, OUString::createFromAscii( pText
));
1306 //for now we will just always export with a style and not worry about
1307 //anyone else for the moment.
1309 //wrap a style around it
1310 SvXMLElementExport
aStyle(*this, XML_NAMESPACE_MATH
, XML_MSTYLE
, sal_True
,sal_True
);
1311 ExportExpression(pNode
, nLevel
);
1318 void SmXMLExport::ExportVerticalBrace(const SmNode
*pNode
, int nLevel
)
1320 //Place the overbrace value OVER a vertical brace and then place that
1321 //expression OVER the overbrace value, If someone can find a
1322 //dedicated term in MathML to handle this overbrace/underbrace concept
1326 switch (pNode
->GetToken().eType
)
1337 OSL_ENSURE(pNode
->GetNumSubNodes()==3,"Bad Vertical Brace");
1338 SvXMLElementExport
aOver1(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1340 // using accents will draw the over-/underbraces too close to the base
1341 // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
1342 // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
1343 SvXMLElementExport
aOver2(*this, XML_NAMESPACE_MATH
,which
, sal_True
, sal_True
);
1344 ExportNodes(pNode
->GetSubNode(0), nLevel
);
1345 ExportNodes(pNode
->GetSubNode(1), nLevel
);
1347 ExportNodes(pNode
->GetSubNode(2), nLevel
);
1350 void SmXMLExport::ExportMatrix(const SmNode
*pNode
, int nLevel
)
1352 SvXMLElementExport
aTable(*this, XML_NAMESPACE_MATH
, XML_MTABLE
, sal_True
, sal_True
);
1353 const SmMatrixNode
*pMatrix
= static_cast<const SmMatrixNode
*>(pNode
);
1355 for (sal_uLong y
= 0; y
< pMatrix
->GetNumRows(); y
++)
1357 SvXMLElementExport
aRow(*this, XML_NAMESPACE_MATH
, XML_MTR
, sal_True
, sal_True
);
1358 for (sal_uLong x
= 0; x
< pMatrix
->GetNumCols(); x
++)
1359 if (const SmNode
*pTemp
= pNode
->GetSubNode(i
++))
1361 SvXMLElementExport
aCell(*this, XML_NAMESPACE_MATH
, XML_MTD
, sal_True
, sal_True
);
1362 ExportNodes(pTemp
, nLevel
+1);
1367 void SmXMLExport::ExportNodes(const SmNode
*pNode
, int nLevel
)
1371 switch(pNode
->GetType())
1374 ExportTable(pNode
, nLevel
);
1379 ExportExpression(pNode
, nLevel
);
1382 ExportLine(pNode
, nLevel
);
1385 ExportText(pNode
, nLevel
);
1387 case NSPECIAL
: //NSPECIAL requires some sort of Entity preservation in the XML engine.
1388 case NGLYPH_SPECIAL
:
1391 sal_Unicode cTmp
= 0;
1392 const SmTextNode
*pTemp
= static_cast< const SmTextNode
* >(pNode
);
1393 if (!pTemp
->GetText().isEmpty())
1394 cTmp
= ConvertMathToMathML( pTemp
->GetText()[0] );
1397 // no conversion to MathML implemented -> export it as text
1398 // thus at least it will not vanish into nothing
1399 ExportText(pNode
, nLevel
);
1403 //To fully handle generic MathML we need to implement the full
1404 //operator dictionary, we will generate MathML with explicit
1405 //stretchiness for now.
1406 sal_Int16 nLength
= GetAttrList().getLength();
1407 sal_Bool bAddStretch
=sal_True
;
1408 for ( sal_Int16 i
= 0; i
< nLength
; i
++ )
1410 OUString sLocalName
;
1411 sal_uInt16 nPrefix
= GetNamespaceMap().GetKeyByAttrName(
1412 GetAttrList().getNameByIndex(i
), &sLocalName
);
1414 if ( ( XML_NAMESPACE_MATH
== nPrefix
) &&
1415 IsXMLToken(sLocalName
, XML_STRETCHY
) )
1417 bAddStretch
= sal_False
;
1423 AddAttribute(XML_NAMESPACE_MATH
, XML_STRETCHY
, XML_FALSE
);
1425 ExportMath(pNode
, nLevel
);
1430 ExportMath(pNode
, nLevel
);
1433 ExportBinaryHorizontal(pNode
, nLevel
);
1436 ExportUnaryHorizontal(pNode
, nLevel
);
1439 ExportBrace(pNode
, nLevel
);
1442 ExportBinaryVertical(pNode
, nLevel
);
1445 ExportSubSupScript(pNode
, nLevel
);
1448 ExportRoot(pNode
, nLevel
);
1451 ExportOperator(pNode
, nLevel
);
1454 ExportAttributes(pNode
, nLevel
);
1457 ExportFont(pNode
, nLevel
);
1459 case NVERTICAL_BRACE
:
1460 ExportVerticalBrace(pNode
, nLevel
);
1463 ExportMatrix(pNode
, nLevel
);
1466 ExportBlank(pNode
, nLevel
);
1469 OSL_FAIL( "Warning: failed to export a node?" );
1475 ////////////////////////////////////////////////////////////
1477 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */