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 .
20 #include <svtools/htmltokn.h>
21 #include <svtools/htmlkywd.hxx>
22 #include <svtools/htmlout.hxx>
23 #include <numrule.hxx>
28 #include "htmlnum.hxx"
29 #include "wrthtml.hxx"
31 #include <osl/diagnose.h>
36 void SwHTMLWriter::FillNextNumInfo()
38 m_pNextNumRuleInfo
= nullptr;
40 SwNodeOffset nPos
= m_pCurrentPam
->GetPoint()->GetNodeIndex() + 1;
45 const SwNode
* pNd
= m_pDoc
->GetNodes()[nPos
];
46 if( pNd
->IsTextNode() )
48 m_pNextNumRuleInfo
.reset( new SwHTMLNumRuleInfo( *pNd
->GetTextNode() ) );
50 // Before a table we keep the old level if the same numbering is
51 // continued after the table and no new numbering is started.
52 // The table will get the indentation that corresponds to its
53 // numbering level during import.
55 m_pNextNumRuleInfo
->GetNumRule()==GetNumInfo().GetNumRule() &&
56 !m_pNextNumRuleInfo
->IsRestart(GetNumInfo()) )
58 m_pNextNumRuleInfo
->SetDepth( GetNumInfo().GetDepth() );
61 else if( pNd
->IsTableNode() )
63 // A table is skipped so the node after table is viewed.
64 nPos
= pNd
->EndOfSectionIndex() + 1;
69 // In all other case the numbering is over.
70 m_pNextNumRuleInfo
.reset(new SwHTMLNumRuleInfo
);
73 while( !m_pNextNumRuleInfo
);
76 void SwHTMLWriter::ClearNextNumInfo()
78 m_pNextNumRuleInfo
.reset();
81 void SwHTMLWriter::SetNextNumInfo( std::unique_ptr
<SwHTMLNumRuleInfo
> pNxt
)
83 m_pNextNumRuleInfo
= std::move(pNxt
);
86 SwHTMLWriter
& OutHTML_NumberBulletListStart( SwHTMLWriter
& rWrt
,
87 const SwHTMLNumRuleInfo
& rInfo
)
89 SwHTMLNumRuleInfo
& rPrevInfo
= rWrt
.GetNumInfo();
90 bool bSameRule
= rPrevInfo
.GetNumRule() == rInfo
.GetNumRule();
91 if( bSameRule
&& rPrevInfo
.GetDepth() >= rInfo
.GetDepth() &&
92 !rInfo
.IsRestart(rPrevInfo
) )
97 bool bStartValue
= false;
98 if( !bSameRule
&& rInfo
.GetDepth() )
100 OUString
aName( rInfo
.GetNumRule()->GetName() );
101 if( 0 != rWrt
.m_aNumRuleNames
.count( aName
) )
103 // The rule has been applied before
104 sal_Int16 eType
= rInfo
.GetNumRule()
105 ->Get( rInfo
.GetDepth()-1 ).GetNumberingType();
106 if( SVX_NUM_CHAR_SPECIAL
!= eType
&& SVX_NUM_BITMAP
!= eType
)
108 // If it's a numbering rule, the current number should be
109 // exported as start value, but only if there are no nodes
110 // within the numbering that have a lower level
112 if( rInfo
.GetDepth() > 1 )
115 rWrt
.m_pCurrentPam
->GetPoint()->GetNodeIndex() + 1;
118 const SwNode
* pNd
= rWrt
.m_pDoc
->GetNodes()[nPos
];
119 if( pNd
->IsTextNode() )
121 const SwTextNode
*pTextNd
= pNd
->GetTextNode();
122 if( !pTextNd
->GetNumRule() )
124 // node isn't numbered => check completed
128 OSL_ENSURE(! pTextNd
->IsOutline(),
129 "outline not expected");
131 if( pTextNd
->GetActualListLevel() + 1 <
134 if (rPrevInfo
.GetDepth() == 0)
135 // previous node had no numbering => write start value
138 // node is numbered, but level is lower
140 // => check completed
145 else if( pNd
->IsTableNode() )
148 nPos
= pNd
->EndOfSectionIndex() + 1;
152 // end node or sections start node -> check
163 rWrt
.m_aNumRuleNames
.insert( aName
);
167 OSL_ENSURE( rWrt
.m_nLastParaToken
== HtmlTokenId::NONE
,
168 "<PRE> was not closed before <OL>." );
169 sal_uInt16 nPrevDepth
=
170 (bSameRule
&& !rInfo
.IsRestart(rPrevInfo
)) ? rPrevInfo
.GetDepth() : 0;
172 for( sal_uInt16 i
=nPrevDepth
; i
<rInfo
.GetDepth(); i
++ )
174 rWrt
.OutNewLine(); // <OL>/<UL> in a new row
176 rWrt
.m_aBulletGrfs
[i
].clear();
177 OString sOut
= "<" + rWrt
.GetNamespace();
178 if (rWrt
.mbXHTML
&& i
!= nPrevDepth
)
180 // for all skipped sublevels, add a li
181 sOut
+= OOO_STRING_SVTOOLS_HTML_li
"><" + rWrt
.GetNamespace();
183 const SwNumFormat
& rNumFormat
= rInfo
.GetNumRule()->Get( i
);
184 sal_Int16 eType
= rNumFormat
.GetNumberingType();
185 if( SVX_NUM_CHAR_SPECIAL
== eType
)
187 // unordered list: <UL>
188 sOut
+= OOO_STRING_SVTOOLS_HTML_unorderlist
;
190 if (!rWrt
.mbReqIF
) // No 'type' attribute in ReqIF
192 // determine the type by the bullet character
193 const char* pStr
= nullptr;
194 switch (rNumFormat
.GetBulletChar())
196 case HTML_BULLETCHAR_DISC
:
197 pStr
= OOO_STRING_SVTOOLS_HTML_ULTYPE_disc
;
199 case HTML_BULLETCHAR_CIRCLE
:
200 pStr
= OOO_STRING_SVTOOLS_HTML_ULTYPE_circle
;
202 case HTML_BULLETCHAR_SQUARE
:
203 pStr
= OOO_STRING_SVTOOLS_HTML_ULTYPE_square
;
209 sOut
+= OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_type
"=\"") + pStr
+ "\"";
213 else if( SVX_NUM_BITMAP
== eType
)
215 // Unordered list: <UL>
216 sOut
+= OOO_STRING_SVTOOLS_HTML_unorderlist
;
220 // Ordered list: <OL>
221 sOut
+= OOO_STRING_SVTOOLS_HTML_orderlist
;
223 if (!rWrt
.mbReqIF
) // No 'type' nor 'start' attribute in ReqIF
225 // determine the type by the format
229 case SVX_NUM_CHARS_UPPER_LETTER
:
230 case SVX_NUM_CHARS_UPPER_LETTER_N
:
233 case SVX_NUM_CHARS_LOWER_LETTER
:
234 case SVX_NUM_CHARS_LOWER_LETTER_N
:
237 case SVX_NUM_ROMAN_UPPER
:
240 case SVX_NUM_ROMAN_LOWER
:
246 sOut
+= " " OOO_STRING_SVTOOLS_HTML_O_type
"=\"" + OStringChar(cType
) + "\"";
249 sal_uInt16 nStartVal
= rNumFormat
.GetStart();
250 if( bStartValue
&& 1 == nStartVal
&& i
== rInfo
.GetDepth()-1 )
252 if ( rWrt
.m_pCurrentPam
->GetPointNode().GetTextNode()->GetNum() )
254 nStartVal
= static_cast< sal_uInt16
>( rWrt
.m_pCurrentPam
->GetPointNode()
255 .GetTextNode()->GetNumberVector()[i
] );
259 OSL_FAIL( "<OutHTML_NumberBulletListStart(..) - text node has no number." );
264 sOut
+= " " OOO_STRING_SVTOOLS_HTML_O_start
"=\"" + OString::number(static_cast<sal_Int32
>(nStartVal
)) + "\"";
269 rWrt
.Strm().WriteOString(sOut
);
271 if (eType
== SVX_NUM_BITMAP
)
272 OutHTML_BulletImage(rWrt
, nullptr, rNumFormat
.GetBrush(), rWrt
.m_aBulletGrfs
[i
]);
274 if( rWrt
.m_bCfgOutStyles
)
275 OutCSS1_NumberBulletListStyleOpt( rWrt
, *rInfo
.GetNumRule(), static_cast<sal_uInt8
>(i
) );
277 rWrt
.Strm().WriteChar( '>' );
279 rWrt
.IncIndentLevel(); // indent content of <OL>
285 SwHTMLWriter
& OutHTML_NumberBulletListEnd( SwHTMLWriter
& rWrt
,
286 const SwHTMLNumRuleInfo
& rNextInfo
)
288 SwHTMLNumRuleInfo
& rInfo
= rWrt
.GetNumInfo();
289 bool bSameRule
= rNextInfo
.GetNumRule() == rInfo
.GetNumRule();
290 bool bListEnd
= !bSameRule
|| rNextInfo
.GetDepth() < rInfo
.GetDepth() || rNextInfo
.IsRestart(rInfo
);
291 bool bNextIsSubitem
= !bListEnd
&& rNextInfo
.GetDepth() > rInfo
.GetDepth();
293 // XHTML </li> for the list item content, if there is an open <li>.
294 if (bListEnd
|| (!bNextIsSubitem
&& rNextInfo
.IsNumbered()))
296 HTMLOutFuncs::Out_AsciiTag(
297 rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_li
),
306 OSL_ENSURE( rWrt
.m_nLastParaToken
== HtmlTokenId::NONE
,
307 "<PRE> was not closed before </OL>." );
308 sal_uInt16 nNextDepth
=
309 (bSameRule
&& !rNextInfo
.IsRestart(rInfo
)) ? rNextInfo
.GetDepth() : 0;
311 // MIB 23.7.97: We must loop backwards, to get the right order of </OL>/</UL>
312 for( sal_uInt16 i
=rInfo
.GetDepth(); i
>nNextDepth
; i
-- )
314 rWrt
.DecIndentLevel(); // indent content of <OL>
315 if (rWrt
.IsLFPossible())
316 rWrt
.OutNewLine(); // </OL>/</UL> in a new line
318 // a list is started or ended:
319 sal_Int16 eType
= rInfo
.GetNumRule()->Get( i
-1 ).GetNumberingType();
321 if( SVX_NUM_CHAR_SPECIAL
== eType
|| SVX_NUM_BITMAP
== eType
)
322 aTag
= OOO_STRING_SVTOOLS_HTML_unorderlist
""_ostr
;
324 aTag
= OOO_STRING_SVTOOLS_HTML_orderlist
""_ostr
;
325 HTMLOutFuncs::Out_AsciiTag( rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + aTag
), false );
326 if (rWrt
.mbXHTML
&& (i
!= nNextDepth
+ 1 || (i
!= 1 && rNextInfo
.IsNumbered())))
328 // for all skipped sublevels, close a li
329 HTMLOutFuncs::Out_AsciiTag(
330 rWrt
.Strm(), Concat2View(rWrt
.GetNamespace() + OOO_STRING_SVTOOLS_HTML_li
),
333 rWrt
.SetLFPossible(true);
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */