summaryrefslogtreecommitdiffstats
path: root/sw/source/filter/html/htmlnumwriter.cxx
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 /sw/source/filter/html/htmlnumwriter.cxx
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 'sw/source/filter/html/htmlnumwriter.cxx')
-rw-r--r--sw/source/filter/html/htmlnumwriter.cxx336
1 files changed, 336 insertions, 0 deletions
diff --git a/sw/source/filter/html/htmlnumwriter.cxx b/sw/source/filter/html/htmlnumwriter.cxx
new file mode 100644
index 0000000000..046747754a
--- /dev/null
+++ b/sw/source/filter/html/htmlnumwriter.cxx
@@ -0,0 +1,336 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <numrule.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <pam.hxx>
+
+#include "htmlnum.hxx"
+#include "wrthtml.hxx"
+
+#include <osl/diagnose.h>
+
+using namespace css;
+
+
+void SwHTMLWriter::FillNextNumInfo()
+{
+ m_pNextNumRuleInfo = nullptr;
+
+ SwNodeOffset nPos = m_pCurrentPam->GetPoint()->GetNodeIndex() + 1;
+
+ bool bTable = false;
+ do
+ {
+ const SwNode* pNd = m_pDoc->GetNodes()[nPos];
+ if( pNd->IsTextNode() )
+ {
+ m_pNextNumRuleInfo.reset( new SwHTMLNumRuleInfo( *pNd->GetTextNode() ) );
+
+ // Before a table we keep the old level if the same numbering is
+ // continued after the table and no new numbering is started.
+ // The table will get the indentation that corresponds to its
+ // numbering level during import.
+ if( bTable &&
+ m_pNextNumRuleInfo->GetNumRule()==GetNumInfo().GetNumRule() &&
+ !m_pNextNumRuleInfo->IsRestart(GetNumInfo()) )
+ {
+ m_pNextNumRuleInfo->SetDepth( GetNumInfo().GetDepth() );
+ }
+ }
+ else if( pNd->IsTableNode() )
+ {
+ // A table is skipped so the node after table is viewed.
+ nPos = pNd->EndOfSectionIndex() + 1;
+ bTable = true;
+ }
+ else
+ {
+ // In all other case the numbering is over.
+ m_pNextNumRuleInfo.reset(new SwHTMLNumRuleInfo);
+ }
+ }
+ while( !m_pNextNumRuleInfo );
+}
+
+void SwHTMLWriter::ClearNextNumInfo()
+{
+ m_pNextNumRuleInfo.reset();
+}
+
+void SwHTMLWriter::SetNextNumInfo( std::unique_ptr<SwHTMLNumRuleInfo> pNxt )
+{
+ m_pNextNumRuleInfo = std::move(pNxt);
+}
+
+SwHTMLWriter& OutHTML_NumberBulletListStart( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rInfo )
+{
+ SwHTMLNumRuleInfo& rPrevInfo = rWrt.GetNumInfo();
+ bool bSameRule = rPrevInfo.GetNumRule() == rInfo.GetNumRule();
+ if( bSameRule && rPrevInfo.GetDepth() >= rInfo.GetDepth() &&
+ !rInfo.IsRestart(rPrevInfo) )
+ {
+ return rWrt;
+ }
+
+ bool bStartValue = false;
+ if( !bSameRule && rInfo.GetDepth() )
+ {
+ OUString aName( rInfo.GetNumRule()->GetName() );
+ if( 0 != rWrt.m_aNumRuleNames.count( aName ) )
+ {
+ // The rule has been applied before
+ sal_Int16 eType = rInfo.GetNumRule()
+ ->Get( rInfo.GetDepth()-1 ).GetNumberingType();
+ if( SVX_NUM_CHAR_SPECIAL != eType && SVX_NUM_BITMAP != eType )
+ {
+ // If it's a numbering rule, the current number should be
+ // exported as start value, but only if there are no nodes
+ // within the numbering that have a lower level
+ bStartValue = true;
+ if( rInfo.GetDepth() > 1 )
+ {
+ SwNodeOffset nPos =
+ rWrt.m_pCurrentPam->GetPoint()->GetNodeIndex() + 1;
+ do
+ {
+ const SwNode* pNd = rWrt.m_pDoc->GetNodes()[nPos];
+ if( pNd->IsTextNode() )
+ {
+ const SwTextNode *pTextNd = pNd->GetTextNode();
+ if( !pTextNd->GetNumRule() )
+ {
+ // node isn't numbered => check completed
+ break;
+ }
+
+ OSL_ENSURE(! pTextNd->IsOutline(),
+ "outline not expected");
+
+ if( pTextNd->GetActualListLevel() + 1 <
+ rInfo.GetDepth() )
+ {
+ if (rPrevInfo.GetDepth() == 0)
+ // previous node had no numbering => write start value
+ bStartValue = true;
+ else
+ // node is numbered, but level is lower
+ bStartValue = false;
+ // => check completed
+ break;
+ }
+ nPos++;
+ }
+ else if( pNd->IsTableNode() )
+ {
+ // skip table
+ nPos = pNd->EndOfSectionIndex() + 1;
+ }
+ else
+ {
+ // end node or sections start node -> check
+ // completed
+ break;
+ }
+ }
+ while( true );
+ }
+ }
+ }
+ else
+ {
+ rWrt.m_aNumRuleNames.insert( aName );
+ }
+ }
+
+ OSL_ENSURE( rWrt.m_nLastParaToken == HtmlTokenId::NONE,
+ "<PRE> was not closed before <OL>." );
+ sal_uInt16 nPrevDepth =
+ (bSameRule && !rInfo.IsRestart(rPrevInfo)) ? rPrevInfo.GetDepth() : 0;
+
+ for( sal_uInt16 i=nPrevDepth; i<rInfo.GetDepth(); i++ )
+ {
+ rWrt.OutNewLine(); // <OL>/<UL> in a new row
+
+ rWrt.m_aBulletGrfs[i].clear();
+ OString sOut = "<" + rWrt.GetNamespace();
+ if (rWrt.mbXHTML && i != nPrevDepth)
+ {
+ // for all skipped sublevels, add a li
+ sOut += OOO_STRING_SVTOOLS_HTML_li "><" + rWrt.GetNamespace();
+ }
+ const SwNumFormat& rNumFormat = rInfo.GetNumRule()->Get( i );
+ sal_Int16 eType = rNumFormat.GetNumberingType();
+ if( SVX_NUM_CHAR_SPECIAL == eType )
+ {
+ // unordered list: <UL>
+ sOut += OOO_STRING_SVTOOLS_HTML_unorderlist;
+
+ // determine the type by the bullet character
+ const char *pStr = nullptr;
+ switch( rNumFormat.GetBulletChar() )
+ {
+ case HTML_BULLETCHAR_DISC:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_disc;
+ break;
+ case HTML_BULLETCHAR_CIRCLE:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_circle;
+ break;
+ case HTML_BULLETCHAR_SQUARE:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_square;
+ break;
+ }
+
+ if( pStr )
+ {
+ sOut += OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_type "=\"") + pStr + "\"";
+ }
+ }
+ else if( SVX_NUM_BITMAP == eType )
+ {
+ // Unordered list: <UL>
+ sOut += OOO_STRING_SVTOOLS_HTML_unorderlist;
+ }
+ else
+ {
+ // Ordered list: <OL>
+ sOut += OOO_STRING_SVTOOLS_HTML_orderlist;
+
+ if (!rWrt.mbReqIF) // No 'type' nor 'start' attribute in ReqIF
+ {
+ // determine the type by the format
+ char cType = 0;
+ switch (eType)
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N:
+ cType = 'A';
+ break;
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N:
+ cType = 'a';
+ break;
+ case SVX_NUM_ROMAN_UPPER:
+ cType = 'I';
+ break;
+ case SVX_NUM_ROMAN_LOWER:
+ cType = 'i';
+ break;
+ }
+ if( cType )
+ {
+ sOut += " " OOO_STRING_SVTOOLS_HTML_O_type "=\"" + OStringChar(cType) + "\"";
+ }
+
+ sal_uInt16 nStartVal = rNumFormat.GetStart();
+ if( bStartValue && 1 == nStartVal && i == rInfo.GetDepth()-1 )
+ {
+ if ( rWrt.m_pCurrentPam->GetPointNode().GetTextNode()->GetNum() )
+ {
+ nStartVal = static_cast< sal_uInt16 >( rWrt.m_pCurrentPam->GetPointNode()
+ .GetTextNode()->GetNumberVector()[i] );
+ }
+ else
+ {
+ OSL_FAIL( "<OutHTML_NumberBulletListStart(..) - text node has no number." );
+ }
+ }
+ if( nStartVal != 1 )
+ {
+ sOut += " " OOO_STRING_SVTOOLS_HTML_O_start "=\"" + OString::number(static_cast<sal_Int32>(nStartVal)) + "\"";
+ }
+ }
+ }
+
+ rWrt.Strm().WriteOString(sOut);
+
+ if (eType == SVX_NUM_BITMAP)
+ OutHTML_BulletImage(rWrt, nullptr, rNumFormat.GetBrush(), rWrt.m_aBulletGrfs[i]);
+
+ if( rWrt.m_bCfgOutStyles )
+ OutCSS1_NumberBulletListStyleOpt( rWrt, *rInfo.GetNumRule(), static_cast<sal_uInt8>(i) );
+
+ rWrt.Strm().WriteChar( '>' );
+
+ rWrt.IncIndentLevel(); // indent content of <OL>
+ }
+
+ return rWrt;
+}
+
+SwHTMLWriter& OutHTML_NumberBulletListEnd( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rNextInfo )
+{
+ SwHTMLNumRuleInfo& rInfo = rWrt.GetNumInfo();
+ bool bSameRule = rNextInfo.GetNumRule() == rInfo.GetNumRule();
+ bool bListEnd = !bSameRule || rNextInfo.GetDepth() < rInfo.GetDepth() || rNextInfo.IsRestart(rInfo);
+ bool bNextIsSubitem = !bListEnd && rNextInfo.GetDepth() > rInfo.GetDepth();
+
+ // XHTML </li> for the list item content, if there is an open <li>.
+ if (bListEnd || (!bNextIsSubitem && rNextInfo.IsNumbered()))
+ {
+ HTMLOutFuncs::Out_AsciiTag(
+ rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_li),
+ false);
+ }
+
+ if (!bListEnd)
+ {
+ return rWrt;
+ }
+
+ OSL_ENSURE( rWrt.m_nLastParaToken == HtmlTokenId::NONE,
+ "<PRE> was not closed before </OL>." );
+ sal_uInt16 nNextDepth =
+ (bSameRule && !rNextInfo.IsRestart(rInfo)) ? rNextInfo.GetDepth() : 0;
+
+ // MIB 23.7.97: We must loop backwards, to get the right order of </OL>/</UL>
+ for( sal_uInt16 i=rInfo.GetDepth(); i>nNextDepth; i-- )
+ {
+ rWrt.DecIndentLevel(); // indent content of <OL>
+ if (rWrt.IsLFPossible())
+ rWrt.OutNewLine(); // </OL>/</UL> in a new line
+
+ // a list is started or ended:
+ sal_Int16 eType = rInfo.GetNumRule()->Get( i-1 ).GetNumberingType();
+ OString aTag;
+ if( SVX_NUM_CHAR_SPECIAL == eType || SVX_NUM_BITMAP == eType)
+ aTag = OOO_STRING_SVTOOLS_HTML_unorderlist ""_ostr;
+ else
+ aTag = OOO_STRING_SVTOOLS_HTML_orderlist ""_ostr;
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + aTag), false );
+ if (rWrt.mbXHTML && (i != nNextDepth + 1 || (i != 1 && rNextInfo.IsNumbered())))
+ {
+ // for all skipped sublevels, close a li
+ HTMLOutFuncs::Out_AsciiTag(
+ rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_li),
+ /*bOn=*/false);
+ }
+ rWrt.SetLFPossible(true);
+ }
+
+ return rWrt;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */