summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2017-07-07 11:33:34 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2017-07-07 12:54:05 +0200
commit6a3960044c609b682170f7a34612761e62746c98 (patch)
tree63ace6152ee8b775a6fe79e2786471be8479e2ab
parent919b6958dbb1c17c060ba9a58fe245b825b271c2 (diff)
tdf#108995: take xml:space attribute into account
See paragraph 2.10 of XML 1.0 specification and 17.3.3.31 of ECMA-376-1:2016 Change-Id: I7f19d3b9cf2ccce88a5fa03022beeb99facc04fe Reviewed-on: https://gerrit.libreoffice.org/39682 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> (cherry picked from commit 7c1a51516aaf2767e43b393259a1ad21570df5fb) Reviewed-on: https://gerrit.libreoffice.org/39688 Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--sw/qa/extras/ooxmlimport/data/xml_space.docxbin0 -> 1309 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx10
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx37
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx8
4 files changed, 53 insertions, 2 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/xml_space.docx b/sw/qa/extras/ooxmlimport/data/xml_space.docx
new file mode 100644
index 000000000000..305c135fdd75
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/xml_space.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 767f908ab6fb..a46a09d32bf3 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1466,6 +1466,16 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108714, "tdf108714.docx")
CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, breakType);
}
+DECLARE_OOXMLIMPORT_TEST(testTdf108995, "xml_space.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
+ // We need to take xml:space attribute into account
+ uno::Reference< text::XTextRange > paragraph = getParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(OUString("\tA\t\tline with\txml:space=\"preserve\" \n"
+ "A line without xml:space"),
+ paragraph->getString());
+}
+
// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 84d2a65ad6e0..bb59ed9bebdc 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -627,6 +627,12 @@ void OOXMLFastContextHandler::text(const OUString & sText)
// tdf#108806: CRLFs in XML were converted to \n before this point.
// These must be converted to spaces before further processing.
OUString sNormalizedText = sText.replaceAll("\n", " ");
+ // tdf#108995: by default, leading and trailing white space is ignored;
+ // tabs are converted to spaces
+ if (!IsPreserveSpace())
+ {
+ sNormalizedText = sNormalizedText.trim().replaceAll("\t", " ");
+ }
mpStream->utext(reinterpret_cast < const sal_uInt8 * >
(sNormalizedText.getStr()),
sNormalizedText.getLength());
@@ -889,6 +895,15 @@ void OOXMLFastContextHandler::sendPropertiesToParent()
}
}
+bool OOXMLFastContextHandler::IsPreserveSpace() const
+{
+ // xml:space attribute applies to all elements within the content of the element where it is specified,
+ // unless overridden with another instance of the xml:space attribute
+ if (mpParent)
+ return mpParent->IsPreserveSpace();
+ return false; // default value
+}
+
/*
class OOXMLFastContextHandlerStream
*/
@@ -896,7 +911,9 @@ void OOXMLFastContextHandler::sendPropertiesToParent()
OOXMLFastContextHandlerStream::OOXMLFastContextHandlerStream
(OOXMLFastContextHandler * pContext)
: OOXMLFastContextHandler(pContext),
- mpPropertySetAttrs(new OOXMLPropertySet)
+ mpPropertySetAttrs(new OOXMLPropertySet),
+ mbPreserveSpace(false),
+ mbPreserveSpaceSet(false)
{
}
@@ -907,7 +924,14 @@ OOXMLFastContextHandlerStream::~OOXMLFastContextHandlerStream()
void OOXMLFastContextHandlerStream::newProperty(Id nId,
const OOXMLValue::Pointer_t& pVal)
{
- if (nId != 0x0)
+ if (nId == NS_ooxml::LN_CT_Text_space)
+ {
+ // Set <xml:space> value early, to allow
+ // child contexts use it when dealing with strings
+ mbPreserveSpace = pVal->getString() == "preserve";
+ mbPreserveSpaceSet = true;
+ }
+ else if (nId != 0x0)
{
OOXMLProperty::Pointer_t pProperty(new OOXMLProperty(nId, pVal, OOXMLProperty::ATTRIBUTE));
@@ -938,6 +962,15 @@ void OOXMLFastContextHandlerStream::handleHyperlink()
getPropertySetAttrs()->resolve(aHyperlinkHandler);
}
+bool OOXMLFastContextHandlerStream::IsPreserveSpace() const
+{
+ // xml:space attribute applies to all elements within the content of the element where it is specified,
+ // unless overridden with another instance of the xml:space attribute
+ if (mbPreserveSpaceSet)
+ return mbPreserveSpace;
+ return OOXMLFastContextHandler::IsPreserveSpace();
+}
+
/*
class OOXMLFastContextHandlerProperties
*/
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index e4e3e563fad5..eaf40e27f47b 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -224,6 +224,9 @@ protected:
void startAction(Token_t Element);
void endAction(Token_t Element);
+ // 2.10 of XML 1.0 specification
+ virtual bool IsPreserveSpace() const;
+
const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() { return m_xContext;}
bool inPositionV;
@@ -258,8 +261,13 @@ public:
void handleHyperlink();
+protected:
+ virtual bool IsPreserveSpace() const override;
+
private:
mutable OOXMLPropertySet::Pointer_t mpPropertySetAttrs;
+ bool mbPreserveSpace : 1;
+ bool mbPreserveSpaceSet : 1;
};
class OOXMLFastContextHandlerProperties : public OOXMLFastContextHandler