summaryrefslogtreecommitdiffstats
path: root/include/oox/mathml
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /include/oox/mathml
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/oox/mathml')
-rw-r--r--include/oox/mathml/imexport.hxx62
-rw-r--r--include/oox/mathml/importutils.hxx255
2 files changed, 317 insertions, 0 deletions
diff --git a/include/oox/mathml/imexport.hxx b/include/oox/mathml/imexport.hxx
new file mode 100644
index 0000000000..c77689166d
--- /dev/null
+++ b/include/oox/mathml/imexport.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_OOX_MATHML_IMEXPORT_HXX
+#define INCLUDED_OOX_MATHML_IMEXPORT_HXX
+
+#include <oox/core/filterbase.hxx>
+#include <oox/dllapi.h>
+#include <oox/export/utils.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/textenc.h>
+#include <sax/fshelper.hxx>
+#include <tools/gen.hxx>
+
+namespace oox
+{
+
+namespace formulaimport
+{
+class XmlStream;
+}
+
+/**
+ Interface class, StarMath will implement readFormulaOoxml() to read OOXML
+ representing the formula, getFormulaSize() to provide the size of the resulting
+ formula, and writeFormula*() to write out markup representing the formula.
+ */
+class OOX_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") FormulaImExportBase
+{
+public:
+ virtual void readFormulaOoxml( oox::formulaimport::XmlStream& stream ) = 0;
+ virtual Size getFormulaSize() const = 0; // Unit is mm100
+
+ virtual void writeFormulaOoxml(::sax_fastparser::FSHelperPtr pSerializer,
+ oox::core::OoxmlVersion version,
+ oox::drawingml::DocumentType documentType, sal_Int8 nAlign) = 0;
+ virtual void writeFormulaRtf( OStringBuffer& rBuffer, rtl_TextEncoding nEncoding ) = 0;
+ enum eFormulaAlign { INLINE, CENTER, LEFT, RIGHT };
+
+protected:
+ FormulaImExportBase();
+
+ ~FormulaImExportBase() {}
+};
+
+namespace core { class ContextHandler; }
+namespace drawingml { class TextParagraph; }
+
+::rtl::Reference<core::ContextHandler> CreateLazyMathBufferingContext(
+ core::ContextHandler const& rParent, drawingml::TextParagraph & rPara);
+
+} // namespace
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/oox/mathml/importutils.hxx b/include/oox/mathml/importutils.hxx
new file mode 100644
index 0000000000..8aae6fe318
--- /dev/null
+++ b/include/oox/mathml/importutils.hxx
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_OOX_MATHML_IMPORTUTILS_HXX
+#define INCLUDED_OOX_MATHML_IMPORTUTILS_HXX
+
+#include <map>
+#include <string_view>
+#include <vector>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <oox/dllapi.h>
+#include <oox/token/tokens.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace com::sun::star
+{
+namespace xml::sax
+{
+class XFastAttributeList;
+}
+}
+
+namespace oox::formulaimport
+{
+// used to differentiate between tags that opening or closing
+const int TAG_OPENING = 1 << 29;
+const int TAG_CLOSING = 1 << 30;
+
+// you probably want to #define these to something shorter in the .cxx file,
+// but they must be done as macros, otherwise they wouldn't be usable for case values,
+// and macros cannot be namespaced
+#define XML_STREAM_OPENING(token) (TAG_OPENING | token)
+#define XML_STREAM_CLOSING(token) (TAG_CLOSING | token)
+
+/**
+ Class for storing a stream of xml tokens.
+
+ A part of an XML file can be parsed and stored in this stream, from which it can be read
+ as if parsed linearly. The purpose of this class is to allow simpler handling of XML
+ files, unlike the usual LO way of using callbacks, context handlers and similar needlessly
+ complicated stuff (YMMV).
+
+ The advantages of this approach is easy to read and debug code (as it is just functions
+ reading tokens one by one and calling other functions, compared to having to use callbacks
+ and temporary storage). The disadvantage is that the XML structure needs to be handled
+ manually by the code.
+
+ Note that tag identifiers are simply int values and the API does not care besides matching
+ their values to XML stream contents and requiring that the values are not as high as TAG_OPENING.
+ Be prepared for the fact that some of the functions may throw exceptions if the input
+ stream does not match the required token (TBD).
+
+ The API tries to make the common idioms as simple as possible, see the following examples.
+
+ Parse <tagone attr="value"><tagtwo>text</tagtwo></tagone> , where tagtwo is optional:
+ @code
+XmlStream::Tag tagoneTag = stream.ensureOpeningTag( tagone );
+if( attributeTag.hasAttribute( attr ))
+ ... = attributeTag.attribute( attr, defaultValueOfTheRightType );
+if( XmlStream::Tag tagtwoTag = stream.checkOpeningTag( tagtwo ))
+{
+ ... = tagtwoTag.text;
+ stream.ensureClosingTag( tagtwo );
+}
+stream.ensureClosingTag( tagone );
+ @endcode
+
+ Parse an element that may contain several sub-elements of different types in random order:
+ @code
+stream.ensureOpeningTag( element );
+while( !stream.atEnd() && stream.currentToken() != CLOSING( element ))
+ {
+ switch( stream.currentToken())
+ {
+ case OPENING( subelement1 ):
+ handleSubElement1();
+ break;
+ case OPENING( subelement2 ):
+ ... process subelement2;
+ break;
+ default:
+ stream.handleUnexpectedTag();
+ break;
+ }
+stream.ensureClosingTag( element );
+ @endcode
+
+ If there may not be a zero number of sub-elements, use a helper bool variable or use a do-while loop.
+
+ Parse an element that may contain an unknown number of sub-elements of the same type:
+ @code
+stream.ensureOpeningTag( element );
+while( !stream.atEnd() && stream.findTag( OPENING( subelement )))
+ {
+ handleSubelement();
+ }
+stream.ensureClosingTag( element );
+ @endcode
+
+ If there may not be a zero number of sub-elements, use a helper bool variable or use a do-while loop.
+
+ @since 3.5
+*/
+class OOX_DLLPUBLIC XmlStream
+{
+public:
+ XmlStream();
+ /**
+ Structure representing a list of attributes.
+ */
+ // One could theoretically use oox::AttributeList, but that complains if the passed reference is empty,
+ // which would be complicated to avoid here. Also, parsers apparently reuse the same instance of XFastAttributeList,
+ // which means using oox::AttributeList would make them all point to the one instance.
+ struct OOX_DLLPUBLIC AttributeList
+ {
+ OUString& operator[](int token);
+ OUString attribute(int token, const OUString& def) const;
+ bool attribute(int token, bool def) const;
+ sal_Unicode attribute(int token, sal_Unicode def) const;
+ // when adding more attribute() overloads, add also to XmlStream itself
+ protected:
+ std::map<int, OUString> attrs;
+ };
+ /**
+ Structure representing a tag, including its attributes and content text immediately following it.
+ */
+ struct OOX_DLLPUBLIC Tag
+ {
+ Tag(int token = XML_TOKEN_INVALID,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& attributes
+ = css::uno::Reference<css::xml::sax::XFastAttributeList>());
+ Tag(int token, AttributeList attribs);
+ int token; ///< tag type, or XML_TOKEN_INVALID
+ AttributeList attributes;
+ OUString text;
+ /**
+ This function returns value of the given attribute, or the passed default value if not found.
+ The type of the default value selects the return type (OUString here).
+ */
+ OUString attribute(int token, const OUString& def = OUString()) const;
+ /**
+ @overload
+ */
+ bool attribute(int token, bool def) const;
+ /**
+ @overload
+ */
+ sal_Unicode attribute(int token, sal_Unicode def) const;
+ // when adding more attribute() overloads, add also to XmlStream::AttributeList and inline below
+ /**
+ Converts to true if the tag has a valid token, false otherwise. Allows simple
+ usage in if(), for example 'if( XmlStream::Tag foo = stream.checkOpeningTag( footoken ))'.
+ */
+ operator bool() const;
+ };
+ /**
+ @return true if current position is at the end of the XML stream
+ */
+ bool atEnd() const;
+ /**
+ @return data about the current tag
+ */
+ Tag currentTag() const;
+ /**
+ @return the token for the current tag
+ */
+ int currentToken() const;
+ /**
+ Moves position to the next tag.
+ */
+ void moveToNextTag();
+ /**
+ Ensures that an opening tag with the given token is read. If the current tag does not match,
+ writes out a warning and tries to recover by skipping tags until found (or until the current element would end).
+ If found, the position in the stream is afterwards moved to the next tag.
+ @return the matching found opening tag, or empty tag if not found
+ */
+ Tag ensureOpeningTag(int token);
+ /**
+ Tries to find an opening tag with the given token. Works similarly like ensureOpeningTag(),
+ but if a matching tag is not found, the position in the stream is not altered. The primary
+ use of this function is to check for optional elements.
+ @return the matching found opening tag, or empty tag if not found
+ */
+ Tag checkOpeningTag(int token);
+ /**
+ Ensures that a closing tag with the given token is read. Like ensureOpeningTag(),
+ if not, writes out a warning and tries to recover by skipping tags until found (or until the current element would end).
+ If found, the position in the stream is afterwards moved to the next tag.
+ */
+ void ensureClosingTag(int token);
+ /**
+ Tries to find the given token, until either found (returns true) or end of current element.
+ Position in the stream is set to make the tag current (i.e. it will be the next one read).
+ */
+ bool findTag(int token);
+ /**
+ Handle the current (unexpected) tag.
+ */
+ void handleUnexpectedTag();
+
+protected:
+ Tag checkTag(int token, bool optional);
+ bool findTagInternal(int token, bool silent);
+ void skipElementInternal(int token, bool silent);
+ std::vector<Tag> tags;
+ unsigned int pos;
+};
+
+/**
+ This class is used for creating XmlStream.
+
+ Simply use this class and then pass it as XmlStream to the consumer.
+
+ @since 3.5.0
+*/
+class OOX_DLLPUBLIC XmlStreamBuilder : public XmlStream
+{
+public:
+ void appendOpeningTag(int token,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& attributes
+ = css::uno::Reference<css::xml::sax::XFastAttributeList>());
+ void appendOpeningTag(int token, const AttributeList& attribs);
+ void appendClosingTag(int token);
+ // appends the characters after the last appended token
+ void appendCharacters(std::u16string_view characters);
+};
+
+inline OUString XmlStream::Tag::attribute(int t, const OUString& def) const
+{
+ return attributes.attribute(t, def);
+}
+
+inline bool XmlStream::Tag::attribute(int t, bool def) const
+{
+ return attributes.attribute(t, def);
+}
+
+inline sal_Unicode XmlStream::Tag::attribute(int t, sal_Unicode def) const
+{
+ return attributes.attribute(t, def);
+}
+
+} // namespace
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */