summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorJustin Luth <justin.luth@collabora.com>2019-11-29 22:10:27 +0300
committerMichael Stahl <michael.stahl@cib.de>2020-01-08 17:41:52 +0100
commit1bbff471cdcfcd4a9ceb6ff6fed7006fbc3f6e1c (patch)
tree560e8f9eee793ce5d547bbadd5ef5a69a10a8c28 /writerfilter
parentf2d54bb55d23d000d2c69860cb145ae379e1ea10 (diff)
tdf#123262 writerfilter: completely ignore footnote separators
... except for processing enough to observe the separator exists. For each footnote reference, the entire footnote.xml file is parsed every time. The text in the "separator" footnote was being added to every footnote. The normal case where this is just a single paragraph was already handled, but this patch generalizes everything to handle cases of actual text or multiple paragraphs. Not every footnote has a type, so we can't depend on that to turn ignoringText ON/OFF. Every footnote has an ID, but theoretically the ID could be processed before or after the type, and it has no idea which type it is. Finally, the skipped text has no idea how many times/paragaphs it needs to skip. So a three-way control was needed to handle on/used/off. As a safeguard, finishing the footnote.xml parse (PopFootOrEndnote) ensures that ignoring won't be left on in the unlikely case that the separator is the last footnote. Change-Id: Ia30ca8d3a36417a4691e3b2e1c978720be017030 Reviewed-on: https://gerrit.libreoffice.org/82172 Tested-by: Jenkins Reviewed-by: Justin Luth <justin_luth@sil.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit acb9d901009d026cb48e6a8b94e6200f05110504) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85734 Reviewed-by: Michael Stahl <michael.stahl@cib.de>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx28
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx14
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx18
3 files changed, 34 insertions, 26 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 5417b6a05e0b..87b7fdbcbecc 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1078,9 +1078,20 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
}
break;
case NS_ooxml::LN_CT_FtnEdn_type:
- // This is the "separator" footnote, ignore its linebreak.
+ // This is the "separator" footnote, ignore its linebreaks/text.
if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
- m_pImpl->SeenFootOrEndnoteSeparator();
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
+ else
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
+ break;
+ case NS_ooxml::LN_CT_FtnEdn_id:
+ {
+ SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
+ if ( eSkip == SkipFootnoteSeparator::ON )
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
+ else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
+ }
break;
case NS_ooxml::LN_CT_DataBinding_prefixMappings:
m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
@@ -3398,18 +3409,19 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
if (!m_pImpl->hasTableManager())
return;
+ SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
+ if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING )
+ {
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
+ return;
+ }
+
try
{
m_pImpl->getTableManager().utext(data_, len);
if (bNewLine)
{
- if (m_pImpl->m_bIgnoreNextPara)
- {
- m_pImpl->m_bIgnoreNextPara = false;
- return;
- }
-
const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(true) && m_pImpl->GetIsLastParagraphInSection();
PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 82c5b08c9e0f..ec337152525f 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -268,7 +268,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bInFootOrEndnote(false),
m_bHasFootnoteStyle(false),
m_bCheckFootnoteStyle(false),
- m_bSeenFootOrEndnoteSeparator(false),
+ m_eSkipFootnoteState(SkipFootnoteSeparator::OFF),
m_bLineNumberingSet( false ),
m_bIsInFootnoteProperties( false ),
m_bIsParaMarkerChange( false ),
@@ -299,7 +299,6 @@ DomainMapper_Impl::DomainMapper_Impl(
m_nLastTableCellParagraphDepth(0),
m_bHasFtn(false),
m_bHasFtnSep(false),
- m_bIgnoreNextPara(false),
m_bCheckFirstFootnoteTab(false),
m_bIgnoreNextTab(false),
m_bIsSplitPara(false),
@@ -2470,21 +2469,12 @@ void DomainMapper_Impl::PopFootOrEndnote()
return;
}
m_aRedlines.pop();
- m_bSeenFootOrEndnoteSeparator = false;
+ m_eSkipFootnoteState = SkipFootnoteSeparator::OFF;
m_bInFootOrEndnote = false;
m_pFootnoteContext = nullptr;
m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell;
}
-void DomainMapper_Impl::SeenFootOrEndnoteSeparator()
-{
- if (!m_bSeenFootOrEndnoteSeparator)
- {
- m_bSeenFootOrEndnoteSeparator = true;
- m_bIgnoreNextPara = true;
- }
-}
-
void DomainMapper_Impl::PopAnnotation()
{
RemoveLastParagraph();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 18b019e7c402..c8de67b69674 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -114,6 +114,13 @@ enum BreakType
COLUMN_BREAK
};
+enum SkipFootnoteSeparator
+{
+ OFF,
+ ON,
+ SKIPPING
+};
+
/**
* Storage for state that is relevant outside a header/footer, but not inside it.
*
@@ -512,8 +519,8 @@ private:
PropertyMapPtr m_pFootnoteContext;
bool m_bHasFootnoteStyle;
bool m_bCheckFootnoteStyle;
- /// Did we get a <w:separator/> for this footnote already?
- bool m_bSeenFootOrEndnoteSeparator;
+ /// Skip paragraphs from the <w:separator/> footnote
+ SkipFootnoteSeparator m_eSkipFootnoteState;
bool m_bLineNumberingSet;
bool m_bIsInFootnoteProperties;
@@ -781,8 +788,9 @@ public:
void SetCheckFootnoteStyle(bool bVal) { m_bCheckFootnoteStyle = bVal; }
const PropertyMapPtr& GetFootnoteContext() const { return m_pFootnoteContext; }
- /// Got a <w:separator/>.
- void SeenFootOrEndnoteSeparator();
+
+ SkipFootnoteSeparator GetSkipFootnoteState() const { return m_eSkipFootnoteState; }
+ void SetSkipFootnoteState(SkipFootnoteSeparator eId) { m_eSkipFootnoteState = eId; }
void PushAnnotation();
void PopAnnotation();
@@ -992,8 +1000,6 @@ public:
/// If the current section has a footnote separator.
bool m_bHasFtnSep;
- /// If the next newline should be ignored, used by the special footnote separator paragraph.
- bool m_bIgnoreNextPara;
/// If the next tab should be ignored, used for footnotes.
bool m_bCheckFirstFootnoteTab;
bool m_bIgnoreNextTab;